Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v44i066: unzip - Info-ZIP portable UnZip, version 5.12, Part01/20

165 views
Skip to first unread message

Info-ZIP group

unread,
Sep 19, 1994, 12:13:54 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 66
Archive-name: unzip/part01
Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

UnZip is an extraction utility for archives compressed in .zip format (also
called "zipfiles"). Although highly compatible both with PKWARE's PKZIP
and PKUNZIP utilities for MS-DOS and with Info-ZIP's own Zip program, our
primary objectives have been portability and non-MSDOS functionality.

This version of UnZip has been ported to a wide array of hardware--from
micros to supercomputers--and operating systems: Unix (many flavors),
VMS, OS/2, MSDOS (+ Windows), NT, TOPS-20 (partly), AmigaDOS, Atari TOS,
Macintosh and Human68k. UnZip features not found in PKUNZIP include source
code; default extraction of directory trees (with a switch to defeat this,
rather than the reverse); VMS, Macintosh and OS/2 extended file attributes;
and, of course, the ability to run under most of your favorite operating
systems. Plus, it's free. :-)

For source distributions, see the main Contents file for a list of what's
included, and read INSTALL for instructions on compiling (including OS-
specific comments). The individual operating systems' Contents files (for
example, vms/Contents) may list important compilation info in addition to
explaining what files are what, so be sure to read them. Some of the ports
have their own, special README files, so be sure to look for those, too.

See unzip.1 or unzip.doc for usage (or the corresponding UnZipSFX, ZipInfo
and fUnZip docs). For VMS, unzip_def.rnh or unzip_cli.help may be compiled
into unzip.hlp and installed as a normal VMS help entry; see vms/descrip.mms.

CHANGES AND NEW FEATURES
------------------------
The 5.12 release mainly fixes some bugs in 5.11, including a silly pointer
error in unzipsfx. The only new features are fairly minor:

- ZipInfo check for dead space inside archives (PKZIP/Netware bug)
- SFX_EXDIR compilation option to allow -d <exdir> with UnZipSFX
- "unzip -vqqqq" prints just the version number (e.g., "512")

Since neither 5.11 nor 5.1 was posted to Usenet, here's a summary of their
new features. In UnZip 5.11:

- UnZipSFX, a self-extraction stub for prepending to (new-style) zipfiles
(tested under Unix, VMS, MS-DOS, OS/2, etc.; NOT portable *across* OSes)
- unshrink() rewritten to avoid copyright problems; 32-bit version only
- strings moved to far memory in MS-DOS: can use small model again (MSC)
- numerous customization options (see INSTALL)
- diagnostic screen with -v option and no zipfile (i.e., "unzip -v")
- -C option for case-insensitive filename matching (esp. for MS-DOS, OS/2)
- more bad-zipfile "intelligence" (can sometimes even extract concatenated
multi-part archives)
- former -U behavior is now the default; new -L option to provide what was
the default behavior (auto-conversion of uppercase-OS filenames to lower
case)
- ZipInfo -T option to print times in decimal format (yymmdd.hhmmss) for
piping into sort(1)
- performance tweaks for listing archive contents
- improved/expanded documentation, esp. man pages (*.doc files) and INSTALL

In UnZip 5.1:

- wildcard zipfiles (e.g., "unzip -tq \*.zip")
- extract to a directory other than the current one (-d <exdir> option)
- auto-conversion of text files
- ANSI sequences disabled in comments and filenames (avoid "ANSI bombs")
- ZipInfo incorporated into UnZip (-Z option)
- full Amiga, Atari, Mac, NT and Human68K support (partial TOPS-20)
- performance tuning for 35-70% faster extraction (depends on compression
method)

Note that, according to one tester, the 32-bit MS-DOS version is now *faster*
than PKUNZIP on most archives! Cool.

DISTRIBUTION
------------
If you have a question regarding redistribution of Info-ZIP software,
either as-is, as packaging for a commercial product, or as an integral
part of a commercial product, read the Frequently Asked Questions (FAQ)
section of the included COPYING file.

Insofar as C compilers are rare on some platforms and the authors only
have direct access to Unix, VMS, OS/2, MS-DOS, Mac, Amiga and Atari
systems, others may wish to provide ready-to-run executables for new
systems. In general there is no problem with this; we require only that
such distributions include this README file, the Where file, the COPYING
file (contains copyright/redistribution information), and the appropriate
documentation files (unzip.doc and/or unzip.1 for UnZip, etc.). If the
local system provides a way to make self-extracting archives in which both
the executables and text files may be stored together, that is best (in
particular, use UnZipSFX if at all possible, even if it's a few kilobytes
bigger than the alternatives); otherwise we suggest a bare UnZip executable
and a separate zipfile containing the remaining text and binary files. If
another archiving method is in common use on the target system (for example,
Zoo or LHa), that may also be used.

BUGS AND NEW PORTS: CONTACTING INFO-ZIP
----------------------------------------
All bug reports and patches (context diffs only, please!) should go to
zip-...@wkuvx1.wku.edu, which is the e-mail address for the Info-ZIP
authors. "Dumb questions" which aren't adequately answered in the docu-
mentation should also be directed here rather than to a global forum such
as Usenet. (Kindly make certain that your questions *isn't* answered by
the documentation, however--a great deal of effort has gone into making
it clear and complete.) Suggestions for new features can be sent to
info...@wkuvx1.wku.edu, a mailing list for the Info-ZIP beta testers,
for discussion (the authors hang out here as well, of course), although
we don't promise to act on all suggestions. If it is something which is
manifestly useful, sending the required patches to zip-bugs directly (as
per the instructions in the ZipPorts file) is likely to produce a quicker
response than asking us to do it--the authors are always somewhat short
on time. (Please do NOT send patches or encoded zipfiles to the info-zip
address.)

If you are considering a port, not only should you read the ZipPorts file,
but also please check in with zip-bugs BEFORE getting started, since the
code is constantly being updated behind the scenes. For example, an Acorn/
Archimedes port is already almost complete, as is an OS/2 dynamic link lib-
rary (DLL) version; VMOS, VM/CMS, Netware, QDOS and NT DLL ports are claimed
to be under construction, although we have yet to see any up-to-date patches.
We will arrange to send you the latest sources. The alternative is the pos-
sibility that your hard work will be tucked away in a sub-archive and mostly
ignored, or completely ignored if someone else has already done the port
(and you'd be surprised how often this has happened). IBM mainframe ports
(VM/CMS and/or MVS) would be particularly welcome. (It can't be *that* hard,
folks...the VMS filesystem is similar in many ways.)


BETA TESTING: JOINING INFO-ZIP
-------------------------------
If you'd like to keep up to date with our UnZip (and companion Zip utility)
development, join the ranks of beta testers, add your own thoughts and con-
tributions, etc., send a two-line mail message containing the commands HELP
and LIST (on separate lines in the body of the message, not on the subject
line) to mxse...@wkuvx1.wku.edu. You'll receive two messages listing the
various Info-ZIP mailing-list formats which are available (and also various
unrelated lists) and instructions on how to subscribe to one or more of them
(courtesy of Hunter Goatley). As of mid-1994, subscribing to the announce-
ments list requires a command of the form

SUBSCRIBE Info-ZIP-announce "Joe Isuzu"

The discussion list is called either Info-ZIP or Info-ZIP-digest, depending
on one's preference for delivery.

-- Greg Roelofs (Cave Newt), UnZip maintainer/container/explainer and
developer guy, with inspiration from David Kirschbaum
----------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: unzip-5.12 unzip-5.12/amiga unzip-5.12/atari
# unzip-5.12/human68k unzip-5.12/mac unzip-5.12/msdos
# unzip-5.12/msdos/README unzip-5.12/nt unzip-5.12/os2
# unzip-5.12/tops20 unzip-5.12/unix unzip-5.12/unzip.h
# unzip-5.12/vms
# Wrapped by kent@sparky on Sat Sep 17 23:33:34 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 20)."'
if test ! -d 'unzip-5.12' ; then
echo shar: Creating directory \"'unzip-5.12'\"
mkdir 'unzip-5.12'
fi
if test ! -d 'unzip-5.12/amiga' ; then
echo shar: Creating directory \"'unzip-5.12/amiga'\"
mkdir 'unzip-5.12/amiga'
fi
if test ! -d 'unzip-5.12/atari' ; then
echo shar: Creating directory \"'unzip-5.12/atari'\"
mkdir 'unzip-5.12/atari'
fi
if test ! -d 'unzip-5.12/human68k' ; then
echo shar: Creating directory \"'unzip-5.12/human68k'\"
mkdir 'unzip-5.12/human68k'
fi
if test ! -d 'unzip-5.12/mac' ; then
echo shar: Creating directory \"'unzip-5.12/mac'\"
mkdir 'unzip-5.12/mac'
fi
if test ! -d 'unzip-5.12/msdos' ; then
echo shar: Creating directory \"'unzip-5.12/msdos'\"
mkdir 'unzip-5.12/msdos'
fi
if test -f 'unzip-5.12/msdos/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/README'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/README'\" \(4906 characters\)
sed "s/^X//" >'unzip-5.12/msdos/README' <<'END_OF_FILE'
XNotes about MS-DOS executables and compilers:
X
X - Borland start-up code is reported to switch the screen mode auto-
X matically if it's not 80 columns (or possibly 40) and either 25, 43
X or 50 lines. In particular, extended modes such as 100x40 are not
X retained.
X
X - Borland start-up code also uses interrupt 1Ah, causing incorrect
X behavior (including lock-ups) on some Japanese MS-DOS machines such
X as the Fujitsu FMR series, which lack this interrupt.
X
X - Some(?) Borland compilers are apparently incapable of putting static
X data into far memory; this means all of UnZip's strings are in near
X memory, and there is not enough room to enable ZipInfo in the small
X memory model. Even if strings are in far memory, the *code* segment
X produced by Borland compilers is now too big for one segment. The
X large memory model is therefore the default for Borland compilers, but
X it may be possible to compile in the medium model as well (not tested).
X
X - Older Borland compilers do not understand source files with Unix
X line-endings (LF rather than CR/LF). Use "flip" or a similar utility
X to convert the line endings before compiling, or take a look at the
X Borland.fix file in the UnZip source distribution.
X
X - Microsoft C 5.1 large-model code is more than an order of magnitude
X slower than the identical code compiled with MSC 6 or 7 (a factor of
X 15 in our tests, actually). This may be due to a lousy optimizer or
X lousy libraries; regardless, since UnZip is hovering at the doorstep
X of the large memory model, we recommend upgrading to a later version
X of the compiler.
X
XFor these reasons, Info-ZIP's distributed versions of the 16-bit MS-DOS
Xexecutables are compiled with MSC 6 or 7.
X
X - The default wildcard ("globbing") behavior of djgpp/go32 is disabled
X by default in UnZip, but this can be overridden if the GO32 environment
X variable is set to "glob". This will cause UnZip to fail with various
X odd errors about "filename not matched" and the like; to avoid this, set
X the GO32 variable to "noglob" or unset it altogether. (The documented
X method of avoiding this by quoting wildcards with single quotes was
X buggy in djgpp 1.11 but is reported fixed in 1.12; not tested.)
X
X - djgpp's handling of timezones, necessary for the correct conversion of
X MS-DOS filetimes to those used in the Unix-like C library, is completely
X broken in djgpp 1.12 and probably earlier versions as well. It is fixed
X (or very close to it) in the most recent 1.12m1 beta, so be sure to up-
X grade to 1.12m1 before compiling. Otherwise UnZip's -f and -u (freshen/
X update) functions will not work correctly.
X
X - emx+gcc's DOS extender does not understand DPMI, and while there is an
X alternative extender called RSX available (found in dpmigcc4.zip as of
X August 1994), its setup is somewhat kludgy when the local memory manager
X supports both DPMI and VCPI (or something else). It's also not yet as
X widely known or available as djgpp.
X
XFor these reasons Info-ZIP's distributed 32-bit MS-DOS executables are com-
Xpiled with djgpp 1.12m1. These are stand-alone programs; the "go32" DOS
Xextender is included inside the executables. They generally run up to twice
Xas fast as the 16-bit versions, but they only work on 386's and above. In
Xsome cases they're actually slower. If this is the case for you, first try
Xrunning under plain DOS, after removing any memory manager in your config.sys
Xand rebooting, to check if the slowdown is due to your memory manager. (Ac-
Xcording to notes found in another package, there was a known conflict between
Xthe go32 extender and QEMM's DPMI; this was apparently just fixed in QEMM
X7.04/QDPMI 1.05, but if you still have an older version (1.03 or 1.01), add
X"set GO32=nodpmi" to your autoexec.bat to avoid the conflict.) There may
Xalso be a problem with the time spent by the djgpp runtime creating and de-
Xleting a swap file. If you use SMARTDRV or another disk cache, make sure
Xthat writes are also cached.
X
XIf you already have djgpp 1.12m1 or later (or, more specifically, go32.exe
X1.12m1 or later somewhere in your PATH), you can remove go32.exe from
Xunzip386.exe to get a smaller executable:
X
X exe2coff unzip386.exe
X coff2exe unzip386
X del unzip386
X
XAs noted above, go32/djgpp has its own wildcard-expansion routines which
Xare disabled in UnZip by default because of incompatibilities with UnZip's
Xown wildcards. Stripping the go32 extender may cause go32's wildcards to
Xbe re-enabled; in this case you must set GO32 as follows for UnZip to work
Xcorrectly:
X
X set GO32=noglob
X
XWith this setting unzip386.exe behaves just like unzip.exe.
X
XFor other problems related to DJGPP, read the documentation provided in
Xoak.oakland.edu:/pub/msdos/djgpp/djdev112.zip. If a problem occurs with
Xunzip386.exe, check first if it also occurs with unzip.exe before reporting
Xit.
X
X
XGRR 940828
END_OF_FILE
if test 4906 -ne `wc -c <'unzip-5.12/msdos/README'`; then
echo shar: \"'unzip-5.12/msdos/README'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/README'
fi
if test ! -d 'unzip-5.12/nt' ; then
echo shar: Creating directory \"'unzip-5.12/nt'\"
mkdir 'unzip-5.12/nt'
fi
if test ! -d 'unzip-5.12/os2' ; then
echo shar: Creating directory \"'unzip-5.12/os2'\"
mkdir 'unzip-5.12/os2'
fi
if test ! -d 'unzip-5.12/tops20' ; then
echo shar: Creating directory \"'unzip-5.12/tops20'\"
mkdir 'unzip-5.12/tops20'
fi
if test ! -d 'unzip-5.12/unix' ; then
echo shar: Creating directory \"'unzip-5.12/unix'\"
mkdir 'unzip-5.12/unix'
fi
if test -f 'unzip-5.12/unzip.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unzip.h'\"
else
echo shar: Extracting \"'unzip-5.12/unzip.h'\" \(59872 characters\)
sed "s/^X//" >'unzip-5.12/unzip.h' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X unzip.h
X
X This header file is used by all of the UnZip source files. Its contents
X are divided into seven more-or-less separate sections: predefined macros,
X OS-dependent includes, (mostly) OS-independent defines, typedefs, function
X prototypes (or "forward declarations," in the case of non-ANSI compilers),
X macros, and global-variable declarations.
X
X ---------------------------------------------------------------------------*/
X
X
X
X#ifndef __unzip_h /* prevent multiple inclusions */
X#define __unzip_h
X
X/*****************************************/
X/* Predefined, Machine-specific Macros */
X/*****************************************/
X
X#if defined(__GO32__) && defined(unix) /* MS-DOS extender: NOT Unix */
X# undef unix
X#endif
X#if (defined(__convex__) && !defined(__convexc__))
X# define __convexc__
X#endif
X
X#if defined(unix) || defined(M_XENIX) || defined(COHERENT) || defined(__hpux)
X# ifndef UNIX
X# define UNIX
X# endif
X#endif /* unix || M_XENIX || COHERENT || __hpux */
X#if defined(__convexc__) || defined(MINIX)
X# ifndef UNIX
X# define UNIX
X# endif
X#endif /* __convexc__ || MINIX */
X
X#ifdef __COMPILER_KCC__
X# include <c-env.h>
X# ifdef SYS_T20
X# define TOPS20
X# endif
X#endif /* __COMPILER_KCC__ */
X
X/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C */
X#ifdef __POWERC
X# define __TURBOC__
X# define MSDOS
X#endif /* __POWERC */
X#if defined(__MSDOS__) && (!defined(MSDOS)) /* just to make sure */
X# define MSDOS
X#endif
X
X#if defined(linux) && (!defined(LINUX))
X# define LINUX
X#endif
X
X/* use prototypes and ANSI libraries if __STDC__, or Microsoft or Borland C, or
X * Silicon Graphics, or Convex?, or IBM C Set/2, or GNU gcc/emx, or Watcom C,
X * or Macintosh, or Windows NT, or Sequent, or Atari.
X */
X#if defined(__STDC__) || defined(MSDOS) || defined(sgi)
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X#if defined(__IBMC__) || defined(__EMX__) || defined(__WATCOMC__)
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X#if defined(THINK_C) || defined(MPW) || defined(WIN32) || defined(_SEQUENT_)
X# ifndef PTX /* Sequent running Dynix/ptx: non-modern compiler */
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X# endif
X#endif
X#if defined(ATARI_ST) || defined(__BORLANDC__) /* || defined(__convexc__) */
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X
X/* turn off prototypes if requested */
X#if defined(NOPROTO) && defined(PROTO)
X# undef PROTO
X#endif
X
X/* used to remove arguments in function prototypes for non-ANSI C */
X#ifdef PROTO
X# define OF(a) a
X#else
X# define OF(a) ()
X#endif
X
X/* bad or (occasionally?) missing stddef.h: */
X#if defined(M_XENIX) || defined(DNIX)
X# define NO_STDDEF_H
X#endif
X
X#if defined(apollo) /* defines __STDC__ */
X# define NO_STDLIB_H
X#endif /* apollo */
X
X#ifdef DNIX
X# define SYSV
X# define SHORT_NAMES /* 14-char limitation on path components */
X/* # define FILENAME_MAX 14 */
X# define FILENAME_MAX NAME_MAX /* GRR: experiment */
X#endif
X
X#if (defined(__SYSTEM_FIVE) || defined(M_SYSV) || defined(M_SYS5))
X# ifndef SYSV
X# define SYSV
X# endif
X#endif /* __SYSTEM_FIVE || M_SYSV || M_SYS5 */
X
X#if (defined(ultrix) || defined(bsd4_2) || defined(sun) || defined(pyr))
X# if (!defined(BSD) && !defined(SYSV))
X# define BSD
X# endif
X#endif /* ultrix || bsd4_2 || sun || pyr */
X#if defined(__convexc__)
X# if (!defined(BSD) && !defined(SYSV))
X# define BSD
X# endif
X#endif /* __convexc__ */
X
X#ifdef pyr /* Pyramid */
X# ifdef BSD
X# define pyr_bsd
X# define USE_STRINGS_H /* instead of more common string.h */
X# endif
X# define ZMEM /* should ZMEM only be for BSD universe...? */
X# define DECLARE_ERRNO /* (AT&T memcpy was claimed to be very slow) */
X#endif /* pyr */
X
X#if (defined(CRAY) && defined(ZMEM))
X# undef ZMEM
X#endif
X
X/* stat() bug for Borland, Watcom, VAX C (also GNU?), and Atari ST MiNT on
X * TOS filesystems: returns 0 for wildcards! (returns 0xffffffff on Minix
X * filesystem or U: drive under Atari MiNT) */
X#if (defined(__TURBOC__) || defined(__WATCOMC__) || defined(VMS))
X# define WILD_STAT_BUG
X#endif
X#if (defined(__MINT__))
X# define WILD_STAT_BUG
X#endif
X
X#ifdef WILD_STAT_BUG
X# define SSTAT(path,pbuf) (iswild(path) || stat(path,pbuf))
X#else
X# define SSTAT stat
X#endif
X
X#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */
X# define stat(p,s) zstat(p,s)
X#endif
X
X#define STRNICMP zstrnicmp
X
X
X
X
X
X
X/***************************/
X/* OS-Dependent Includes */
X/***************************/
X
X#ifndef MINIX /* Minix needs it after all the other includes (?) */
X# include <stdio.h>
X#endif
X#include <ctype.h> /* skip for VMS, to use tolower() function? */
X#include <errno.h> /* used in mapname() */
X#ifdef USE_STRINGS_H
X# include <strings.h> /* strcpy, strcmp, memcpy, index/rindex, etc. */
X#else
X# include <string.h> /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */
X#endif
X#ifdef MODERN
X# include <limits.h> /* GRR: EXPERIMENTAL! (can be deleted) */
X#endif
X
X#ifdef EFT
X# define LONGINT off_t /* Amdahl UTS nonsense ("extended file types") */
X#else
X# define LONGINT long
X#endif
X
X#ifdef MODERN
X# ifndef NO_STDDEF_H
X# include <stddef.h>
X# endif
X# ifndef NO_STDLIB_H
X# include <stdlib.h> /* standard library prototypes, malloc(), etc. */
X# endif
X typedef size_t extent;
X typedef void voidp;
X#else /* !MODERN */
X LONGINT lseek();
X# ifdef VAXC /* not fully modern, but does have stdlib.h */
X# include <stdlib.h>
X# else
X char *malloc();
X# endif
X typedef unsigned int extent;
X typedef char voidp;
X# define void int
X#endif /* ?MODERN */
X
X/* this include must be down here for SysV.4, for some reason... */
X#include <signal.h> /* used in unzip.c, file_io.c */
X
X/*---------------------------------------------------------------------------
X Amiga section:
X ---------------------------------------------------------------------------*/
X
X#ifdef AMIGA
X# include "amiga/amiga.h"
X# ifndef AZTEC_C
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# endif
X# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
X# define DATE_FORMAT DF_MDY
X# define lenEOL 1
X# define PutNativeEOL *q++ = native(LF);
X/* # define USE_FWRITE if write() returns 16-bit int */
X# define PIPE_ERROR (errno == 9999) /* always false */
X#endif
X
X/*---------------------------------------------------------------------------
X Atari ST section:
X ---------------------------------------------------------------------------*/
X
X#if (defined(ATARI_ST) || defined(__MINT__)) /* comments by [cjh] */
X# ifdef __TURBOC__
X# include <ext.h> /* stat() */
X# include <tos.h> /* OS-specific functions (Fdup) */
X# endif
X# include <time.h>
X# ifndef __MINT__
X# define dup Fdup
X# define mkdir Dcreate
X# define DIR_END '\\'
X# else
X# include <sys/types.h> /* didn't we include this already? */
X# include <sys/stat.h>
X# include <fcntl.h> /* O_BINARY */
X# include <unistd.h> /* dup proto & unix system calls live here */
X# include <time.h>
X# include <stdio.h> /* didn't we include this already? */
X# define dup dup
X# define mkdir mkdir
X# define DIR_END '/' /* much sexier than DOS filenames... */
X# define timezone _timezone /* oops */
X# define DIRENT
X# define SYMLINKS
X# ifdef S_ISLNK /* WARNING: horrible kludge!!!! */
X# undef S_ISLNK /* MiNTlibs & POSIX don't define S_ISLNK */
X# define S_ISLNK(a) (((a) & 0xa000) == 0xa000)
X# endif
X# ifdef SHORT_NAMES /* library will truncate weird names on TOS fs */
X# undef SHORT_NAMES
X# endif
X# ifndef ZMEM
X# define ZMEM /* we have bcopy, etc., ifndef __STRICT_ANSI__ */
X# endif
X# endif /* __MINT__ */
X# ifndef S_IFMT
X# define S_IFMT (S_IFCHR | S_IFREG | S_IFDIR)
X# endif
X# define DATE_FORMAT DF_MDY
X# ifndef lenEOL
X# define lenEOL 2 /* DOS convention; MiNT doesn't really care */
X# endif
X# ifndef PutNativeEOL
X# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
X# endif
X# define EXE_EXTENSION ".tos" /* or .ttp instead?? */
X#endif
X
X/*---------------------------------------------------------------------------
X Human68k/X68000 section:
X ---------------------------------------------------------------------------*/
X
X#ifdef __human68k__ /* DO NOT DEFINE DOS_OS2 HERE! If Human68k is so much */
X# include <time.h> /* like MS-DOS and/or OS/2, create DOS_HUM_OS2 macro. */
X# include <fcntl.h>
X# include <io.h>
X# include <conio.h>
X# include <jctype.h>
X# include <sys/stat.h>
X# define DATE_FORMAT DF_YMD /* Japanese standard */
X /* GRR: these EOL macros are guesses */
X# define lenEOL 2
X# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
X# define EXE_EXTENSION ".exe" /* just a guess... */
X#endif
X
X/*---------------------------------------------------------------------------
X Mac section:
X ---------------------------------------------------------------------------*/
X
X#ifdef THINK_C
X# define MACOS
X# ifndef __STDC__ /* if Think C hasn't defined __STDC__ ... */
X# define __STDC__ 1 /* make sure it's defined: it needs it */
X# else
X# if !__STDC__ /* sometimes __STDC__ is defined as 0; */
X# undef __STDC__ /* it needs to be 1 or required header */
X# define __STDC__ 1 /* files are not properly included. */
X# endif /* !__STDC__ */
X# endif
X# define CREATOR 'KAHL'
X# define MAIN unzip
X#endif /* THINK_C */
X
X#ifdef MPW
X# define MACOS
X# include <Errors.h>
X# include <Files.h>
X# include <Memory.h>
X# include <Quickdraw.h>
X# include <ToolUtils.h>
X# ifdef fileno
X# undef fileno
X# endif
X# ifdef MCH_MACINTOSH
X# define CREATOR 'Manx'
X# else
X# define CREATOR 'MPS '
X# endif
X#endif /* MPW */
X
X#ifdef MACOS
X# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
X# define fileno(x) ((x) == stdout ? 1 : (short)(x))
X# define open(x,y) macopen((x), (y), gnVRefNum, glDirID)
X# define fopen(x,y) macfopen((x), (y), gnVRefNum, glDirID)
X# define close macclose
X# define fclose(x) macclose(fileno((x)))
X# define read macread
X# define write macwrite
X# define lseek maclseek
X# define creat(x,y) maccreat((x), gnVRefNum, glDirID, gostCreator, gostType)
X# define stat(x,y) macstat((x), (y), gnVRefNum, glDirID)
X# define dup
X# ifndef MCH_MACINTOSH
X# define NO_STRNICMP
X# endif
X# define DIR_END ':'
X# define DATE_FORMAT DF_MDY
X# define lenEOL 1
X# define PutNativeEOL *q++ = native(CR);
X# define MALLOC_WORK
X
X# ifdef THINK_C
X# define fgets wfgets
X# define fflush(f)
X# define fprintf wfprintf
X# define fputs(s,f) wfprintf((f), "%s", (s))
X# define printf wprintf
X# ifdef putc
X# undef putc
X# endif
X# define putc(c,f) wfprintf((f), "%c", (c))
X# define getenv macgetenv
X# endif
X
X# ifndef isascii
X# define isascii(c) ((unsigned char)(c) <= 0x3F)
X# endif
X
X# include "macstat.h"
X# include "macdir.h"
X
X# ifdef CR
X# undef CR
X# endif
X
Xtypedef struct _ZipExtraHdr {
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
X} ZIP_EXTRA_HEADER;
X
Xtypedef struct _MacInfoMin {
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
X unsigned long signature; /* 4 bytes */
X FInfo finfo; /* 16 bytes */
X unsigned long lCrDat; /* 4 bytes */
X unsigned long lMdDat; /* 4 bytes */
X unsigned long flags ; /* 4 bytes */
X unsigned long lDirID; /* 4 bytes */
X /*------------*/
X} MACINFOMIN; /* = 40 bytes for size of data */
X
Xtypedef struct _MacInfo {
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
X unsigned long signature; /* 4 bytes */
X FInfo finfo; /* 16 bytes */
X unsigned long lCrDat; /* 4 bytes */
X unsigned long lMdDat; /* 4 bytes */
X unsigned long flags ; /* 4 bytes */
X unsigned long lDirID; /* 4 bytes */
X char rguchVolName[28]; /* 28 bytes */
X /*------------*/
X} MACINFO; /* = 68 bytes for size of data */
X#endif /* MACOS */
X
X/*---------------------------------------------------------------------------
X MS-DOS and OS/2 section:
X ---------------------------------------------------------------------------*/
X
X#ifdef MSDOS
X# include <dos.h> /* for REGS macro (TC) or _dos_setftime (MSC) */
X# ifdef __TURBOC__ /* includes Power C */
X# include <sys/timeb.h> /* for structure ftime */
X# ifndef __BORLANDC__ /* there appears to be a bug (?) in Borland's */
X# include <mem.h> /* MEM.H related to __STDC__ and far poin- */
X# endif /* ters. (dpk) [mem.h included for memcpy] */
X# endif
X#endif /* MSDOS */
X
X#ifdef __IBMC__
X# define S_IFMT 0xF000
X# define timezone _timezone
X# define PIPE_ERROR (errno == EERRSET || errno == EOS2ERR)
X#endif
X
X#ifdef __WATCOMC__
X# define __32BIT__
X# undef far
X# define far
X# undef near
X# define near
X# define PIPE_ERROR (errno == -1)
X#endif
X
X#ifdef __EMX__
X# ifndef __32BIT__
X# define __32BIT__
X# endif
X# define far
X#endif
X
X#ifdef __GO32__ /* note: MS-DOS compiler, not OS/2 */
X# ifndef __32BIT__
X# define __32BIT__
X# endif
X# include <sys/timeb.h> /* for structure ftime */
X int setmode(int, int); /* not in djgpp's include files */
X#endif
X
X#if defined(_MSC_VER) && (!defined(MSC))
X# define MSC /* for old versions, MSC must be set explicitly */
X#endif
X
X#if 0 /* GRR 930907: MSC 5.1 does declare errno but doesn't define _MSC_VER */
X#ifdef MSC
X# ifndef _MSC_VER /* new with 5.1 or 6.0 ... */
X# define DECLARE_ERRNO /* not declared in errno.h in 5.0 or earlier? */
X# endif
X#endif
X#endif /* 0 */
X
X#if defined(MSDOS) || defined(OS2)
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# include <io.h> /* lseek(), open(), setftime(), dup(), creat() */
X# include <time.h> /* localtime() */
X# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
X# ifdef __GO32__
X# define DIR_END '/'
X# else
X# define DIR_END '\\'
X# endif
X# if (defined(M_I86CM) || defined(M_I86LM))
X# define MED_MEM
X# endif
X# if (defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__))
X# define MED_MEM
X# endif
X# ifndef __32BIT__
X# ifndef MED_MEM
X# define SMALL_MEM
X# endif
X/* # define USE_FWRITE write() *can* write up to 65534 bytes after all */
X# endif
X# define DATE_FORMAT dateformat()
X# define lenEOL 2
X# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
X#endif
X
X#ifdef OS2 /* defined for all OS/2 compilers */
X# ifdef MSDOS
X# undef MSDOS
X# endif
X# ifdef isupper
X# undef isupper
X# endif
X# ifdef tolower
X# undef tolower
X# endif
X# define isupper(x) IsUpperNLS((unsigned char)(x))
X# define tolower(x) ToLowerNLS((unsigned char)(x))
X#endif
X
X#ifdef MSDOS
X# define EXE_EXTENSION ".exe" /* OS/2 has GetLoadPath() function instead */
X#endif
X
X#if defined(MSWIN) && defined(FILE_IO_C)
X# include "wizunzip.h"
X#endif
X
X/*---------------------------------------------------------------------------
X MTS section (piggybacks UNIX, I think):
X ---------------------------------------------------------------------------*/
X
X#ifdef MTS
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# include <sys/file.h> /* MTS uses this instead of fcntl.h */
X# include <timeb.h>
X# include <time.h>
X# include <unix.h> /* some important non-ANSI routines */
X# define mkdir(s,n) (-1) /* no "make directory" capability */
X# define EBCDIC /* set EBCDIC conversion on */
X# define NO_STRNICMP /* unzip's is as good the one in MTS */
X# define USE_FWRITE
X# define close_outfile() fclose(outfile) /* can't set time on files */
X# define umask(n) /* Don't have umask() on MTS */
X# define FOPWT "w" /* Open file for writing in TEXT mode */
X# define DATE_FORMAT DF_MDY
X# define lenEOL 1
X# define PutNativeEOL *q++ = native(LF);
X#endif
X
X/*---------------------------------------------------------------------------
X NT section:
X ---------------------------------------------------------------------------*/
X
X#ifdef WIN32 /* NT */
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# include <io.h> /* read(), open(), etc. */
X# include <time.h>
X# include <memory.h>
X# include <direct.h> /* mkdir() */
X# include <fcntl.h>
X# if defined(FILE_IO_C)
X# include <conio.h>
X# include <sys\types.h>
X# include <sys\utime.h>
X# include <windows.h>
X# endif
X# define DATE_FORMAT DF_MDY
X# define lenEOL 2
X# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
X# define NT
X# if (defined(_MSC_VER) && !defined(MSC))
X# define MSC
X# endif
X#endif
X
X/*---------------------------------------------------------------------------
X TOPS-20 section:
X ---------------------------------------------------------------------------*/
X
X#ifdef TOPS20
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# include <sys/param.h>
X# include <sys/time.h>
X# include <sys/timeb.h>
X/* # include <utime.h> GRR: not used, I suspect... */
X# include <sys/file.h>
X# include <timex.h>
X# include <monsym.h> /* get amazing monsym() macro */
X extern int open(), close(), read();
X extern int stat(), unlink(), jsys(), fcntl();
X extern long lseek(), dup(), creat();
X# define strchr index /* GRR: necessary? */
X# define strrchr rindex
X# define REALLY_SHORT_SYMS
X# define NO_MKDIR
X# define DIR_BEG '<'
X# define DIR_END '>'
X# define DIR_EXT ".directory"
X# define DATE_FORMAT DF_MDY
X# define EXE_EXTENSION ".exe" /* just a guess... */
X#endif /* TOPS20 */
X
X/*---------------------------------------------------------------------------
X Unix section:
X ---------------------------------------------------------------------------*/
X
X#ifdef UNIX
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X
X# ifndef COHERENT
X# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
X# else /* COHERENT */
X# ifdef _I386
X# include <fcntl.h> /* Coherent 4.0.x, Mark Williams C */
X# else
X# include <sys/fcntl.h> /* Coherent 3.10, Mark Williams C */
X# endif
X# define SHORT_SYMS
X# ifndef __COHERENT__ /* Coherent 4.2 has tzset() */
X# define tzset settz
X# endif
X# endif /* ?COHERENT */
X
X# ifndef NO_PARAM_H
X# ifdef NGROUPS_MAX
X# undef NGROUPS_MAX /* SCO bug: defined again in <sys/param.h> */
X# endif
X# ifdef BSD
X# define TEMP_BSD /* may be defined again in <sys/param.h> */
X# undef BSD
X# endif
X# include <sys/param.h> /* conflict with <sys/types.h>, some systems? */
X# ifdef TEMP_BSD
X# undef TEMP_BSD
X# ifndef BSD
X# define BSD
X# endif
X# endif
X# endif /* !NO_PARAM_H */
X
X# ifdef __osf__
X# define DIRENT
X# ifdef BSD
X# undef BSD
X# endif
X# endif /* __osf__ */
X
X# ifdef BSD
X# include <sys/time.h>
X# include <sys/timeb.h>
X# ifdef _AIX
X# include <time.h>
X# endif
X# else
X# include <time.h>
X struct tm *gmtime(), *localtime();
X# endif
X
X# if defined(BSD4_4) || defined(LINUX) || (defined(SYSV) && defined(MODERN))
X# include <unistd.h> /* this includes utime.h, at least on SGIs */
X# endif
X
X# if defined(BSD4_4) || defined(_POSIX_SOURCE) || defined(sgi) || defined(_AIX)
X# include <utime.h> /* NeXT, at least, does NOT define utimbuf in here */
X# else
X struct utimbuf {
X time_t actime; /* new access time */
X time_t modtime; /* new modification time */
X };
X# endif /* ?(BSD4_4 || _POSIX_SOURCE || sgi || _AIX) */
X
X# if (defined(V7) || defined(pyr_bsd))
X# define strchr index
X# define strrchr rindex
X# endif
X# ifdef V7
X# define O_RDONLY 0
X# define O_WRONLY 1
X# define O_RDWR 2
X# endif
X
X# ifdef MINIX
X# include <stdio.h>
X# endif
X# define DATE_FORMAT DF_MDY
X# define lenEOL 1
X# define PutNativeEOL *q++ = native(LF);
X#endif /* UNIX */
X
X/*---------------------------------------------------------------------------
X VMS section:
X ---------------------------------------------------------------------------*/
X
X#ifdef VMS
X# include <types.h> /* GRR: experimenting... */
X# include <stat.h>
X# include <time.h> /* the usual non-BSD time functions */
X# include <file.h> /* same things as fcntl.h has */
X# include <unixio.h>
X# include <rms.h>
X# define _MAX_PATH NAM$C_MAXRSS /* to define FILNAMSIZ below */
X# define RETURN return_VMS /* VMS interprets return codes incorrectly */
X# define DIR_BEG '['
X# define DIR_END ']'
X# define DIR_EXT ".dir"
X# define DATE_FORMAT DF_MDY
X# define lenEOL 1
X# define PutNativeEOL *q++ = native(LF);
X#endif /* VMS */
X
X
X
X
X
X/*************/
X/* Defines */
X/*************/
X
X#define UNZIP
X#define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */
X#define VMS_UNZIP_VERSION 42 /* if OS-needed-to-extract is VMS: can do */
X
X#if defined(MSDOS) || defined(NT) || defined(OS2)
X# define DOS_NT_OS2
X#endif
X
X#if defined(MSDOS) || defined(OS2)
X# define DOS_OS2
X#endif
X
X#if defined(MSDOS) || defined(OS2) || defined(ATARI_ST)
X# define DOS_OS2_TOS
X#endif
X
X#if defined(MSDOS) || defined(ATARI_ST)
X# define DOS_TOS
X#endif
X
X#if defined(MSDOS) || defined(TOPS20) || defined(VMS)
X# define DOS_T20_VMS
X#endif
X
X#if defined(TOPS20) || defined(VMS)
X# define T20_VMS
X#endif
X
X/* clean up with a few defaults */
X#ifndef DIR_END
X# define DIR_END '/' /* last char before program name (or filename) */
X#endif
X#ifndef RETURN
X# define RETURN return /* only used in main() */
X#endif
X#ifndef PRINTF
X# define PRINTF printf
X#endif
X#ifndef FPRINTF
X# define FPRINTF fprintf
X#endif
X#ifndef PUTC
X# define PUTC putc /* putchar() not used: use PUTC(c,stdout) instead */
X#endif
X
X#define DIR_BLKSIZ 64 /* number of directory entries per block
X * (should fit in 4096 bytes, usually) */
X#ifndef WSIZE
X# define WSIZE 0x8000 /* window size--must be a power of two, and */
X#endif /* at least 32K for zip's deflate method */
X
X#ifndef INBUFSIZ
X# if (defined(MED_MEM) || defined(SMALL_MEM))
X# define INBUFSIZ 2048 /* works for MS-DOS small model */
X# else
X# define INBUFSIZ 8192 /* larger buffers for real OSes */
X# endif
X#endif
X
X/* GRR: NT defines MSDOS?? */
X#if (!defined(MSDOS) && !defined(__IBMC__)) || defined(NT)
X# define near
X# define far
X#endif
X#if defined(__GO32__) || defined(__EMX__)
X# define near
X# define far
X#endif
X
X/* Logic for case of small memory, length of EOL > 1: if OUTBUFSIZ == 2048,
X * OUTBUFSIZ>>1 == 1024 and OUTBUFSIZ>>7 == 16; therefore rawbuf is 1008 bytes
X * and transbuf 1040 bytes. Have room for 32 extra EOL chars; 1008/32 == 31.5
X * chars/line, smaller than estimated 35-70 characters per line for C source
X * and normal text. Hence difference is sufficient for most "average" files.
X * (Argument scales for larger OUTBUFSIZ.)
X */
X#ifdef SMALL_MEM /* i.e., 16-bit OS's: MS-DOS, OS/2 1.x, etc. */
X# ifndef Far
X# define Far far /* __far only works for MSC 6.00, not 6.0a or Borland */
X# endif
X# define OUTBUFSIZ INBUFSIZ
X# if (lenEOL == 1)
X# define RAWBUFSIZ (OUTBUFSIZ>>1)
X# else
X# define RAWBUFSIZ ((OUTBUFSIZ>>1) - (OUTBUFSIZ>>7))
X# endif
X# define TRANSBUFSIZ (OUTBUFSIZ-RAWBUFSIZ)
X#else
X# define LoadFarString(x) x
X# define LoadFarStringSmall(x) x
X# define LoadFarStringSmall2(x) x
X# ifdef MED_MEM
X# define OUTBUFSIZ 0xFF80 /* can't malloc arrays of 0xFFE8 or more */
X# define TRANSBUFSIZ 0xFF80
X# else
X# define OUTBUFSIZ (lenEOL*WSIZE) /* more efficient text conversion */
X# define TRANSBUFSIZ (lenEOL*OUTBUFSIZ)
X# define NEW_UNSHRINK
X# endif
X# define RAWBUFSIZ OUTBUFSIZ
X#endif /* ?SMALL_MEM */
X
X#ifndef Far
X# define Far /* GRR: should combine this with near/far above */
X#endif
X
X#ifndef MAIN
X# define MAIN main
X#endif
X
X#if (defined(SFX) && !defined(NO_ZIPINFO))
X# define NO_ZIPINFO
X#endif
X
X#ifndef O_BINARY
X# define O_BINARY 0
X#endif
X
X#ifndef PIPE_ERROR
X# define PIPE_ERROR (errno == EPIPE)
X#endif
X
X/* File operations--use "b" for binary if allowed or fixed length 512 on VMS */
X#ifdef VMS
X# define FOPR "r","ctx=stm"
X# define FOPM "r+","ctx=stm","rfm=fix","mrs=512"
X# define FOPW "w","ctx=stm","rfm=fix","mrs=512"
X#else /* !VMS */
X# if defined(MODERN) || defined(AMIGA)
X# define FOPR "rb"
X# define FOPM "r+b"
X# ifdef TOPS20 /* TOPS-20 MODERN? You kidding? */
X# define FOPW "w8"
X# else
X# define FOPW "wb"
X# endif
X# else /* !MODERN */
X# define FOPR "r"
X# define FOPM "r+"
X# define FOPW "w"
X# endif /* ?MODERN */
X#endif /* VMS */
X
X/*
X * If <limits.h> exists on most systems, should include that, since it may
X * define some or all of the following: NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
X * _POSIX_PATH_MAX.
X */
X#ifdef DOS_OS2_TOS
X# include <limits.h>
X#endif
X
X#ifndef PATH_MAX
X# ifdef MAXPATHLEN
X# define PATH_MAX MAXPATHLEN /* in <sys/param.h> on some systems */
X# else
X# ifdef _MAX_PATH
X# define PATH_MAX _MAX_PATH
X# else
X# if FILENAME_MAX > 255
X# define PATH_MAX FILENAME_MAX /* used like PATH_MAX on some systems */
X# else
X# define PATH_MAX 1024
X# endif
X# endif /* ?_MAX_PATH */
X# endif /* ?MAXPATHLEN */
X#endif /* !PATH_MAX */
X
X#define FILNAMSIZ (PATH_MAX+1)
X
X#ifdef SHORT_SYMS /* Mark Williams C, ...? */
X# define extract_or_test_files xtr_or_tst_files
X# define extract_or_test_member xtr_or_tst_member
X#endif
X
X#ifdef REALLY_SHORT_SYMS /* TOPS-20 linker: first 6 chars */
X# define process_cdir_file_hdr XXpcdfh
X# define process_local_file_hdr XXplfh
X# define extract_or_test_files XXxotf /* necessary? */
X# define extract_or_test_member XXxotm /* necessary? */
X# define check_for_newer XXcfn
X# define overwrite_all XXoa
X# define process_all_files XXpaf
X# define extra_field XXef
X# define explode_lit8 XXel8
X# define explode_lit4 XXel4
X# define explode_nolit8 XXnl8
X# define explode_nolit4 XXnl4
X# define cpdist8 XXcpdist8
X# define inflate_codes XXic
X# define inflate_stored XXis
X# define inflate_fixed XXif
X# define inflate_dynamic XXid
X# define inflate_block XXib
X# define maxcodemax XXmax
X#endif
X
X#define ZSUFX ".zip"
X#define CENTRAL_HDR_SIG "\113\001\002" /* the infamous "PK" signature */
X#define LOCAL_HDR_SIG "\113\003\004" /* bytes, sans "P" (so unzip */
X#define END_CENTRAL_SIG "\113\005\006" /* executable not mistaken for */
X#define EXTD_LOCAL_SIG "\113\007\010" /* zipfile itself) */
X
X#define SKIP 0 /* choice of activities for do_string() */
X#define DISPLAY 1
X#define FILENAME 2
X#define EXTRA_FIELD 3
X
X#define DOES_NOT_EXIST -1 /* return values for check_for_newer() */
X#define EXISTS_AND_OLDER 0
X#define EXISTS_AND_NEWER 1
X
X#define ROOT 0 /* checkdir() extract-to path: called once */
X#define INIT 1 /* allocate buildpath: called once per member */
X#define APPEND_DIR 2 /* append a dir comp.: many times per member */
X#define APPEND_NAME 3 /* append actual filename: once per member */
X#define GETPATH 4 /* retrieve the complete path and free it */
X#define END 5 /* free root path prior to exiting program */
X
X/* version_made_by codes (central dir): make sure these */
X/* are not defined on their respective systems!! */
X#define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, NT */
X#define AMIGA_ 1
X#define VMS_ 2
X#define UNIX_ 3
X#define VM_CMS_ 4
X#define ATARI_ 5 /* what if it's a minix filesystem? [cjh] */
X#define FS_HPFS_ 6 /* filesystem used by OS/2, NT */
X#define MAC_ 7
X#define Z_SYSTEM_ 8
X#define CPM_ 9
X#define TOPS20_ 10
X#define FS_NTFS_ 11 /* filesystem used by Windows NT */
X#define QDOS_MAYBE_ 12 /* a bit premature, but somebody once started */
X#define ACORN_ 13 /* Archimedes Acorn RISCOS */
X#define NUM_HOSTS 14 /* index of last system + 1 */
X
X#define STORED 0 /* compression methods */
X#define SHRUNK 1
X#define REDUCED1 2
X#define REDUCED2 3
X#define REDUCED3 4
X#define REDUCED4 5
X#define IMPLODED 6
X#define TOKENIZED 7
X#define DEFLATED 8
X#define NUM_METHODS 9 /* index of last method + 1 */
X/* don't forget to update list_files() appropriately if NUM_METHODS changes */
X
X#define PK_OK 0 /* no error */
X#define PK_COOL 0 /* no error */
X#define PK_GNARLY 0 /* no error */
X#define PK_WARN 1 /* warning error */
X#define PK_ERR 2 /* error in zipfile */
X#define PK_BADERR 3 /* severe error in zipfile */
X#define PK_MEM 4 /* insufficient memory */
X#define PK_MEM2 5 /* insufficient memory */
X#define PK_MEM3 6 /* insufficient memory */
X#define PK_MEM4 7 /* insufficient memory */
X#define PK_MEM5 8 /* insufficient memory */
X#define PK_NOZIP 9 /* zipfile not found */
X#define PK_PARAM 10 /* bad or illegal parameters specified */
X#define PK_FIND 11 /* no files found */
X#define PK_DISK 50 /* disk full */
X#define PK_EOF 51 /* unexpected EOF */
X
X#define IZ_DIR 76 /* potential zipfile is a directory */
X#define IZ_CREATED_DIR 77 /* directory created: set time and permissions */
X#define IZ_VOL_LABEL 78 /* volume label, but can't set on hard disk */
X
X#define DF_MDY 0 /* date format 10/26/91 (USA only) */
X#define DF_DMY 1 /* date format 26/10/91 (most of the world) */
X#define DF_YMD 2 /* date format 91/10/26 (a few countries) */
X
X/*---------------------------------------------------------------------------
X True sizes of the various headers, as defined by PKWARE--so it is not
X likely that these will ever change. But if they do, make sure both these
X defines AND the typedefs below get updated accordingly.
X ---------------------------------------------------------------------------*/
X#define LREC_SIZE 26 /* lengths of local file headers, central */
X#define CREC_SIZE 42 /* directory headers, and the end-of- */
X#define ECREC_SIZE 18 /* central-dir record, respectively */
X
X#define MAX_BITS 13 /* used in old unshrink() */
X#define HSIZE (1 << MAX_BITS) /* size of global work area */
X
X#define LF 10 /* '\n' on ASCII machines; must be 10 due to EBCDIC */
X#define CR 13 /* '\r' on ASCII machines; must be 13 due to EBCDIC */
X#define CTRLZ 26 /* DOS & OS/2 EOF marker (used in file_io.c, vms.c) */
X
X#ifdef EBCDIC
X# define native(c) ebcdic[(c)]
X# define NATIVE "EBCDIC"
X#endif
X
X#ifdef MPW
X# define FFLUSH(f) PUTC('\n',f)
X#else
X# define FFLUSH fflush
X#endif
X
X#ifdef ZMEM /* GRR: THIS IS AN EXPERIMENT... (seems to work) */
X# undef ZMEM
X# define memcpy(dest,src,len) bcopy(src,dest,len)
X# define memzero bzero
X#else
X# define memzero(dest,len) memset(dest,0,len)
X#endif
X
X#ifdef VMS
X# define ENV_UNZIP "UNZIP_OPTS" /* name of environment variable */
X# define ENV_ZIPINFO "ZIPINFO_OPTS"
X#else /* !VMS */
X# define ENV_UNZIP "UNZIP"
X# define ENV_ZIPINFO "ZIPINFO"
X#endif /* ?VMS */
X#define ENV_UNZIP2 "UNZIPOPT" /* alternate name for zip compat. */
X#define ENV_ZIPINFO2 "ZIPINFOOPT"
X
X#if !defined(QQ) && !defined(NOQQ)
X# define QQ
X#endif
X
X#ifdef QQ /* Newtware version: no file */
X# define QCOND (!qflag) /* comments with -vq or -vqq */
X#else /* Bill Davidsen version: no way to */
X# define QCOND (which_hdr) /* kill file comments when listing */
X#endif
X
X#ifdef OLD_QQ
X# define QCOND2 (qflag < 2)
X#else
X# define QCOND2 (!qflag)
X#endif
X
X#ifndef TRUE
X# define TRUE 1 /* sort of obvious */
X#endif
X#ifndef FALSE
X# define FALSE 0
X#endif
X
X#ifndef SEEK_SET
X# define SEEK_SET 0
X# define SEEK_CUR 1
X# define SEEK_END 2
X#endif
X
X#if (defined(UNIX) && defined(S_IFLNK) && !defined(MTS))
X# define SYMLINKS
X# ifndef S_ISLNK
X# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
X# endif
X#endif /* UNIX && S_IFLNK && !MTS */
X
X#ifndef S_ISDIR
X# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
X#endif
X
X#ifndef IS_VOLID
X# define IS_VOLID(m) ((m) & 0x08)
X#endif
X
X
X
X
X
X/**************/
X/* Typedefs */
X/**************/
X
Xtypedef char boolean;
Xtypedef unsigned char uch; /* code assumes unsigned bytes; these type- */
Xtypedef unsigned short ush; /* defs replace byte/UWORD/ULONG (which are */
Xtypedef unsigned long ulg; /* predefined on some systems) & match zip */
X
Xtypedef struct min_info {
X long offset;
X ulg compr_size; /* compressed size (needed if extended header) */
X ulg crc; /* crc (needed if extended header) */
X int hostnum;
X unsigned file_attr; /* local flavor, as used by creat(), chmod()... */
X unsigned encrypted : 1; /* file encrypted: decrypt before uncompressing */
X unsigned ExtLocHdr : 1; /* use time instead of CRC for decrypt check */
X unsigned textfile : 1; /* file is text (according to zip) */
X unsigned textmode : 1; /* file is to be extracted as text */
X unsigned lcflag : 1; /* convert filename to lowercase */
X unsigned vollabel : 1; /* "file" is an MS-DOS volume (disk) label */
X} min_info;
X
Xtypedef struct VMStimbuf {
X char *revdate; /* (both correspond to Unix modtime/st_mtime) */
X char *credate;
X} VMStimbuf;
X
X/*---------------------------------------------------------------------------
X Zipfile work area declarations.
X ---------------------------------------------------------------------------*/
X
X#ifdef MALLOC_WORK
X
X union work {
X struct {
X short *Prefix_of; /* (8193 * sizeof(short)) */
X uch *Suffix_of;
X uch *Stack;
X } shrink; /* unshrink() */
X uch *Slide; /* explode(), inflate(), unreduce() */
X };
X# define prefix_of area.shrink.Prefix_of
X# define suffix_of area.shrink.Suffix_of
X# define stack area.shrink.Stack
X
X#else /* !MALLOC_WORK */
X
X# ifdef NEW_UNSHRINK /* weird segmentation violations if union NODE array */
X union work {
X uch Stack[8192]; /* unshrink() */
X uch Slide[WSIZE]; /* explode(), inflate(), unreduce() */
X };
X# define stack area.Stack
X# else
X union work {
X struct {
X short Prefix_of[HSIZE]; /* (8192 * sizeof(short)) */
X uch Suffix_of[HSIZE];
X uch Stack[HSIZE];
X } shrink;
X uch Slide[WSIZE]; /* explode(), inflate(), unreduce() */
X };
X# define prefix_of area.shrink.Prefix_of
X# define suffix_of area.shrink.Suffix_of
X# define stack area.shrink.Stack
X# endif /* ?NEW_UNSHRINK */
X
X#endif /* ?MALLOC_WORK */
X
X#define slide area.Slide
X
X/*---------------------------------------------------------------------------
X Zipfile layout declarations. If these headers ever change, make sure the
X xxREC_SIZE defines (above) change with them!
X ---------------------------------------------------------------------------*/
X
X typedef uch local_byte_hdr[ LREC_SIZE ];
X# define L_VERSION_NEEDED_TO_EXTRACT_0 0
X# define L_VERSION_NEEDED_TO_EXTRACT_1 1
X# define L_GENERAL_PURPOSE_BIT_FLAG 2
X# define L_COMPRESSION_METHOD 4
X# define L_LAST_MOD_FILE_TIME 6
X# define L_LAST_MOD_FILE_DATE 8
X# define L_CRC32 10
X# define L_COMPRESSED_SIZE 14
X# define L_UNCOMPRESSED_SIZE 18
X# define L_FILENAME_LENGTH 22
X# define L_EXTRA_FIELD_LENGTH 24
X
X typedef uch cdir_byte_hdr[ CREC_SIZE ];
X# define C_VERSION_MADE_BY_0 0
X# define C_VERSION_MADE_BY_1 1
X# define C_VERSION_NEEDED_TO_EXTRACT_0 2
X# define C_VERSION_NEEDED_TO_EXTRACT_1 3
X# define C_GENERAL_PURPOSE_BIT_FLAG 4
X# define C_COMPRESSION_METHOD 6
X# define C_LAST_MOD_FILE_TIME 8
X# define C_LAST_MOD_FILE_DATE 10
X# define C_CRC32 12
X# define C_COMPRESSED_SIZE 16
X# define C_UNCOMPRESSED_SIZE 20
X# define C_FILENAME_LENGTH 24
X# define C_EXTRA_FIELD_LENGTH 26
X# define C_FILE_COMMENT_LENGTH 28
X# define C_DISK_NUMBER_START 30
X# define C_INTERNAL_FILE_ATTRIBUTES 32
X# define C_EXTERNAL_FILE_ATTRIBUTES 34
X# define C_RELATIVE_OFFSET_LOCAL_HEADER 38
X
X typedef uch ec_byte_rec[ ECREC_SIZE+4 ];
X/* define SIGNATURE 0 space-holder only */
X# define NUMBER_THIS_DISK 4
X# define NUM_DISK_WITH_START_CENTRAL_DIR 6
X# define NUM_ENTRIES_CENTRL_DIR_THS_DISK 8
X# define TOTAL_ENTRIES_CENTRAL_DIR 10
X# define SIZE_CENTRAL_DIRECTORY 12
X# define OFFSET_START_CENTRAL_DIRECTORY 16
X# define ZIPFILE_COMMENT_LENGTH 20
X
X
X typedef struct local_file_header { /* LOCAL */
X uch version_needed_to_extract[2];
X ush general_purpose_bit_flag;
X ush compression_method;
X ush last_mod_file_time;
X ush last_mod_file_date;
X ulg crc32;
X ulg csize;
X ulg ucsize;
X ush filename_length;
X ush extra_field_length;
X } local_file_hdr;
X
X typedef struct central_directory_file_header { /* CENTRAL */
X uch version_made_by[2];
X uch version_needed_to_extract[2];
X ush general_purpose_bit_flag;
X ush compression_method;
X ush last_mod_file_time;
X ush last_mod_file_date;
X ulg crc32;
X ulg csize;
X ulg ucsize;
X ush filename_length;
X ush extra_field_length;
X ush file_comment_length;
X ush disk_number_start;
X ush internal_file_attributes;
X ulg external_file_attributes;
X ulg relative_offset_local_header;
X } cdir_file_hdr;
X
X typedef struct end_central_dir_record { /* END CENTRAL */
X ush number_this_disk;
X ush num_disk_with_start_central_dir;
X ush num_entries_centrl_dir_ths_disk;
X ush total_entries_central_dir;
X ulg size_central_directory;
X ulg offset_start_central_directory;
X ush zipfile_comment_length;
X } ecdir_rec;
X
X
X
X
X
X/*************************/
X/* Function Prototypes */
X/*************************/
X
X#ifndef __
X# define __ OF
X#endif
X
X/*---------------------------------------------------------------------------
X Functions in unzip.c (main initialization/driver routines):
X ---------------------------------------------------------------------------*/
X
Xint uz_opts __((int *pargc, char ***pargv));
Xint usage __((int error));
Xint process_zipfiles __((void));
Xint do_seekable __((int lastchance));
Xint uz_end_central __((void));
Xint process_cdir_file_hdr __((void));
Xint process_local_file_hdr __((void));
X
X/*---------------------------------------------------------------------------
X Functions in zipinfo.c (zipfile-listing routines):
X ---------------------------------------------------------------------------*/
X
Xint zi_opts __((int *pargc, char ***pargv));
Xint zi_end_central __((void));
Xint zipinfo __((void));
X/* static int zi_long __((void)); */
X/* static int zi_short __((void)); */
X/* static char *zi_time __((ush *datez, ush *timez)); */
Xulg SizeOfEAs __((void *extra_field)); /* also in os2.c? */
Xint list_files __((void));
X/* static int ratio __((ulg uc, ulg c)); */
X
X/*---------------------------------------------------------------------------
X Functions in file_io.c:
X ---------------------------------------------------------------------------*/
X
Xint open_input_file __((void));
Xint open_outfile __((void)); /* also vms.c */
Xunsigned readbuf __((char *buf, register unsigned len));
Xint FillBitBuffer __((void));
Xint readbyte __((void));
X#ifdef FUNZIP
X int flush __((ulg size));
X#else
X int flush __((uch *buf, ulg size, int unshrink));
X#endif
Xvoid handler __((int signal));
Xtime_t dos_to_unix_time __((unsigned ddate, unsigned dtime));
Xint check_for_newer __((char *filename)); /* also os2.c, vms.c */
Xint find_ecrec __((long searchlen));
Xint get_cdir_ent __((void));
Xint do_string __((unsigned int len, int option));
Xush makeword __((uch *b));
Xulg makelong __((uch *sig));
Xint zstrnicmp __((register char *s1, register char *s2, register int n));
X
X#ifdef ZMEM /* MUST be ifdef'd because of conflicts with the standard def. */
X char *memset __((register char *, register char, register unsigned int));
X char *memcpy __((register char *, register char *, register unsigned int));
X#endif
X
X#ifdef SMALL_MEM
X char *LoadFarString __((char Far *sz));
X char *LoadFarStringSmall __((char Far *sz));
X char *LoadFarStringSmall2 __((char Far *sz));
X char Far * Far zfstrcpy __((char Far *s1, const char Far *s2));
X#endif
X
X
X/*---------------------------------------------------------------------------
X Functions in extract.c:
X ---------------------------------------------------------------------------*/
X
Xint extract_or_test_files __((void));
X/* static int store_info __((void)); */
X/* static int extract_or_test_member __((void)); */
Xint memextract __((uch *, ulg, uch *, ulg));
Xint FlushMemory __((void));
Xint ReadMemoryByte __((ush *x));
X
X/*---------------------------------------------------------------------------
X Decompression functions:
X ---------------------------------------------------------------------------*/
X
Xint explode __((void)); /* explode.c */
Xint inflate __((void)); /* inflate.c */
Xint inflate_free __((void)); /* inflate.c */
Xvoid unreduce __((void)); /* unreduce.c */
X/* static void LoadFollowers __((void)); * unreduce.c */
Xint unshrink __((void)); /* unshrink.c */
X/* static void partial_clear __((void)); * unshrink.c */
X
X/*---------------------------------------------------------------------------
X Human68K-only functions:
X ---------------------------------------------------------------------------*/
X
X#ifdef __human68k__
X void InitTwentyOne __((void));
X#endif
X
X/*---------------------------------------------------------------------------
X Macintosh-only functions:
X ---------------------------------------------------------------------------*/
X
X#ifdef MACOS
X int macmkdir __((char *, short, long));
X short macopen __((char *, short, short, long));
X FILE *macfopen __((char *, char *, short, long));
X short maccreat __((char *, short, long, OSType, OSType));
X short macread __((short, char *, unsigned));
X long macwrite __((short, char *, unsigned));
X short macclose __((short));
X long maclseek __((short, long, short));
X char *macgetenv __((char *));
X char *wfgets __((char *, int, FILE *));
X void wfprintf __((FILE *, char *, ...));
X void wprintf __((char *, ...));
X#endif
X
X/*---------------------------------------------------------------------------
X MSDOS-only functions:
X ---------------------------------------------------------------------------*/
X
X#if (defined(__GO32__) || (defined(MSDOS) && defined(__EMX__)))
X unsigned _dos_getcountryinfo(void *); /* msdos.c */
X void _dos_setftime(int, unsigned short, unsigned short); /* msdos.c */
X void _dos_setfileattr(char *, int); /* msdos.c */
X unsigned _dos_creat(char *, unsigned, int *); /* msdos.c */
X void _dos_getdrive(unsigned *); /* msdos.c */
X unsigned _dos_close(int); /* msdos.c */
X#endif
X
X/*---------------------------------------------------------------------------
X OS/2-only functions:
X ---------------------------------------------------------------------------*/
X
X#ifdef OS2 /* GetFileTime conflicts with something in NT header files */
X int GetCountryInfo __((void)); /* os2.c */
X long GetFileTime __((char *name)); /* os2.c */
X void SetPathInfo __((char *path, ush moddate, ush modtime, int flags));
X int IsEA __((void *extra_field)); /* os2.c */
X void SetEAs __((char *path, void *eablock)); /* os2.c */
X ulg SizeOfEAs __((void *extra_field)); /* os2.c */
X/* static int IsFileNameValid __((char *name)); os2.c */
X/* static void map2fat __((char *pathcomp, char **pEndFAT)); os2.c */
X/* static int SetLongNameEA __((char *name, char *longname)); os2.c */
X/* static void InitNLS __((void)); os2.c */
X int IsUpperNLS __((int nChr)); /* os2.c */
X int ToLowerNLS __((int nChr)); /* os2.c */
X void DebugMalloc __((void)); /* os2.c */
X#endif
X
X/*---------------------------------------------------------------------------
X TOPS20-only functions:
X ---------------------------------------------------------------------------*/
X
X#ifdef TOPS20
X int upper __((char *s)); /* tops20.c */
X int enquote __((char *s)); /* tops20.c */
X int dequote __((char *s)); /* tops20.c */
X int fnlegal __(()); /* error if prototyped(?) */ /* tops20.c */
X#endif
X
X/*---------------------------------------------------------------------------
X VMS-only functions:
X ---------------------------------------------------------------------------*/
X
X#ifdef VMS
X int check_format __((void)); /* vms.c */
X int find_vms_attrs __((void)); /* vms.c */
X int CloseOutputFile __((void)); /* vms.c */
X/* static uch *extract_block __((struct extra_block *, int *, uch *, int)); */
X/* static int _flush_blocks __((int final_flag)); * vms.c */
X/* static int _flush_records __((int final_flag)); * vms.c */
X/* static int WriteBuffer __((unsigned char *buf, int len)); * vms.c */
X/* static int WriteRecord __((unsigned char *rec, int len)); * vms.c */
X/* static void message __((int string, char *status)); * vms.c */
X void return_VMS __((int zip_error)); /* vms.c */
X#ifdef VMSCLI
X ulg vms_unzip_cmdline __((int *, char ***)); /* cmdline.c */
X#endif
X#endif
X
X/*---------------------------------------------------------------------------
X Miscellaneous/shared functions:
X ---------------------------------------------------------------------------*/
X
Xint match __((char *s, char *p, int ic)); /* match.c */
Xint iswild __((char *p)); /* match.c */
X
Xvoid envargs __((int *, char ***, char *, char *)); /* envargs.c */
Xvoid mksargs __((int *, char ***)); /* envargs.c */
X
Xint dateformat __((void));
Xvoid version __((void)); /* local */
Xint mapattr __((void)); /* local */
Xint mapname __((int renamed)); /* local */
Xint checkdir __((char *pathcomp, int flag)); /* local */
Xchar *do_wild __((char *wildzipfn)); /* local */
Xchar *GetLoadPath __((void)); /* local */
X#ifndef MTS /* macro in MTS */
X void close_outfile __((void)); /* local */
X#endif
X
X
X
X
X
X/************/
X/* Macros */
X/************/
X
X#ifndef MAX
X# define MAX(a,b) ((a) > (b) ? (a) : (b))
X#endif
X#ifndef MIN
X# define MIN(a,b) ((a) < (b) ? (a) : (b))
X#endif
X
X#ifdef DEBUG
X# define Trace(x) FPRINTF x
X#else
X# define Trace(x)
X#endif
X
X#if defined(UNIX) || defined(T20_VMS) /* generally old systems */
X# define ToLower(x) ((char)(isupper((int)x)? tolower((int)x) : x))
X#else
X# define ToLower tolower /* assumed "smart"; used in match() */
X#endif
X
X
X#define LSEEK(abs_offset) {LONGINT request=(abs_offset)+extra_bytes,\
X inbuf_offset=request%INBUFSIZ, bufstart=request-inbuf_offset;\
X if(request<0) {FPRINTF(stderr, LoadFarStringSmall(SeekMsg), LoadFarString(ReportMsg)); return(3);}\
X else if(bufstart!=cur_zipfile_bufstart)\
X {cur_zipfile_bufstart=lseek(zipfd,(LONGINT)bufstart,SEEK_SET);\
X if((incnt=read(zipfd,(char *)inbuf,INBUFSIZ))<=0) return(51);\
X inptr=inbuf+(int)inbuf_offset; incnt-=(int)inbuf_offset;} else\
X {incnt+=(inptr-inbuf)-(int)inbuf_offset; inptr=inbuf+(int)inbuf_offset;}}
X
X/*
X * Seek to the block boundary of the block which includes abs_offset,
X * then read block into input buffer and set pointers appropriately.
X * If block is already in the buffer, just set the pointers. This macro
X * is used by process_end_central_dir (unzip.c) and do_string (file_io.c).
X * A slightly modified version is embedded within extract_or_test_files
X * (unzip.c). ReadByte and readbuf (file_io.c) are compatible.
X *
X * macro LSEEK(abs_offset)
X * ulg abs_offset;
X * {
X * LONGINT request = abs_offset + extra_bytes;
X * LONGINT inbuf_offset = request % INBUFSIZ;
X * LONGINT bufstart = request - inbuf_offset;
X *
X * if (request < 0) {
X * FPRINTF(stderr, LoadFarStringSmall(SeekMsg),
X * LoadFarString(ReportMsg));
X * return(3); /-* 3: severe error in zipfile *-/
X * } else if (bufstart != cur_zipfile_bufstart) {
X * cur_zipfile_bufstart = lseek(zipfd, (LONGINT)bufstart, SEEK_SET);
X * if ((incnt = read(zipfd,inbuf,INBUFSIZ)) <= 0)
X * return(51); /-* 51: unexpected EOF *-/
X * inptr = inbuf + (int)inbuf_offset;
X * incnt -= (int)inbuf_offset;
X * } else {
X * incnt += (inptr-inbuf) - (int)inbuf_offset;
X * inptr = inbuf + (int)inbuf_offset;
X * }
X * }
X *
X */
X
X
X#define SKIP_(length) if(length&&((error=do_string(length,SKIP))!=0))\
X {error_in_archive=error; if(error>1) return error;}
X
X/*
X * Skip a variable-length field, and report any errors. Used in zipinfo.c
X * and unzip.c in several functions.
X *
X * macro SKIP_(length)
X * ush length;
X * {
X * if (length && ((error = do_string(length, SKIP)) != 0)) {
X * error_in_archive = error; /-* might be warning *-/
X * if (error > 1) /-* fatal *-/
X * return (error);
X * }
X * }
X *
X */
X
X
X#ifdef FUNZIP
X# define FLUSH flush
X# define NEXTBYTE getc(in) /* redefined in crypt.h if full version */
X#else
X# define FLUSH(w) if (mem_mode) outcnt=(w); else flush(slide,(ulg)w,0)
X# define NEXTBYTE \
X (csize-- <= 0L ? EOF : (--incnt >= 0 ? (int)(*inptr++) : readbyte()))
X#endif
X
X
X#define READBITS(nbits,zdest) {if(nbits>bits_left) {int temp; zipeof=1;\
X while (bits_left<=8*(sizeof(bitbuf)-1) && (temp=NEXTBYTE)!=EOF) {\
X bitbuf|=(ulg)temp<<bits_left; bits_left+=8; zipeof=0;}}\
X zdest=(int)((ush)bitbuf&mask_bits[nbits]);bitbuf>>=nbits;bits_left-=nbits;}
X
X/*
X * macro READBITS(nbits,zdest) * only used by unreduce and unshrink *
X * {
X * if (nbits > bits_left) { * fill bitbuf, which is 8*sizeof(ulg) bits *
X * int temp;
X *
X * zipeof = 1;
X * while (bits_left <= 8*(sizeof(bitbuf)-1) &&
X * (temp = NEXTBYTE) != EOF) {
X * bitbuf |= (ulg)temp << bits_left;
X * bits_left += 8;
X * zipeof = 0;
X * }
X * }
X * zdest = (int)((ush)bitbuf & mask_bits[nbits]);
X * bitbuf >>= nbits;
X * bits_left -= nbits;
X * }
X *
X */
X
X
X/* GRR: should change name to STRLOWER and use StringLower if possible */
X
X/*
X * Copy the zero-terminated string in str1 into str2, converting any
X * uppercase letters to lowercase as we go. str2 gets zero-terminated
X * as well, of course. str1 and str2 may be the same character array.
X */
X#ifdef __human68k__
X# define TOLOWER(str1, str2) \
X { \
X char *p=(str1), *q=(str2); \
X uch c; \
X while ((c = *p++) != '\0') { \
X if (iskanji(c)) { \
X if (*p == '\0') \
X break; \
X *q++ = c; \
X *q++ = *p++; \
X } else \
X *q++ = isupper(c) ? tolower(c) : c; \
X } \
X *q = '\0'; \
X }
X#else
X# define TOLOWER(str1, str2) \
X { \
X char *p, *q; \
X p = (str1) - 1; \
X q = (str2); \
X while (*++p) \
X *q++ = (char)(isupper((int)(*p))? tolower((int)(*p)) : *p); \
X *q = '\0'; \
X }
X#endif
X/*
X * NOTES: This macro makes no assumptions about the characteristics of
X * the tolower() function or macro (beyond its existence), nor does it
X * make assumptions about the structure of the character set (i.e., it
X * should work on EBCDIC machines, too). The fact that either or both
X * of isupper() and tolower() may be macros has been taken into account;
X * watch out for "side effects" (in the C sense) when modifying this
X * macro.
X */
X
X
X#ifndef native
X# define native(c) (c)
X# define A_TO_N(str1)
X#else
X# ifndef NATIVE
X# define NATIVE "native chars"
X# endif
X# define A_TO_N(str1) {register unsigned char *p;\
X for (p=str1; *p; p++) *p=native(*p);}
X#endif
X
X/*
X * Translate the zero-terminated string in str1 from ASCII to the native
X * character set. The translation is performed in-place and uses the
X * "native" macro to translate each character.
X *
X * macro A_TO_N( str1 )
X * {
X * register unsigned char *p;
X *
X * for (p = str1; *p; ++p)
X * *p = native(*p);
X * }
X *
X * NOTE: Using the "native" macro means that is it the only part of unzip
X * which knows which translation table (if any) is actually in use to
X * produce the native character set. This makes adding new character set
X * translation tables easy, insofar as all that is needed is an appropriate
X * "native" macro definition and the translation table itself. Currently,
X * the only non-ASCII native character set implemented is EBCDIC, but this
X * may not always be so.
X */
X
X
X
X
X
X/*************/
X/* Globals */
X/*************/
X
X extern int zipinfo_mode;
X extern int aflag;
X extern int cflag;
X extern int C_flag;
X extern int fflag;
X extern int hflag;
X extern int jflag;
X extern int lflag;
X extern int L_flag;
X extern int overwrite_none;
X extern int overwrite_all;
X extern int force_flag;
X extern int qflag;
X#ifdef DOS_NT_OS2
X extern int sflag;
X extern int volflag;
X#endif
X extern int tflag;
X extern int T_flag;
X extern int uflag;
X extern int vflag;
X extern int V_flag;
X#ifdef VMS
X extern int secinf;
X#endif
X extern int zflag;
X#ifdef MACOS
X extern int HFSFlag;
X#endif
X extern int filespecs;
X extern int xfilespecs;
X extern int process_all_files;
X extern int create_dirs;
X#ifndef NO_ZIPINFO
X extern int newzip;
X#endif
X extern LONGINT real_ecrec_offset;
X extern LONGINT expect_ecrec_offset;
X extern long csize;
X extern long ucsize;
X extern long used_csize;
X extern char **pfnames;
X extern char **pxnames;
X extern char near sig[];
X extern char near answerbuf[];
X extern min_info *pInfo;
X
X extern union work area;
X
X#ifdef FUNZIP
X extern ulg near crc_32_tab[];
X#else
X extern ulg *crc_32_tab;
X#endif
X extern ulg crc32val;
X extern ush near mask_bits[];
X
X extern uch *inbuf;
X extern uch *inptr;
X extern int incnt;
X extern ulg bitbuf;
X extern int bits_left;
X extern boolean zipeof;
X extern char *zipfn;
X extern int zipfd;
X extern LONGINT ziplen;
X extern LONGINT cur_zipfile_bufstart;
X extern LONGINT extra_bytes;
X extern uch *extra_field;
X extern uch *hold;
X extern char near local_hdr_sig[];
X extern char near central_hdr_sig[];
X extern char near end_central_sig[];
X extern local_file_hdr lrec;
X extern cdir_file_hdr crec;
X extern ecdir_rec ecrec;
X extern struct stat statbuf;
X
X extern int mem_mode;
X extern int disk_full;
X extern int newfile;
X#ifdef SYMLINKS
X extern int symlnk;
X#endif
X#ifdef FUNZIP
X extern FILE *in;
X#endif
X extern FILE *outfile;
X extern uch *outbuf;
X extern uch *outbuf2;
X extern uch *outptr;
X extern ulg outcnt;
X#ifdef MSWIN
X extern char *filename;
X#else
X extern char near filename[];
X#endif
X
X#ifdef DECLARE_ERRNO
X extern int errno;
X#endif
X
X#ifdef EBCDIC
X extern uch ebcdic[];
X#endif
X
X#ifdef MACOS
X extern short gnVRefNum;
X extern long glDirID;
X extern OSType gostCreator;
X extern OSType gostType;
X extern boolean fMacZipped;
X extern boolean macflag;
X extern short giCursor;
X extern CursHandle rghCursor[];
X#endif
X
X extern char Far CentSigMsg[];
X extern char Far EndSigMsg[];
X extern char Far SeekMsg[];
X extern char Far ReportMsg[];
X extern char Far FilenameNotMatched[];
X extern char Far ExclFilenameNotMatched[];
X
X#endif /* !__unzip_h */
END_OF_FILE
if test 59872 -ne `wc -c <'unzip-5.12/unzip.h'`; then
echo shar: \"'unzip-5.12/unzip.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unzip.h'
fi
if test ! -d 'unzip-5.12/vms' ; then
echo shar: Creating directory \"'unzip-5.12/vms'\"
mkdir 'unzip-5.12/vms'
fi
echo shar: End of archive 1 \(of 20\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 20 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...

Info-ZIP group

unread,
Sep 19, 1994, 12:14:15 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 67
Archive-name: unzip/part02

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/nt/Contents unzip-5.12/unzip.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:36 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 2 (of 20)."'
if test -f 'unzip-5.12/nt/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/nt/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/nt/Contents'\" \(202 characters\)
sed "s/^X//" >'unzip-5.12/nt/Contents' <<'END_OF_FILE'
XContents of the "nt" sub-archive for UnZip 5.1 and later:
X
X Contents this file
X Makefile makefile for UnZip and MS NT SDK or VC++, or DEC C/C++
X nt.c NT-specific support routines
X
END_OF_FILE
if test 202 -ne `wc -c <'unzip-5.12/nt/Contents'`; then
echo shar: \"'unzip-5.12/nt/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/nt/Contents'
fi
if test -f 'unzip-5.12/unzip.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unzip.c'\"
else
echo shar: Extracting \"'unzip-5.12/unzip.c'\" \(66790 characters\)
sed "s/^X//" >'unzip-5.12/unzip.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X unzip.c
X
X UnZip - a zipfile extraction utility. See below for make instructions, or
X read the comments in Makefile and the various Contents files for more de-
X tailed explanations. To report a bug, send a *complete* description to
X zip-...@wkuvx1.wku.edu; include machine type, operating system and ver-
X sion, compiler and version, and reasonably detailed error messages or prob-
X lem report. To join Info-ZIP, see the instructions in README.
X
X UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
X which in turn was almost a complete rewrite of version 3.x. For a detailed
X revision history, see UnzpHist.zip at quest.jpl.nasa.gov. For a list of
X the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
X distribution.
X
X ---------------------------------------------------------------------------
X
X [from original zipinfo.c]
X
X This program reads great gobs of totally nifty information, including the
X central directory stuff, from ZIP archives ("zipfiles" for short). It
X started as just a testbed for fooling with zipfiles, but at this point it
X is actually a useful utility. It also became the basis for the rewrite of
X UnZip (3.16 -> 4.0), using the central directory for processing rather than
X the individual (local) file headers.
X
X As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
X If the executable is named "unzip" (or "unzip.exe", depending), it behaves
X like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
X ZipInfo. The ZipInfo behavior may also be triggered by use of unzip's -Z
X option; for example, "unzip -Z [zipinfo_options] archive.zip".
X
X Another dandy product from your buddies at Newtware!
X
X Author: Greg Roelofs, ne...@uchicago.edu, 23 August 1990 -> ... 1994
X
X ---------------------------------------------------------------------------
X
X Version: unzip512.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Windows,
X Windows NT, Macintosh, Amiga, Atari, Human68K and TOPS-20. De-
X cryption requires sources in zcrypt23.zip, and Windows (not NT)
X support requires sources in wunz20sr.zip (not up to date). See
X accompanying file "Where" in the main source distribution for
X ftp, uucp and mail-server sites.
X
X Copyrights: see accompanying file "COPYING" in UnZip source distribution.
X
X ---------------------------------------------------------------------------*/
X
X
X
X#include "unzip.h" /* includes, typedefs, macros, prototypes, etc. */
X#include "crypt.h"
X#include "version.h"
X#ifdef MSWIN


X# include "wizunzip.h"
X#endif
X
X

X
X/**********************/
X/* Global Variables */
X/**********************/
X
Xint zipinfo_mode; /* behave like ZipInfo or like normal UnZip? */
X
Xint aflag=0; /* -a: do ASCII-EBCDIC and/or end-of-line translation */
Xint cflag=0; /* -c: output to stdout */
Xint C_flag=0; /* -C: match filenames case-insensitively */
Xint dflag=0; /* -d: all args are files/dirs to be extracted */
Xint fflag=0; /* -f: "freshen" (extract only newer files) */
Xint hflag=0; /* -h: header line (zipinfo) */
Xint jflag=0; /* -j: junk pathnames (unzip) */
Xint lflag=(-1); /* -12slmv: listing format (zipinfo) */
Xint L_flag=0; /* -L: convert filenames from some OSes to lowercase */
Xint overwrite_none=0; /* -n: never overwrite files (no prompting) */
Xint overwrite_all=0; /* -o: OK to overwrite files without prompting */
Xint force_flag=0; /* (shares -o for now): force to override errors, etc. */
Xint qflag=0; /* -q: produce a lot less output */
X#ifdef DOS_NT_OS2
X int sflag=0; /* -s: convert filename spaces (blanks) to underscores */
X int volflag=0; /* -$: extract volume labels */
X#endif
Xint tflag=0; /* -t: test (unzip) or totals line (zipinfo) */
Xint T_flag=0; /* -T: decimal time format (zipinfo) */
Xint uflag=0; /* -u: "update" (extract only newer & brand-new files) */
Xint vflag=0; /* -v: (verbosely) list directory */
Xint V_flag=0; /* -V: don't strip VMS version numbers */
X#ifdef VMS
X int secinf=0; /* -X: keep owner/protection */
X#endif
Xint zflag=0; /* -z: display the zipfile comment (only, for unzip) */
X
Xint filespecs; /* number of real file specifications to be matched */
Xint xfilespecs; /* number of excluded filespecs to be matched */
Xint process_all_files = 0;
Xint create_dirs; /* used by main(), mapname(), checkdir() */
Xint extract_flag;
X
X#if (defined(CRYPT) || !defined(NO_ZIPINFO))
X int newzip; /* used in extract.c, crypt.c, zipinfo.c */
X#endif
X
XLONGINT real_ecrec_offset, expect_ecrec_offset;
X
Xlong csize; /* used by list_files(), ReadByte(): must be signed */
Xlong ucsize; /* used by list_files(), unReduce(), explode() */
Xlong used_csize; /* used by extract_or_test_member(), explode() */
X
Xstatic char *fnames[2] = {"*", NULL}; /* default filenames vector */
Xchar **pfnames = fnames, **pxnames = &fnames[1];
Xchar near sig[5];
Xchar near answerbuf[10];
X
Xmin_info info[DIR_BLKSIZ], *pInfo=info;
X
X/*---------------------------------------------------------------------------
X unreduce/unshrink/explode/inflate working storage and globals:
X ---------------------------------------------------------------------------*/
X
Xunion work area; /* see unzip.h for the definition of work */
Xulg crc32val;
X
Xush near mask_bits[] = {
X 0x0000,
X 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
X 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
X};
X
X/*---------------------------------------------------------------------------
X Input file variables:
X ---------------------------------------------------------------------------*/
X
Xuch *inbuf, *inptr; /* input buffer (any size is OK) and pointer */
Xint incnt;
X
Xulg bitbuf;
Xint bits_left;
Xboolean zipeof;
X
X#ifdef SFX
X char *argv0; /* used for NT and EXE_EXTENSION */
X#else
X char *wildzipfn;
X#endif
Xchar *zipfn; /* GRR: MSWIN: must nuke any malloc'd zipfn... */
X
Xint zipfd; /* zipfile file handle */
XLONGINT ziplen;
X
Xuch *hold;
Xchar near local_hdr_sig[5]; /* initialize signatures at runtime so unzip */
Xchar near central_hdr_sig[5]; /* executable won't look like a zipfile */
Xchar near end_central_sig[5];
X/* char extd_local_sig[5]; NOT USED YET */
X
Xcdir_file_hdr crec; /* used in unzip.c, extract.c, misc.c */
Xlocal_file_hdr lrec; /* used in unzip.c, extract.c */
Xecdir_rec ecrec; /* used in unzip.c, extract.c */
Xstruct stat statbuf; /* used by main, mapname, check_for_newer */
X
XLONGINT cur_zipfile_bufstart; /* extract_or_test_files, readbuf, ReadByte */
XLONGINT extra_bytes = 0; /* used in unzip.c, misc.c */
X
Xuch *extra_field = (uch *)NULL; /* used by VMS, Mac and OS/2 versions */
X
X#ifdef MACOS
X short gnVRefNum;
X long glDirID;
X OSType gostCreator;
X OSType gostType;
X boolean fMacZipped;
X boolean macflag;
X CursHandle rghCursor[4]; /* status cursors */
X short giCursor = 0;
X#endif
X
X/*---------------------------------------------------------------------------
X Output stream variables:
X ---------------------------------------------------------------------------*/
X
Xint mem_mode = 0;
Xint disk_full;
X#ifdef SYMLINKS
X int symlnk;
X#endif
XFILE *outfile;
Xuch *outbuf;
Xuch *outptr;
Xulg outcnt; /* number of chars stored in outbuf */
X#ifdef SMALL_MEM
X uch *outbuf2; /* initialized in main() (never changes) */
X#else
X uch *outbuf2 = (uch *)NULL; /* malloc'd ONLY if unshrink and -a */
X#endif
X#ifdef MSWIN
X char *filename;
X#else
X char near filename[FILNAMSIZ]; /* also used by NT for temporary SFX path */


X#endif
X
X
X
X
X

X/********************/
X/* Global strings */
X/********************/
X
Xchar Far UnzipVersion[] = UZ_VERSION; /* now defined in version.h */
X#ifndef NO_ZIPINFO
X char Far ZipinfoVersion[] = ZI_VERSION;
X#endif
X
Xchar Far EndSigMsg[] = "\nnote:\
X didn't find end-of-central-dir signature at end of central dir.\n";
Xchar Far CentSigMsg[] =
X "error: expected central file header signature not found (file #%u).\n";
Xchar Far SeekMsg[] =
X "error [%s]: attempt to seek before beginning of zipfile\n%s";
Xchar Far FilenameNotMatched[] = "caution: filename not matched: %s\n";
Xchar Far ExclFilenameNotMatched[] =
X "caution: excluded filename not matched: %s\n";
X
X#ifndef SFX
X char Far CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
X#endif
X
X#ifdef VMS
X char Far ReportMsg[] = "\
X (please check that you have transferred or created the zipfile in the\n\
X appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
X#else
X char Far ReportMsg[] = "\
X (please check that you have transferred or created the zipfile in the\n\
X appropriate BINARY mode and that you have compiled unzip properly)\n";
X#endif
X
X/*******************/
X/* Local strings */
X/*******************/
X
X#ifndef SFX
X static char Far EnvUnZip[] = ENV_UNZIP;
X static char Far EnvUnZip2[] = ENV_UNZIP2;
X static char Far EnvZipInfo[] = ENV_ZIPINFO;
X static char Far EnvZipInfo2[] = ENV_ZIPINFO2;
X#endif
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X static char Far NotExtracting[] = "caution: not extracting; -d ignored\n";
X static char Far MustGiveExdir[] =
X "error: must specify directory to which to extract with -d option\n";
X#endif
X
Xstatic char Far CentDirTooLong[] =
X "error [%s]: reported length of central directory is\n\
X %d bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1\n\
X zipfile?). Compensating...\n";
Xstatic char Far InvalidOptionsMsg[] = "error:\
X -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
Xstatic char Far IgnoreOOptionMsg[] =
X "caution: both -n and -o specified; ignoring -o\n";
Xstatic char Far CantAllocateBuffers[] =
X "error: can't allocate unzip buffers\n";
X
X/* usage() strings */
X#ifndef VMSCLI
X#ifndef SFX
X#ifdef VMS
X static char Far Example2[] = "vms.c";
X static char Far Example1[] =
X"unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS";
X#else
X static char Far Example2[] = "ReadMe";
X static char Far Example1[] =
X"unzip -p foo | more => send contents of foo.zip via pipe into program more";
X#endif /* ?VMS */
X
X#ifdef DOS_NT_OS2
X static char Far loc_str[] = " -$ label removables (-$$ => fixed disks)";
X static char Far loc2str[] = "\
X -s spaces in filenames => '_'\n";
X#else /* !DOS_NT_OS2 */
X#ifdef VMS
X static char Far loc_str[] = "\"-X\" restore owner/protection info";
X static char Far loc2str[] = "\n";
X#else
X static char Far loc_str[] = ""; /* Unix, Amiga, Mac, etc. */
X /* char Far loc_str[] = " -X restore UID/GID info"; Unix version, in 5.2 */
X static char Far loc2str[] = "";
X#endif /* ?VMS */
X#endif /* ?DOS_NT_OS2 */
X#endif /* !SFX */
X
X#ifndef NO_ZIPINFO
X#ifdef VMSWILD
X static char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
X#else
X static char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
X#endif
Xstatic char Far ZipInfoUsageLine1[] = "\
XZipInfo %s, by Newtware and the fine folks at Info-ZIP.\n\
X\n\
XList name, date/time, attribute, size, compression method, etc., about files\n\
Xin list (excluding those in xlist) contained in the specified .zip archive(s).\
X\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
X usage: zipinfo [-12smlvhtTz] file[.zip] [list...] [-x xlist...]\n\
X or: unzip %s-Z%s [-12smlvhtTz] file[.zip] [list...] [-x xlist...]\n";
X
Xstatic char Far ZipInfoUsageLine2[] = "\nmain\
X listing-format options: -s short Unix \"ls -l\" format (def.)\n\
X -1 filenames ONLY, one per line -m medium Unix \"ls -l\" format\n\
X -2 just filenames but allow -h/-t/-z -l long Unix \"ls -l\" format\n\
X -v verbose, multi-page format\n";
X
Xstatic char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
X -h print header line -t print totals for listed files or for all\n\
X -z print zipfile comment %c-T%c print file times in sortable decimal format\
X\n -x exclude filenames that follow from listing\n";
X/*" -p disable automatic \"more\" function (for pipes) [not implemented]\n";*/
X#endif /* !NO_ZIPINFO */
X#endif /* !VMSCLI */
X
X#ifdef BETA
X static char Far BetaVersion[] = "%s\
X THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
X#endif
X
X#ifdef SFX
X# if (defined(SFX_EXDIR) && !defined(VMS))
X static char Far UnzipSFXUsage[] = "\
XUnZipSFX %s, by Info-ZIP (zip-...@wkuvx1.wku.edu).\n\
XValid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCLV%s.\n";
X# else
X static char Far UnzipSFXUsage[] = "\
XUnZipSFX %s, by Info-ZIP (zip-...@wkuvx1.wku.edu).\n\
XValid options are -tfupcz; modifiers are -abjnoqCLV%s.\n";
X# endif
X static char Far CantFindMyself[] =
X "unzipsfx: can't find myself! [%s]\n";
X#else /* !SFX */
X static char Far CompileOptions[] = "UnZip special compilation options:\n";
X static char Far CompileOptFormat[] = "\t%s\n";
X static char Far EnvOptions[] = "\nUnZip and ZipInfo environment options:\n";
X static char Far EnvOptFormat[] = "%16s: %s\n";
X static char Far None[] = "[none]";
X# ifdef NO_ZIPINFO
X static char Far No_ZipInfo[] = "NO_ZIPINFO";
X# endif
X# ifdef CHECK_EOF
X static char Far Check_EOF[] = "CHECK_EOF";
X# endif
X# ifdef DOSWILD
X static char Far DosWild[] = "DOSWILD";
X# endif
X# ifdef VMSWILD
X static char Far VmsWild[] = "VMSWILD";
X# endif
X# ifdef VMSCLI
X static char Far VmsCLI[] = "VMSCLI";
X# endif
X# ifdef ASM_INFLATECODES
X static char Far AsmInflateCodes[] = "ASM_INFLATECODES";
X# endif
X# ifdef ASM_CRC
X static char Far AsmCRC[] = "ASM_CRC";
X# endif
X# ifdef REGARGS
X static char Far RegArgs[] = "REGARGS";
X# endif
X# ifdef OLD_EXDIR
X static char Far Old_Exdir[] = "OLD_EXDIR";
X# endif
X# ifdef CHECK_VERSIONS
X static char Far Check_Versions[] = "CHECK_VERSIONS";
X# endif
X# ifdef RETURN_CODES
X static char Far Return_Codes[] = "RETURN_CODES";
X# endif
X# ifdef RETURN_SEVERITY
X static char Far Return_Severity[] = "RETURN_SEVERITY";
X# endif
X# ifdef DEBUG
X static char Far Debug[] = "DEBUG";
X# endif
X# ifdef DEBUG_TIME
X static char Far DebugTime[] = "DEBUG_TIME";
X# endif
X# ifdef CRYPT
X static char Far Decryption[] = "[decryption]";
X# endif
X# ifdef __EMX__
X static char Far EnvEMX[] = "EMX";
X static char Far EnvEMXOPT[] = "EMXOPT";
X# endif
X# ifdef __GO32__
X static char Far EnvGO32[] = "GO32";
X static char Far EnvGO32TMP[] = "GO32TMP";
X# endif
X
X/* UnzipUsageLine1[] is also used in vms/cmdline.c: do not make it static */
Xchar Far UnzipUsageLine1[] = "\
XUnZip %s, by Info-ZIP. Portions (c) 1989 by S. H. Smith.\n\
XSend bug reports to authors at zip-...@wkuvx1.wku.edu; see README for details.\
X\n\n";
Xstatic char Far UnzipUsageLine2a[] = "\
XLatest sources and executables are always in ftp.uu.net:/pub/archiving/zip, at\
X\nleast as of date of this release; see \"Where\" for other ftp and non-ftp \
Xsites.\n\n";
X
X#ifndef VMSCLI
Xstatic char Far UnzipUsageLine2[] = "\
XUsage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
X Default action is to extract files in list, except those in xlist, to exdir;\n\
X file[.zip] may be a wildcard. %s\n\n";
X
X#ifdef NO_ZIPINFO
X# define ZIPINFO_MODE_OPTION ""
X static char Far ZipinfoMode[] =
X "(ZipInfo mode is disabled in this version.)";
X#else
X# define ZIPINFO_MODE_OPTION "[-Z] "
X# ifdef VMS
X static char Far ZipinfoMode[] =
X "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).";
X# else
X static char Far ZipinfoMode[] =
X "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
X# endif
X#endif /* ?NO_ZIPINFO */
X
Xstatic char Far UnzipUsageLine3[] = "\
X -p extract files to pipe, no messages -l list files (short format)\n\
X -f freshen existing files, create none -t test compressed archive data\n\
X -u update files, create if necessary -z display archive comment\n\
X -x exclude files which follow (in xlist) -d extract files into exdir\n\n";
X
Xstatic char Far UnzipUsageLine4[] = "\
Xmodifiers: -q quiet mode (-qq => quieter)\n\
X -n never overwrite existing files -a auto-convert any text files\n\
X -o overwrite files WITHOUT prompting -aa treat ALL files as text\n \
X -j junk paths (don't make directories) -v be verbose/print version info\n\
X %c-C%c match filenames case-insensitively %c-L%c make (some) names \
Xlowercase\n %-42s %c-V%c retain VMS version numbers\n%s";
X
Xstatic char Far UnzipUsageLine5[] = "\
XExamples (see unzip.doc for more info):\n\
X unzip data1 -x joe => extract all files except joe from zipfile data1.zip\n\
X %s\n\
X unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
X#endif /* !VMSCLI */
X
X/* process_zipfiles() strings */
X static char Far FilesProcessOK[] = "%d archive%s successfully processed.\n";
X static char Far ArchiveWarning[] =
X "%d archive%s had warnings but no fatal errors.\n";
X static char Far ArchiveFatalError[] = "%d archive%s had fatal errors.\n";
X static char Far FileHadNoZipfileDir[] =
X "%d file%s had no zipfile directory.\n";
X static char Far ZipfileWasDir[] = "1 \"zipfile\" was a directory.\n";
X static char Far ManyZipfilesWereDir[] =
X "%d \"zipfiles\" were directories.\n";
X static char Far NoZipfileFound[] = "No zipfiles found.\n";
X#endif /* ?SFX */
X
X/* do_seekable() strings */
X#ifndef SFX
X#ifdef UNIX
X static char Far CantFindZipfileDirMsg[] =
X "%s: can't find zipfile directory in one of %s or\n\
X %s%s.zip, and can't find %s, period.\n";
X static char Far CantFindEitherZipfile[] =
X "%s: can't find %s, %s.zip or %s, so there.\n";
X#else /* !UNIX */
X static char Far CantFindZipfileDirMsg[] =
X "%s: can't find zipfile directory in %s,\n\
X %sand can't find %s, period.\n";
X static char Far CantFindEitherZipfile[] =
X "%s: can't find either %s or %s, so there.\n";
X#endif /* ?UNIX */
X static char Far MaybeExe[] =
X "note: %s may be a plain executable, not an archive\n";
X static char Far CentDirNotInZipMsg[] = "\n\
X Zipfile is part of a multi-disk archive, and this is not the disk on\n\
X which the central zipfile directory begins.\n";
X#ifdef NO_MULTIPART
X static char Far NoMultiDiskArcSupport[] =
X "\nerror [%s]: zipfile is part of multi-disk archive\n\
X (sorry, not yet supported).\n";
X static char Far MaybePakBug[] = "warning [%s]:\
X zipfile claims to be 2nd disk of a 2-part archive;\n\
X attempting to process anyway. If no further errors occur, this archive\n\
X was probably created by PAK v2.51 or earlier. This bug was reported to\n\
X NoGate in March 1991 and was supposed to have been fixed by mid-1991; as\n\
X of mid-1992 it still hadn't been. (If further errors do occur, archive\n\
X was probably created by PKZIP 2.04c or later; UnZip does not yet support\n\
X multi-part archives.)\n";
X#else
X static char Far MaybePakBug[] = "warning [%s]:\
X zipfile claims to be last disk of a multi-part archive;\n\
X attempting to process anyway, assuming all parts have been concatenated\n\
X together in order. Expect \"errors\" and warnings...true multi-part support\
X\n doesn't exist yet (coming soon).\n";
X#endif
X static char Far ExtraBytesAtStart[] =
X "warning [%s]: extra %ld bytes at beginning or within zipfile\n\
X (attempting to process anyway)\n";
X#endif /* !SFX */
X
Xstatic char Far MissingBytes[] =
X "error [%s]: missing %ld bytes in zipfile\n\
X (attempting to process anyway)\n";
Xstatic char Far NullCentDirOffset[] =
X "error [%s]: NULL central directory offset\n\
X (attempting to process anyway)\n";
Xstatic char Far ZipfileEmpty[] = "warning [%s]: zipfile is empty\n";
Xstatic char Far CentDirStartNotFound[] =
X "error [%s]: start of central directory not found;\n\
X zipfile corrupt.\n%s";
Xstatic char Far ZipfileCommTrunc1[] = "\ncaution: zipfile comment truncated\n";


X
X
X
X
X

X#ifdef MSWIN
X# include "winsetup.c" /* duplicates some code in main() */
X#else /* !MSWIN */
X
X
X
X/******************/
X/* Main program */
X/******************/
X
Xint MAIN(argc, argv) /* return PK-type error code (except under VMS) */
X int argc;
X char *argv[];
X{
X#ifndef NO_ZIPINFO
X char *p;
X#endif
X int error=FALSE;
X#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
X extern void DebugMalloc(void);
X
X
X atexit(DebugMalloc);
X#endif
X
X/*---------------------------------------------------------------------------
X Macintosh initialization code.


X ---------------------------------------------------------------------------*/
X
X#ifdef MACOS

X int a;
X
X for (a = 0; a < 4; ++a)
X rghCursor[a] = GetCursor(a+128);
X giCursor = 0;
X
X aflag=cflag=dflag=fflag=L_flag=jflag=qflag=tflag=uflag=vflag=zflag = 0;
X local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
X/* extd_local_sig[1] = '\0'; */
X error = FALSE;
X
X overwrite_none = overwrite_all = force_flag = 0;


X#endif /* MACOS */
X

X#ifdef MALLOC_WORK
X area.Slide = (uch *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
X area.shrink.Prefix_of = (short *)area.Slide;
X area.shrink.Suffix_of = area.Slide + (sizeof(short)*(HSIZE+1));
X area.shrink.Stack = area.Slide + (sizeof(short) + sizeof(char))*(HSIZE+1);
X#endif
X
X/*---------------------------------------------------------------------------
X Human68K initialization code.


X ---------------------------------------------------------------------------*/
X
X#ifdef __human68k__

X InitTwentyOne();
X#endif
X
X/*---------------------------------------------------------------------------
X Set signal handler for restoring echo, warn of zipfile corruption, etc.
X ---------------------------------------------------------------------------*/
X
X signal(SIGINT, handler);
X#ifdef SIGTERM /* some systems really have no SIGTERM */
X signal(SIGTERM, handler);
X#endif
X#ifdef SIGBUS
X signal(SIGBUS, handler);
X#endif
X#ifdef SIGSEGV
X signal(SIGSEGV, handler);
X#endif
X
X/*---------------------------------------------------------------------------
X First figure out if we're running in UnZip mode or ZipInfo mode, and put
X the appropriate environment-variable options into the queue. Then rip
X through any command-line options lurking about...
X ---------------------------------------------------------------------------*/
X
X#ifdef SFX
X argv0 = argv[0];
X#if defined(OS2) || defined(NT)
X zipfn = GetLoadPath(); /* non-MSC NT puts path into filename[] */
X#else
X zipfn = argv0;
X#endif
X zipinfo_mode = FALSE;
X if ((error = uz_opts(&argc, &argv)) != 0)
X RETURN(error);
X
X#else /* !SFX */
X
X#ifdef MSDOS
X /* extract MKS extended argument list from environment (before envargs!) */
X mksargs(&argc, &argv);
X#endif
X
X#ifdef VMSCLI
X {
X ulg status = vms_unzip_cmdline(&argc, &argv);
X if (!(status & 1))
X return status;
X }
X#endif /* VMSCLI */
X
X#ifndef NO_ZIPINFO
X if ((p = strrchr(argv[0], DIR_END)) == (char *)NULL)
X p = argv[0];
X else
X ++p;
X
X if (STRNICMP(p, "zipinfo", 7) == 0 || STRNICMP(p, "ii", 2) == 0 ||
X (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
X {
X zipinfo_mode = TRUE;
X envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
X LoadFarStringSmall2(EnvZipInfo2));
X error = zi_opts(&argc, &argv);
X } else
X#endif /* NO_ZIPINFO */
X {
X zipinfo_mode = FALSE;
X envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
X LoadFarStringSmall2(EnvUnZip2));
X error = uz_opts(&argc, &argv);
X }
X if ((argc < 0) || error)
X RETURN(error);
X
X#endif /* ?SFX */
X
X/*---------------------------------------------------------------------------
X Now get the zipfile name from the command line and then process any re-
X maining options and file specifications.
X ---------------------------------------------------------------------------*/
X
X#ifdef DOS_NT_OS2
X /* convert MSDOS-style directory separators to Unix-style ones for
X * user's convenience (include zipfile name itself)
X */
X pfnames = argv;
X while (*pfnames != NULL) {
X char *q;
X
X for (q = *pfnames; *q; ++q)
X if (*q == '\\')
X *q = '/';
X ++pfnames;
X }
X#endif /* DOS_NT_OS2 */
X
X#ifndef SFX
X wildzipfn = *argv++;
X#endif
X
X#if (defined(OLD_EXDIR) || (defined(SFX) && !defined(SFX_EXDIR)))
X
X#ifndef SFX
X if (argc > 0) {
X /* -d: "name/" immediately after zipfile name is a stored directory to
X * be extracted--do NOT treat as directory to which to extract files
X */
X if (extract_flag && !dflag) {
X create_dirs = !fflag;
X if ((error = checkdir(*argv, ROOT)) > 2) /* mem, or file in way */
X RETURN(error);
X else if (!error) { /* it IS extract-to dir, so adjust pointers */
X ++argv;
X --argc;
X }
X }
X }
X#endif /* !SFX */
X
X filespecs = argc;
X xfilespecs = 0;
X
X if (argc > 0) {
X char **pp = argv-1;
X
X pfnames = argv;
X while (*++pp)
X if (strcmp(*pp, "-x") == 0) {
X if (pp > argv) {
X *pp = 0; /* terminate pfnames */
X filespecs = pp - pfnames;
X } else {
X pfnames = fnames; /* defaults */
X filespecs = 0;
X }
X pxnames = pp + 1; /* excluded-names ptr starts after -x */
X xfilespecs = argc - filespecs - 1;
X break; /* skip rest of args */
X }
X process_all_files = FALSE;
X } else
X process_all_files = TRUE; /* for speed */
X
X#else /* !(OLD_EXDIR || (SFX && !SFX_EXDIR)) */
X
X filespecs = argc;
X xfilespecs = 0;
X
X if (argc > 0) {
X int in_files=FALSE, in_xfiles=FALSE;
X char **pp = argv-1;
X
X process_all_files = FALSE;
X pfnames = argv;
X while (*++pp) {
X Trace((stderr, "pp - argv = %d\n", pp-argv));
X if (!dflag && strncmp(*pp, "-d", 2) == 0) {
X char *q = *pp;
X int firstarg = (pp == argv);
X
X dflag = TRUE;
X if (in_files) { /* ... zipfile ... -d exdir ... */
X *pp = 0; /* terminate pfnames */
X filespecs = pp - pfnames;
X in_files = FALSE;
X } else if (in_xfiles) {
X *pp = 0; /* terminate pxnames */
X xfilespecs = pp - pxnames;
X /* "... -x xlist -d exdir": nothing left */
X }
X /* first check for "-dpath", then for "-d path" */
X if (q[2])
X q += 2;
X else if (*++pp)
X q = *pp;
X else {
X FPRINTF(stderr, LoadFarString(MustGiveExdir));
X RETURN(PK_PARAM); /* don't extract here by accident */
X }
X if (extract_flag) {
X create_dirs = !fflag;
X if ((error = checkdir(q, ROOT)) > 2)
X RETURN(error); /* out of memory, or file in way */
X } else
X FPRINTF(stderr, LoadFarString(NotExtracting));
X if (firstarg) /* ... zipfile -d exdir ... */
X if (pp[1]) {
X pfnames = pp + 1; /* argv+2 */
X filespecs = argc - (pfnames-argv); /* for now... */
X } else {
X process_all_files = TRUE;
X pfnames = fnames; /* GRR: necessary? */
X filespecs = 0; /* GRR: necessary? */
X break;
X }
X } else if (!in_xfiles) {
X if (strcmp(*pp, "-x") == 0) {
X in_xfiles = TRUE;
X if (pp == argv || (pp == argv+2 && dflag)) {
X pfnames = fnames; /* defaults */
X filespecs = 0;
X } else if (in_files) {
X *pp = 0; /* terminate pfnames */
X filespecs = pp - pfnames; /* adjust count */
X in_files = FALSE;
X }
X pxnames = pp + 1; /* excluded-names ptr starts after -x */
X xfilespecs = argc - (pxnames-argv); /* anything left... */
X } else
X in_files = TRUE;
X }
X }
X } else
X process_all_files = TRUE; /* for speed */
X
X#endif /* ?(OLD_EXDIR || (SFX && !SFX_EXDIR)) */
X
X/*---------------------------------------------------------------------------
X Okey dokey, we have everything we need to get started. Let's roll.
X ---------------------------------------------------------------------------*/
X
X inbuf = (uch *)malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */
X outbuf = (uch *)malloc(OUTBUFSIZ + 1); /* 1 extra for string termin. */
X
X if ((inbuf == (uch *)NULL) || (outbuf == (uch *)NULL)) {
X FPRINTF(stderr, LoadFarString(CantAllocateBuffers));
X RETURN(PK_MEM);
X }
X hold = inbuf + INBUFSIZ; /* to check for boundary-spanning signatures */
X#ifdef SMALL_MEM
X outbuf2 = outbuf+RAWBUFSIZ; /* never changes */
X#endif
X
X RETURN(process_zipfiles()); /* keep passing errors back... */
X
X} /* end main() */


X
X
X
X
X

X/**********************/
X/* Function uz_opts() */
X/**********************/
X
Xint uz_opts(pargc, pargv)
X int *pargc;
X char ***pargv;
X{
X char **argv, *s;
X int argc, c, error=FALSE, negative=0;
X
X
X argc = *pargc;
X argv = *pargv;
X
X while (--argc > 0 && (*++argv)[0] == '-') {
X s = argv[0] + 1;
X while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
X switch (c) {
X case ('-'):
X ++negative;
X break;
X case ('a'):
X if (negative) {
X aflag = MAX(aflag-negative,0);
X negative = 0;
X } else
X ++aflag;
X break;
X case ('b'):
X if (negative)
X negative = 0; /* do nothing: "-b" is default */
X else
X aflag = 0;
X break;
X case ('c'):
X if (negative) {
X cflag = FALSE, negative = 0;
X#ifdef NATIVE
X aflag = 0;
X#endif
X } else {
X cflag = TRUE;
X#ifdef NATIVE
X aflag = 2; /* so you can read it on the screen */
X#endif
X }
X break;
X case ('C'): /* -C: match filenames case-insensitively */
X if (negative)
X C_flag = FALSE, negative = 0;
X else
X C_flag = TRUE;
X break;
X case ('d'): /* arg after zipfn is stored dir, not extract-to */
X#ifdef OLD_EXDIR
X if (negative)
X dflag = FALSE, negative = 0;
X else
X dflag = TRUE;
X#endif
X break;
X case ('e'): /* just ignore -e, -x options (extract) */
X break;
X case ('f'): /* "freshen" (extract only newer files) */
X if (negative)
X fflag = uflag = FALSE, negative = 0;
X else
X fflag = uflag = TRUE;
X break;
X case ('j'): /* junk pathnames/directory structure */
X if (negative)
X jflag = FALSE, negative = 0;
X else
X jflag = TRUE;
X break;
X#ifndef SFX
X case ('l'):
X if (negative) {
X vflag = MAX(vflag-negative,0);
X negative = 0;
X } else
X ++vflag;
X break;
X#endif /* !SFX */
X case ('L'): /* convert (some) filenames to lowercase */
X if (negative)
X L_flag = FALSE, negative = 0;
X else
X L_flag = TRUE;
X break;
X case ('n'): /* don't overwrite any files */
X if (negative)
X overwrite_none = FALSE, negative = 0;
X else
X overwrite_none = TRUE;
X break;
X case ('o'): /* OK to overwrite files without prompting */
X if (negative) {
X overwrite_all = MAX(overwrite_all-negative,0);
X force_flag = MAX(force_flag-negative,0);
X negative = 0;
X } else {
X ++overwrite_all;
X ++force_flag; /* (share -o for now) force to cont. */
X }
X break;
X case ('p'): /* pipes: extract to stdout, no messages */
X if (negative) {
X cflag = FALSE;
X qflag = MAX(qflag-999,0);
X negative = 0;
X } else {
X cflag = TRUE;
X qflag += 999;
X }
X break;
X case ('q'): /* quiet: fewer comments/messages */
X if (negative) {
X qflag = MAX(qflag-negative,0);
X negative = 0;
X } else
X ++qflag;
X break;
X#ifdef DOS_NT_OS2
X case ('s'): /* spaces in filenames: allow by default */
X if (negative)
X sflag = FALSE, negative = 0;
X else
X sflag = TRUE;
X break;
X#endif
X case ('t'):
X if (negative)
X tflag = FALSE, negative = 0;
X else
X tflag = TRUE;
X break;
X case ('u'): /* update (extract only new and newer files) */
X if (negative)
X uflag = FALSE, negative = 0;
X else
X uflag = TRUE;
X break;
X case ('U'): /* obsolete; to be removed in future release */
X if (negative)
X L_flag = TRUE, negative = 0;
X else
X L_flag = FALSE;
X break;
X#ifndef SFX
X case ('v'): /* verbose */
X if (negative) {
X vflag = MAX(vflag-negative,0);
X negative = 0;
X } else if (vflag)
X ++vflag;
X else
X vflag = 2;
X break;
X#endif /* !SFX */
X case ('V'): /* Version (retain VMS/DEC-20 file versions) */
X if (negative)
X V_flag = FALSE, negative = 0;
X else
X V_flag = TRUE;
X break;
X case ('x'): /* extract: default */
X break;
X#ifdef VMS
X case ('X'): /* restore owner/protection info (need privs?) */
X if (negative)
X secinf = FALSE, negative = 0;
X else
X secinf = TRUE;
X break;
X#endif /* VMS */
X case ('z'): /* display only the archive comment */
X if (negative) {
X zflag -= negative;
X negative = 0;
X } else
X ++zflag;
X break;
X#ifdef DOS_NT_OS2
X case ('$'):
X if (negative) {
X volflag = MAX(volflag-negative,0);
X negative = 0;
X } else
X ++volflag;
X break;
X#endif /* DOS_NT_OS2 */
X default:
X error = TRUE;
X break;
X
X } /* end switch */
X } /* end while (not end of argument string) */
X } /* end while (not done with switches) */
X
X/*---------------------------------------------------------------------------
X Check for nonsensical combinations of options.
X ---------------------------------------------------------------------------*/
X
X if ((cflag && tflag) || (cflag && uflag) || (tflag && uflag) ||
X (fflag && overwrite_none)) {
X FPRINTF(stderr, LoadFarString(InvalidOptionsMsg));
X error = TRUE;
X }
X if (aflag > 2)
X aflag = 2;
X if (overwrite_all && overwrite_none) {
X FPRINTF(stderr, LoadFarString(IgnoreOOptionMsg));
X overwrite_all = FALSE;
X }
X
X#ifdef SFX
X if (error)
X#else
X if ((argc-- == 0) || error)
X#endif
X {
X *pargc = argc;
X *pargv = argv;
X#ifndef SFX
X if (vflag >= 2 && argc == -1) {
X if (qflag > 3)
X PRINTF("%d\n", (UZ_MAJORVER*100 + UZ_MINORVER*10 + PATCHLEVEL));
X else {
X char *envptr, *getenv();
X int numopts = 0;
X
X PRINTF(LoadFarString(UnzipUsageLine1),
X LoadFarStringSmall(UnzipVersion));
X PRINTF(LoadFarString(UnzipUsageLine2a));
X version();
X PRINTF(LoadFarString(CompileOptions));
X#ifdef NO_ZIPINFO
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(No_ZipInfo));
X ++numopts;
X#endif
X#ifdef CHECK_EOF
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Check_EOF));
X ++numopts;
X#endif
X#ifdef DOSWILD
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(DosWild));
X ++numopts;
X#endif
X#ifdef VMSWILD
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(VmsWild));
X ++numopts;
X#endif
X#ifdef VMSCLI
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(VmsCLI));
X ++numopts;
X#endif
X#ifdef ASM_INFLATECODES
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(AsmInflateCodes));
X ++numopts;
X#endif
X#ifdef ASM_CRC
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(AsmCRC));
X ++numopts;
X#endif
X#ifdef REGARGS
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(RegArgs));
X ++numopts;
X#endif
X#ifdef OLD_EXDIR
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Old_Exdir));
X ++numopts;
X#endif
X#ifdef CHECK_VERSIONS
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Check_Versions));
X ++numopts;
X#endif
X#ifdef RETURN_CODES
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Return_Codes));
X ++numopts;
X#endif
X#ifdef RETURN_SEVERITY
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Return_Severity));
X ++numopts;
X#endif
X#ifdef DEBUG
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Debug));
X ++numopts;
X#endif
X#ifdef DEBUG_TIME
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(DebugTime));
X ++numopts;
X#endif
X#ifdef CRYPT
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(Decryption));
X ++numopts;
X#endif
X if (numopts == 0)
X PRINTF(LoadFarString(CompileOptFormat),
X LoadFarStringSmall(None));
X
X PRINTF(LoadFarString(EnvOptions));
X envptr = getenv(LoadFarStringSmall(EnvUnZip));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvUnZip),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X envptr = getenv(LoadFarStringSmall(EnvUnZip2));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvUnZip2),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X envptr = getenv(LoadFarStringSmall(EnvZipInfo));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvZipInfo),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvZipInfo2),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X#ifdef __EMX__
X envptr = getenv(LoadFarStringSmall(EnvEMX));
X PRINTF(LoadFarString(EnvOptFormat), LoadFarStringSmall(EnvEMX),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvEMXOPT),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X#endif /* __EMX__ */
X#ifdef __GO32__
X envptr = getenv(LoadFarStringSmall(EnvGO32));
X PRINTF(LoadFarString(EnvOptFormat), LoadFarStringSmall(EnvGO32),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
X PRINTF(LoadFarString(EnvOptFormat),
X LoadFarStringSmall(EnvGO32TMP),
X (envptr == (char *)NULL || *envptr == 0)?
X LoadFarStringSmall2(None) : envptr);
X#endif /* __GO32__ */
X }
X return 0;
X } else
X#endif /* !SFX */
X return usage(error);
X }
X
X if (cflag || tflag || vflag)
X extract_flag = FALSE;
X else
X extract_flag = TRUE;
X
X *pargc = argc;
X *pargv = argv;
X return 0;
X
X} /* end function uz_opts() */


X
X
X
X
X

X/********************/
X/* Function usage() */
X/********************/
X
X#ifdef SFX
X# ifdef VMS
X# define LOCAL "X. Quote uppercase options"
X# else
X# ifdef DOS_NT_OS2
X# define LOCAL "s$"
X# else
X# ifdef AMIGA
X# define LOCAL "$"
X# else
X# define LOCAL ""
X# endif
X# endif /* ?DOS_NT_OS2 */
X# endif /* ?VMS */
X
Xint usage(error) /* return PK-type error code */
X int error;
X{
X FILE *usagefp;
X
X if (error)
X usagefp = (FILE *)stderr;
X else
X usagefp = (FILE *)stdout;
X
X FPRINTF(usagefp, LoadFarString(UnzipSFXUsage),
X LoadFarStringSmall(UnzipVersion), LOCAL);
X#ifdef BETA
X FPRINTF(usagefp, LoadFarString(BetaVersion), "\n", "SFX");
X#endif
X
X if (error)
X return PK_PARAM;
X else
X return PK_COOL; /* just wanted usage screen: no error */
X
X} /* end function usage() */


X
X
X
X
X

X#else /* !SFX */
X#ifndef VMSCLI
X
Xint usage(error) /* return PK-type error code */
X int error;
X{
X#ifdef VMS
X# define QUOT '\"'
X# define QUOTS "\""
X#else
X# define QUOT ' '
X# define QUOTS ""
X#endif
X
X FILE *usagefp;
X
X
X/*---------------------------------------------------------------------------
X If user requested usage, send it to stdout; else send to stderr.
X ---------------------------------------------------------------------------*/
X
X if (error)
X usagefp = (FILE *)stderr;
X else
X usagefp = (FILE *)stdout;
X
X/*---------------------------------------------------------------------------
X Print either ZipInfo usage or UnZip usage, depending on incantation.
X (Strings must be no longer than 512 bytes for Turbo C, apparently.)
X ---------------------------------------------------------------------------*/
X
X if (zipinfo_mode) {
X
X#ifndef NO_ZIPINFO
X
X FPRINTF(usagefp, LoadFarString(ZipInfoUsageLine1),
X LoadFarStringSmall(ZipinfoVersion),
X LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS);
X FPRINTF(usagefp, LoadFarString(ZipInfoUsageLine2));
X FPRINTF(usagefp, LoadFarString(ZipInfoUsageLine3), QUOT,QUOT);
X#ifdef VMS
X FPRINTF(usagefp, "\nRemember that non-lowercase filespecs must be\
X quoted in VMS (e.g., \"Makefile\").\n");
X#endif
X
X#endif /* !NO_ZIPINFO */
X
X } else { /* UnZip mode */
X
X FPRINTF(usagefp, LoadFarString(UnzipUsageLine1),
X LoadFarStringSmall(UnzipVersion));
X#ifdef BETA
X FPRINTF(usagefp, LoadFarString(BetaVersion), "", "");
X#endif
X FPRINTF(usagefp, LoadFarString(UnzipUsageLine2), ZIPINFO_MODE_OPTION,
X LoadFarStringSmall(ZipinfoMode));
X
X FPRINTF(usagefp, LoadFarString(UnzipUsageLine3));
X
X FPRINTF(usagefp, LoadFarString(UnzipUsageLine4), QUOT,QUOT, QUOT,QUOT,
X LoadFarStringSmall(loc_str), QUOT,QUOT,
X LoadFarStringSmall2(loc2str));
X
X /* This is extra work for SMALL_MEM, but it will work since
X * LoadFarStringSmall2 uses the same buffer. Remember, this
X * is a hack. */
X FPRINTF(usagefp, LoadFarString(UnzipUsageLine5),
X LoadFarStringSmall(Example1),
X LoadFarStringSmall2(Example2),
X LoadFarStringSmall2(Example2));
X
X }
X
X if (error)
X return PK_PARAM;
X else
X return PK_COOL; /* just wanted usage screen: no error */
X
X} /* end function usage() */
X
X#endif /* !VMSCLI */
X#endif /* ?SFX */
X#endif /* ?MSWIN */
X
X
X
X
X/*******************************/
X/* Function process_zipfiles() */
X/*******************************/
X
Xint process_zipfiles() /* return PK-type error code */
X{
X#ifndef SFX
X char *lastzipfn = (char *)NULL;
X int NumWinFiles, NumLoseFiles, NumWarnFiles;
X int NumMissDirs, NumMissFiles;
X#endif
X int error=0, error_in_archive=0;
X
X
X/*---------------------------------------------------------------------------
X Start by constructing the various PK signature strings.
X ---------------------------------------------------------------------------*/
X
X local_hdr_sig[0] /* = extd_local_sig[0] */ = '\120'; /* ASCII 'P', */
X central_hdr_sig[0] = end_central_sig[0] = '\120'; /* not EBCDIC */
X
X strcpy(local_hdr_sig+1, LOCAL_HDR_SIG);
X strcpy(central_hdr_sig+1, CENTRAL_HDR_SIG);
X strcpy(end_central_sig+1, END_CENTRAL_SIG);
X/* strcpy(extd_local_sig+1, EXTD_LOCAL_SIG); still to be used in multi? */
X
X/*---------------------------------------------------------------------------
X Match (possible) wildcard zipfile specification with existing files and
X attempt to process each. If no hits, try again after appending ".zip"
X suffix. If still no luck, give up.
X ---------------------------------------------------------------------------*/
X
X#ifdef SFX
X if ((error = do_seekable(0)) == PK_NOZIP) {
X#ifdef EXE_EXTENSION
X int len=strlen(argv0);
X
X /* append .exe if appropriate; also .sfx? */
X if ((zipfn = (char *)malloc(len+5)) != (char *)NULL) {
X strcpy(zipfn, argv0);
X strcpy(zipfn+len, EXE_EXTENSION);
X error = do_seekable(0);
X free(zipfn);
X zipfn = argv0; /* for "can't find myself" message only */
X }
X#endif /* EXE_EXTENSION */
X#ifdef NT
X zipfn = argv0; /* for "can't find myself" message only */
X#endif
X }
X if (error) {
X if (error == IZ_DIR)
X error_in_archive = PK_NOZIP;
X else
X error_in_archive = error;
X if (error == PK_NOZIP)
X FPRINTF(stderr, LoadFarString(CantFindMyself), zipfn);
X }
X
X#else /* !SFX */
X NumWinFiles = NumLoseFiles = NumWarnFiles = 0;
X NumMissDirs = NumMissFiles = 0;
X
X while ((zipfn = do_wild(wildzipfn)) != (char *)NULL) {
X Trace((stderr, "do_wild( %s ) returns %s\n", wildzipfn, zipfn));
X
X lastzipfn = zipfn;
X
X /* print a blank line between the output of different zipfiles */
X if (!qflag && error != PK_NOZIP && error != IZ_DIR &&
X (NumWinFiles+NumLoseFiles+NumWarnFiles+NumMissFiles) > 0)
X PRINTF("\n");
X FFLUSH(stdout);
X
X if ((error = do_seekable(0)) == PK_WARN)
X ++NumWarnFiles;
X else if (error == IZ_DIR)
X ++NumMissDirs;
X else if (error == PK_NOZIP)
X ++NumMissFiles;
X else if (error)
X ++NumLoseFiles;
X else
X ++NumWinFiles;
X
X if (error != IZ_DIR && error > error_in_archive)
X error_in_archive = error;
X Trace((stderr, "do_seekable(0) returns %d\n", error));
X
X } /* end while-loop (wildcard zipfiles) */
X
X if ((NumWinFiles + NumWarnFiles + NumLoseFiles) == 0 &&
X (NumMissDirs + NumMissFiles) == 1 && lastzipfn != (char *)NULL)
X {
X char *p = lastzipfn + strlen(lastzipfn);
X
X NumMissDirs = NumMissFiles = 0;
X if (error_in_archive == PK_NOZIP)
X error_in_archive = PK_COOL;
X zipfn = lastzipfn;
X strcpy(p, ".zip");
X
X#ifdef UNIX
X if ((error = do_seekable(0)) == PK_NOZIP || error == IZ_DIR) {
X if (error == IZ_DIR)
X ++NumMissDirs;
X strcpy(p, ".ZIP");
X error = do_seekable(1);
X }
X#else
X error = do_seekable(1);
X#endif
X if (error == PK_WARN)
X ++NumWarnFiles;
X else if (error == IZ_DIR)
X ++NumMissDirs;
X else if (error == PK_NOZIP)
X /* if increment again => bug: "1 file had no zipfile directory." */
X /* ++NumMissFiles */ ;
X else if (error)
X ++NumLoseFiles;
X else
X ++NumWinFiles;
X
X if (error > error_in_archive)
X error_in_archive = error;
X Trace((stderr, "do_seekable(1) returns %d\n", error));
X }
X#endif /* ?SFX */
X
X FFLUSH(stdout);
X FFLUSH(stderr);
X
X/*---------------------------------------------------------------------------
X Print summary of all zipfiles, assuming zipfile spec was a wildcard (no
X need for a summary if just one zipfile).
X ---------------------------------------------------------------------------*/
X
X#ifndef SFX
X if (iswild(wildzipfn)) {
X if (NumMissFiles + NumLoseFiles + NumWarnFiles > 0 || NumWinFiles != 1)
X FPRINTF(stderr, "\n");
X if ((NumWinFiles > 1) || (NumWinFiles == 1 &&
X NumMissDirs + NumMissFiles + NumLoseFiles + NumWarnFiles > 0))
X FPRINTF(stderr, LoadFarString(FilesProcessOK),
X NumWinFiles, (NumWinFiles == 1)? " was" : "s were");
X if (NumWarnFiles > 0)
X FPRINTF(stderr, LoadFarString(ArchiveWarning),
X NumWarnFiles, (NumWarnFiles == 1)? "" : "s");
X if (NumLoseFiles > 0)
X FPRINTF(stderr, LoadFarString(ArchiveFatalError),
X NumLoseFiles, (NumLoseFiles == 1)? "" : "s");
X if (NumMissFiles > 0)
X FPRINTF(stderr, LoadFarString(FileHadNoZipfileDir),
X NumMissFiles, (NumMissFiles == 1)? "" : "s");
X if (NumMissDirs == 1)
X FPRINTF(stderr, LoadFarString(ZipfileWasDir));
X else if (NumMissDirs > 0)
X FPRINTF(stderr, LoadFarString(ManyZipfilesWereDir), NumMissDirs);
X if (NumWinFiles + NumLoseFiles + NumWarnFiles == 0)
X FPRINTF(stderr, LoadFarString(NoZipfileFound));
X }
X#endif /* !SFX */
X
X /* free allocated memory */
X inflate_free();
X checkdir((char *)NULL, END);
X#ifndef SMALL_MEM
X if (outbuf2)
X free(outbuf2); /* malloc'd ONLY if unshrink and -a */
X#endif
X free(outbuf);
X free(inbuf);
X
X return error_in_archive;
X
X} /* end function process_zipfiles() */


X
X
X
X
X

X/**************************/
X/* Function do_seekable() */
X/**************************/
X
Xint do_seekable(lastchance) /* return PK-type error code */
X int lastchance;
X{
X#ifndef SFX
X static int no_ecrec = FALSE;
X int maybe_exe=FALSE;
X#endif
X int error=0, error_in_archive;
X
X
X/*---------------------------------------------------------------------------
X Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
X which would corrupt the bit streams.
X ---------------------------------------------------------------------------*/
X
X if (SSTAT(zipfn, &statbuf) || (error = S_ISDIR(statbuf.st_mode)) != 0) {
X#ifndef SFX
X if (lastchance)
X if (no_ecrec)
X FPRINTF(stderr, LoadFarString(CantFindZipfileDirMsg),
X zipinfo_mode? "zipinfo" : "unzip",
X wildzipfn, zipinfo_mode? " " : "",
X#ifdef UNIX
X wildzipfn,
X#endif
X zipfn);
X else
X FPRINTF(stderr,
X LoadFarString(CantFindEitherZipfile),
X zipinfo_mode? "zipinfo" : "unzip", wildzipfn,
X#ifdef UNIX
X wildzipfn,
X#endif
X zipfn);
X#endif /* !SFX */
X return error? IZ_DIR : PK_NOZIP;
X }
X ziplen = statbuf.st_size;
X
X#ifndef SFX
X#if defined(UNIX) || defined(DOS_NT_OS2)
X if (statbuf.st_mode & S_IEXEC) /* no extension on Unix exec's: might */
X maybe_exe = TRUE; /* find unzip, not unzip.zip; etc. */
X#endif
X#endif /* !SFX */
X
X#ifdef VMS
X if (check_format()) /* check for variable-length format */
X return PK_ERR;
X#endif
X
X if (open_input_file()) /* this should never happen, given */
X return PK_NOZIP; /* the stat() test above, but... */
X
X/*---------------------------------------------------------------------------
X Find and process the end-of-central-directory header. UnZip need only
X check last 65557 bytes of zipfile: comment may be up to 65535, end-of-
X central-directory record is 18 bytes, and signature itself is 4 bytes;
X add some to allow for appended garbage. Since ZipInfo is often used as
X a debugging tool, search the whole zipfile if zipinfo_mode is true.
X ---------------------------------------------------------------------------*/
X
X cur_zipfile_bufstart = 0;
X inptr = inbuf;
X
X if (!qflag && !zipinfo_mode)
X PRINTF("Archive: %s\n", zipfn);
X
X if ((
X#ifndef NO_ZIPINFO
X zipinfo_mode &&
X ((error_in_archive = find_ecrec(ziplen)) != 0 ||
X (error_in_archive = zi_end_central()) > PK_WARN))
X || (!zipinfo_mode &&
X#endif
X ((error_in_archive = find_ecrec(MIN(ziplen,66000L))) != 0 ||
X (error_in_archive = uz_end_central()) > PK_WARN)))
X {
X close(zipfd);
X#ifdef SFX
X ++lastchance; /* avoid picky compiler warnings */
X return error_in_archive;
X#else
X if (maybe_exe)
X FPRINTF(stderr, LoadFarString(MaybeExe), zipfn);
X if (lastchance)
X return error_in_archive;
X else {
X no_ecrec = TRUE; /* assume we found wrong file: e.g., */
X return PK_NOZIP; /* unzip instead of unzip.zip */
X }
X#endif /* ?SFX */
X }
X
X if ((zflag > 0) && !zipinfo_mode) { /* in unzip, zflag = comment ONLY */
X close(zipfd);
X return error_in_archive;
X }
X
X/*---------------------------------------------------------------------------
X Test the end-of-central-directory info for incompatibilities (multi-disk
X archives) or inconsistencies (missing or extra bytes in zipfile).
X ---------------------------------------------------------------------------*/
X
X#ifdef NO_MULTIPART
X error = !zipinfo_mode && (ecrec.number_this_disk == 1) &&
X (ecrec.num_disk_with_start_central_dir == 1);
X#else
X error = !zipinfo_mode && (ecrec.number_this_disk != 0);
X#endif
X
X#ifndef SFX
X if (zipinfo_mode &&
X ecrec.number_this_disk != ecrec.num_disk_with_start_central_dir)
X {
X FPRINTF(stderr, LoadFarString(CentDirNotInZipMsg));
X error_in_archive = PK_FIND;
X#ifdef NO_MULTIPART /* concatenation of multiple parts works in some cases */
X } else if (!zipinfo_mode && !error && ecrec.number_this_disk != 0) {
X FPRINTF(stderr, LoadFarString(NoMultiDiskArcSupport), zipfn);
X error_in_archive = PK_FIND;
X#endif
X } else { /* this is a (relatively) normal zipfile: process normally */
X if (error) {
X FPRINTF(stderr, LoadFarString(MaybePakBug), zipfn);
X error_in_archive = PK_WARN;
X }
X#endif
X if ((extra_bytes = real_ecrec_offset-expect_ecrec_offset) < (LONGINT)0)
X {
X FPRINTF(stderr, LoadFarString(MissingBytes), zipfn,
X (long)(-extra_bytes));
X error_in_archive = PK_ERR;
X } else if (extra_bytes > 0) {
X if ((ecrec.offset_start_central_directory == 0) &&
X (ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */
X {
X FPRINTF(stderr, LoadFarString(NullCentDirOffset), zipfn);
X ecrec.offset_start_central_directory = extra_bytes;
X extra_bytes = 0;
X error_in_archive = PK_ERR;
X }
X#ifndef SFX
X else {
X FPRINTF(stderr, LoadFarString(ExtraBytesAtStart), zipfn,
X (long)extra_bytes);
X error_in_archive = PK_WARN;
X }
X#endif
X }
X
X /*-----------------------------------------------------------------------
X Check for empty zipfile and exit now if so.
X -----------------------------------------------------------------------*/
X
X if (expect_ecrec_offset == 0L && ecrec.size_central_directory == 0) {
X if (zipinfo_mode)
X PRINTF("%sEmpty zipfile.\n", lflag>9 ? "\n " : "");
X else
X FPRINTF(stderr, LoadFarString(ZipfileEmpty), zipfn);
X close(zipfd);
X return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
X }
X
X /*-----------------------------------------------------------------------
X Compensate for missing or extra bytes, and seek to where the start
X of central directory should be. If header not found, uncompensate
X and try again (necessary for at least some Atari archives created
X with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
X -----------------------------------------------------------------------*/
X
X LSEEK( ecrec.offset_start_central_directory )
X#ifdef OLD_SEEK_TEST
X if (readbuf(sig, 4) == 0) {
X close(zipfd);
X return PK_ERR; /* file may be locked, or possibly disk error(?) */
X }
X if (strncmp(sig, central_hdr_sig, 4))
X#else
X if ((readbuf(sig, 4) == 0) || strncmp(sig, central_hdr_sig, 4))
X#endif
X {
X long tmp = extra_bytes;
X
X extra_bytes = 0;
X LSEEK( ecrec.offset_start_central_directory )
X if ((readbuf(sig, 4) == 0) || strncmp(sig, central_hdr_sig, 4)) {
X FPRINTF(stderr, LoadFarString(CentDirStartNotFound), zipfn,
X LoadFarStringSmall(ReportMsg));
X close(zipfd);
X return PK_BADERR;
X }
X FPRINTF(stderr, LoadFarString(CentDirTooLong), zipfn, -tmp);
X error_in_archive = PK_ERR;
X }
X
X /*-----------------------------------------------------------------------
X Seek to the start of the central directory one last time, since we
X have just read the first entry's signature bytes; then list, extract
X or test member files as instructed, and close the zipfile.
X -----------------------------------------------------------------------*/
X
X Trace((stderr, "about to extract/list files (error = %d)\n",
X error_in_archive));
X
X LSEEK( ecrec.offset_start_central_directory )
X
X#ifndef NO_ZIPINFO
X if (zipinfo_mode) {
X error = zipinfo(); /* ZIPINFO 'EM */
X if (lflag > 9)
X PRINTF("\n");
X } else
X#endif
X#ifndef SFX
X if (vflag && !tflag && !cflag)
X error = list_files(); /* LIST 'EM */
X else
X#endif
X error = extract_or_test_files(); /* EXTRACT OR TEST 'EM */
X
X Trace((stderr, "done with extract/list files (error = %d)\n", error));
X
X if (error > error_in_archive) /* don't overwrite stronger error */
X error_in_archive = error; /* with (for example) a warning */
X#ifndef SFX
X }
X#endif
X
X close(zipfd);
X return error_in_archive;
X
X} /* end function do_seekable() */


X
X
X
X
X

X/*****************************/
X/* Function uz_end_central() */
X/*****************************/
X
Xint uz_end_central() /* return PK-type error code */
X{
X int error = PK_COOL;
X
X
X/*---------------------------------------------------------------------------
X Get the zipfile comment (up to 64KB long), if any, and print it out.
X Then position the file pointer to the beginning of the central directory
X and fill buffer.
X ---------------------------------------------------------------------------*/
X
X#ifdef MSWIN
X cchComment = ecrec.zipfile_comment_length; /* save for comment button */
X if (ecrec.zipfile_comment_length && (zflag > 0))
X#else
X if (ecrec.zipfile_comment_length && (zflag > 0 || (zflag == 0 && !qflag)))
X#endif
X {
X#if 0
X#ifndef MSWIN
X if (zflag == 0) (add "&& single_zipfile" perhaps; unnecessary with
X PRINTF("[%s] comment:\n", zipfn); multiple zipfiles: "Archive:...")
X#endif /* !MSWIN */
X#endif /* 0 */
X if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
X FPRINTF(stderr, LoadFarString(ZipfileCommTrunc1));
X error = PK_WARN;
X }
X }
X return error;
X
X} /* end function uz_end_central() */


X
X
X
X
X

X/************************************/
X/* Function process_cdir_file_hdr() */
X/************************************/
X
Xint process_cdir_file_hdr() /* return PK-type error code */
X{
X int error;
X
X
X/*---------------------------------------------------------------------------
X Get central directory info, save host and method numbers, and set flag
X for lowercase conversion of filename, depending on the OS from which the
X file is coming.
X ---------------------------------------------------------------------------*/
X
X if ((error = get_cdir_ent()) != 0)
X return error;
X
X pInfo->hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
X/* extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
X
X pInfo->lcflag = 0;
X if (L_flag) /* user specified case-conversion */
X switch (pInfo->hostnum) {
X case FS_FAT_: /* PKZIP and zip -k store in uppercase */
X case ATARI_: /* MS-DOS filesystem */
X case CPM_: /* like MS-DOS, right? */
X case VM_CMS_: /* all caps? */
X case TOPS20_:
X case VMS_: /* our Zip uses lowercase, but ASi's doesn't */
X /* case Z_SYSTEM_: ? */
X /* case QDOS_: ? */
X pInfo->lcflag = 1; /* convert filename to lowercase */
X break;
X
X default: /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, */
X break; /* (Z_SYSTEM_): no conversion */
X }
X
X /* do Amigas (AMIGA_) also have volume labels? */
X if (IS_VOLID(crec.external_file_attributes) &&
X (pInfo->hostnum == FS_FAT_ || pInfo->hostnum == FS_HPFS_ ||
X pInfo->hostnum == FS_NTFS_ || pInfo->hostnum == ATARI_))
X {
X pInfo->vollabel = TRUE;
X pInfo->lcflag = 0; /* preserve case of volume labels */
X } else
X pInfo->vollabel = FALSE;
X
X return PK_COOL;
X
X} /* end function process_cdir_file_hdr() */


X
X
X
X
X

X/*************************************/
X/* Function process_local_file_hdr() */
X/*************************************/
X
Xint process_local_file_hdr() /* return PK-type error code */
X{
X local_byte_hdr byterec;
X
X
X/*---------------------------------------------------------------------------
X Read the next local file header and do any necessary machine-type con-
X versions (byte ordering, structure padding compensation--do so by copy-
X ing the data from the array into which it was read (byterec) to the
X usable struct (lrec)).
X ---------------------------------------------------------------------------*/
X
X if (readbuf((char *)byterec, LREC_SIZE) == 0)
X return PK_EOF;
X
X lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
X lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
X
X lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
X lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
X lrec.last_mod_file_time = makeword(&byterec[L_LAST_MOD_FILE_TIME]);
X lrec.last_mod_file_date = makeword(&byterec[L_LAST_MOD_FILE_DATE]);
X lrec.crc32 = makelong(&byterec[L_CRC32]);
X lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]);
X lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
X lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
X lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
X
X csize = (long) lrec.csize;
X ucsize = (long) lrec.ucsize;
X
X if ((lrec.general_purpose_bit_flag & 8) != 0) {
X /* can't trust local header, use central directory: */
X lrec.crc32 = pInfo->crc;
X csize = (long)(lrec.csize = pInfo->compr_size);
X }
X
X return PK_COOL;
X
X} /* end function process_local_file_hdr() */
END_OF_FILE
if test 66790 -ne `wc -c <'unzip-5.12/unzip.c'`; then
echo shar: \"'unzip-5.12/unzip.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unzip.c'
fi
echo shar: End of archive 2 \(of 20\).
cp /dev/null ark2isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:14:25 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 68
Archive-name: unzip/part03

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/version.h unzip-5.12/vms/vms.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:36 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 3 (of 20)."'
if test -f 'unzip-5.12/version.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/version.h'\"
else
echo shar: Extracting \"'unzip-5.12/version.h'\" \(855 characters\)
sed "s/^X//" >'unzip-5.12/version.h' <<'END_OF_FILE'
X/*
X version.h (for UnZip) by Info-ZIP.
X
X This header file is not copyrighted and may be distributed without
X restriction. (That's a little geek humor, heh heh.)
X */
X
X#ifndef __version_h /* don't include more than once */
X#define __version_h
X
X#ifdef BETA
X# define BETALEVEL "e"
X# define UZ_VERSION "5.12e BETA of 25 Aug 94" /* internal beta level */
X# define ZI_VERSION "2.02e BETA of 25 Aug 94"
X# define D2_VERSION "0.0 BETA of xx Xxx 94"
X#else
X# define BETALEVEL ""
X# define UZ_VERSION "5.12 of 28 August 1994" /* official release version */
X# define ZI_VERSION "2.02 of 28 August 1994"
X# define D2_VERSION "0.0 of x Xxxxxx 1994" /* (DLL for OS/2) */
X# define RELEASE
X#endif
X
X#define UZ_MAJORVER 5
X#define UZ_MINORVER 1
X
X#define ZI_MAJORVER 2
X#define ZI_MINORVER 0
X
X#define PATCHLEVEL 2
X
X#endif /* !__version_h */
END_OF_FILE
if test 855 -ne `wc -c <'unzip-5.12/version.h'`; then
echo shar: \"'unzip-5.12/version.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/version.h'
fi
if test -f 'unzip-5.12/vms/vms.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/vms.c'\"
else
echo shar: Extracting \"'unzip-5.12/vms/vms.c'\" \(66172 characters\)
sed "s/^X//" >'unzip-5.12/vms/vms.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X vms.c Igor Mandrichenko and others
X
X This file contains routines to extract VMS file attributes from a zipfile
X extra field and create a file with these attributes. The code was almost
X entirely written by Igor, with a couple of routines by CN.
X
X ---------------------------------------------------------------------------
X
X Copyright (C) 1992-93 Igor Mandrichenko.
X Permission is granted to any individual or institution to use, copy,
X or redistribute this software so long as all of the original files
X are included unmodified and that this copyright notice is retained.
X
X Revision history:
X
X 1.x [moved to History.510 for brevity]
X 2.0 Mandrichenko 7-apr-1993
X Implement PKWARE style VMS file attributes
X 2.0-1 Mandrichenko 10-apr-1993
X ACL handling code added.
X 2.1 Mandrichenko 24-aug-1993
X Get both PKWARE and new INFO-ZIP signatures as equivalent
X Use vmsmunch.h instead of fatdef.h
X 2.2 Cave Newt 3-oct-1993
X Merged GRR 5.1e changes with latest Igor version: open_outfile,
X close_outfile, check_for_newer, UpdateCRC, flush, no ZIPINFO,
X ctype.h, pInfo->textmode, etc. Also merged new do_wild/mapname/
X checkdir routines from Igor and moved VMSmunch.h into vms.h.
X 2.2-1 Mandrichenko 14-dec-1993
X Bug fixes in mapname/checkdir stuff.
X _flush_stream() rewritten to fix some bugs.
X 2.2-2 Goathunter 3 Jan 94
X Fixes for Alpha-VMS.
X 2.2-3 Cave Newt 11 Jan 94
X Disabled version-check by default; enable with CHECK_VERSIONS.
X Installed Igor's ctrl-Z patch.
X 2.2-4 Mandrichenko 18 Jan 94
X Fixed auto-appending of ".zip" and inability to create second
X level of directory structure.
X 2.2-5 Cave Newt, Mike Freeman 28 Jan 94
X Changed close_outfile() to return void for compatibility;
X fixed declaration of second parameter to flush() (ulg size);
X changed str[n]icmp() to STR[N]ICMP().
X 2.2-6 Christian Spieler 9 Apr 94
X Numerous bug fixes/improvements.
X 2.2-7 Cave Newt 11 Apr 94
X Fixed version-number/semicolon bug.
X 2.3 Cave Newt 21 Jun 94
X Added prototype version() routine.
X 2.3-1 Cave Newt 1 Jul 94
X *Really* fixed version-number/semicolon bug.
X 2.3-2 Rodney Brown 10 Jul 94
X Added VMS status/severity level (define RETURN_SEVERITY)
X 2.3-3 Charles Bailey 10 Aug 94
X Fixed severity levels.
X 2.3-4 CN, CS, IM, RB 16 Aug 94
X Further severity tweaks; do_wild() bugfix (CS)
X 2.3-5 CS, CN, IM, GH 18 Aug 94
X Further do_wild() modifications and fixes.
X 2.3-6 Christian Spieler 23 Aug 94
X Added lots of typecasts and fixed some initializations for DEC C.
X
X ---------------------------------------------------------------------------*/
X
X#ifdef VMS /* VMS only ! */
X
X#include "unzip.h"
X#include "vms.h" /* now includes VMSmunch.h */
X
X#define BUFS512 8192*2 /* Must be a multiple of 512 */
X
X#define OK(s) ((s)&1) /* VMS success or warning status */
X#define STRICMP(s1,s2) STRNICMP(s1,s2,2147483647)
X
X/*
X* Local static storage
X*/
Xstatic struct FAB fileblk;
Xstatic struct XABDAT dattim;
Xstatic struct XABRDT rdt;
Xstatic struct RAB rab;
Xstatic struct NAM nam;
X
Xstatic struct FAB *outfab = 0;
Xstatic struct RAB *outrab = 0;
Xstatic struct XABFHC *xabfhc = 0;
Xstatic struct XABDAT *xabdat = 0;
Xstatic struct XABRDT *xabrdt = 0;
Xstatic struct XABPRO *xabpro = 0;
Xstatic struct XABKEY *xabkey = 0;
Xstatic struct XABALL *xaball = 0;
Xstruct XAB *first_xab = 0L, *last_xab = 0L;
X
Xstatic char query = 0;
Xstatic int text_output = 0,
X raw_input,
X hostnum;
X
Xstatic uch rfm;
X
Xstatic uch locbuf[BUFS512];
Xstatic int loccnt = 0;
Xstatic uch *locptr;
Xstatic char got_eol = 0;
X
Xstatic int _flush_blocks(),
X _flush_stream(),
X _flush_varlen(),
X _flush_qio(),
X _close_qio(),
X _close_rms(),
X WriteRecord(),
X WriteBuffer(),
X find_eol();
X
Xstatic int (*_flush_routine)(),
X (*_close_routine)();
X
Xstatic int get_vms_version();
Xstatic int replace();
Xstatic uch *extract_block();
Xstatic void init_buf_ring();
Xstatic void decompress_bits();
Xstatic void UpdateCRC();
Xstatic void message();
Xstatic void free_up();
X
Xstruct bufdsc
X{
X struct bufdsc *next;
X uch *buf;
X int bufcnt;
X};
X
Xstatic struct bufdsc b1, b2, *curbuf;
Xstatic uch buf1[BUFS512];
X
Xint check_format()
X{
X int rtype;
X struct FAB fab;
X
X fab = cc$rms_fab;
X fab.fab$l_fna = zipfn;
X fab.fab$b_fns = strlen(zipfn);
X
X sys$open(&fab);
X rtype = fab.fab$b_rfm;
X sys$close(&fab);
X
X if (rtype == FAB$C_VAR || rtype == FAB$C_VFC)
X {
X fprintf(stderr,
X "\n Error: zipfile is in variable-length record format. Please\n\
X run \"bilf l %s\" to convert the zipfile to stream-LF\n\
X record format. (bilf.c and make_bilf.com are included in the\n\
X VMS UnZip source distribution.)\n\n", zipfn);
X return PK_ERR;


X }
X
X return PK_COOL;
X}
X

X
X
X#define PRINTABLE_FORMAT(x) ( (x) == FAB$C_VAR \
X || (x) == FAB$C_STMLF \
X || (x) == FAB$C_STMCR \
X || (x) == FAB$C_STM )
X
X/* VMS extra field types */
X#define VAT_NONE 0
X#define VAT_IZ 1 /* Old INFO-ZIP format */
X#define VAT_PK 2 /* PKWARE format */
X
Xstatic int vet;
X
Xstatic int create_default_output(),
X create_rms_output(),
X create_qio_output();
X
X/*
X * open_outfile() assignments:
X *
X * VMS attributes ? create_xxx _flush_xxx
X * ---------------- ---------- ----------
X * not found 'default' text mode ?
X * yes -> 'stream'
X * no -> 'block'
X *
X * yes, in IZ format 'rms' text mode ?
X * yes -> switch(fab.rfm)
X * VAR -> 'varlen'
X * STM* -> 'stream'
X * default -> 'block'
X * no -> 'block'
X *
X * yes, in PK format 'qio' 'qio'
X *
X * "text mode" == pInfo -> text || cflag
X */
X
Xint open_outfile()
X{
X switch(vet = find_vms_attrs())
X { case VAT_NONE:
X default:
X return create_default_output();
X case VAT_IZ:
X return create_rms_output();
X case VAT_PK:
X return create_qio_output();
X }
X}
X
Xstatic void init_buf_ring()
X{
X locptr = &locbuf[0];
X loccnt = 0;
X
X b1.buf = &locbuf[0];
X b1.bufcnt = 0;
X b1.next = &b2;
X b2.buf = &buf1[0];
X b2.bufcnt = 0;
X b2.next = &b1;
X curbuf = &b1;
X}
X
X
X
Xstatic int create_default_output()
X{
X int ierr, yr, mo, dy, hh, mm, ss;
X char timbuf[24]; /* length = first entry in "stupid" + 1 */
X int attr_given; /* =1 if VMS attributes are present in
X * extra_field */
X
X rab = cc$rms_rab; /* fill FAB & RAB with default values */
X fileblk = cc$rms_fab;
X
X text_output = pInfo->textmode || cflag; /* extract the file in text
X * (variable-length) format */
X hostnum = pInfo -> hostnum;
X
X outfab = &fileblk;
X outfab->fab$l_xab = 0L;
X rfm = FAB$C_STMLF; /* Default, stream-LF format from VMS
X * or UNIX */
X if (text_output)
X { /* Default format for output text file */
X
X outfab->fab$b_rfm = FAB$C_VAR; /* variable length records */
X outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */
X }
X else
X { /* Default format for output binary file */
X
X outfab->fab$b_rfm = FAB$C_STMLF; /* stream-LF record format */
X outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */
X }
X
X if (!cflag) /* Redirect output */
X outfab->fab$l_fna = filename;
X else
X outfab->fab$l_fna = "sys$output:";
X
X outfab->fab$b_fns = strlen(outfab->fab$l_fna);
X
X {
X static char *month[] =
X {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
X "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
X
X /* fixed-length string descriptor: */
X struct dsc$descriptor stupid =
X {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};
X
X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
X mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
X dy = (lrec.last_mod_file_date & 0x1f);
X hh = (lrec.last_mod_file_time >> 11) & 0x1f;
X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
X ss = (lrec.last_mod_file_time & 0x1f) * 2;
X
X dattim = cc$rms_xabdat; /* fill XABs with default values */
X rdt = cc$rms_xabrdt;
X sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr,
X hh, mm, ss);
X sys$bintim(&stupid, &dattim.xab$q_cdt);
X memcpy(&rdt.xab$q_rdt, &dattim.xab$q_cdt, sizeof(rdt.xab$q_rdt));
X
X dattim.xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) &dattim;
X }
X
X outfab->fab$w_ifi = 0; /* Clear IFI. It may be nonzero after ZIP */
X
X ierr = sys$create(outfab);
X if (ierr == RMS$_FEX)
X ierr = replace();
X
X if (ierr == 0) /* Canceled */
X return free_up(), 1;
X
X if (ERR(ierr))
X {
X char buf[256];
X
X sprintf(buf, "[ Cannot create output file %s ]\n", filename);
X message(buf, ierr);
X message("", outfab->fab$l_stv);
X free_up();
X return PK_WARN;
X }
X
X if (!text_output) /* Do not reopen text files and stdout
X * Just open them in right mode */
X {
X /*
X * Reopen file for Block I/O with no XABs.
X */
X if ((ierr = sys$close(outfab)) != RMS$_NORMAL)
X {
X#ifdef DEBUG
X message("[ create_output_file: sys$close failed ]\n", ierr);
X message("", outfab->fab$l_stv);
X#endif
X fprintf(stderr, "Can't create output file: %s\n", filename);
X free_up();
X return PK_WARN;
X }
X
X
X outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT; /* Get ready for block
X * output */
X outfab->fab$l_xab = 0L; /* Unlink all XABs */
X
X if ((ierr = sys$open(outfab)) != RMS$_NORMAL)
X {
X char buf[256];
X
X sprintf(buf, "[ Cannot open output file %s ]\n", filename);
X message(buf, ierr);
X message("", outfab->fab$l_stv);
X free_up();
X return PK_WARN;
X }
X }
X
X outrab = &rab;
X rab.rab$l_fab = outfab;
X if (!text_output)
X { rab.rab$l_rop |= RAB$M_BIO;
X rab.rab$l_rop |= RAB$M_ASY;
X }
X rab.rab$b_rac = RAB$C_SEQ;
X
X if ((ierr = sys$connect(outrab)) != RMS$_NORMAL)
X {
X#ifdef DEBUG
X message("create_output_file: sys$connect failed.\n", ierr);
X message("", outfab->fab$l_stv);
X#endif
X fprintf(stderr, "Can't create output file: %s\n", filename);
X free_up();
X return PK_WARN;
X }
X
X init_buf_ring();
X
X _flush_routine = text_output? got_eol=0,_flush_stream : _flush_blocks;
X _close_routine = _close_rms;


X return PK_COOL;
X}
X

X
X
Xstatic int create_rms_output()
X{
X int ierr, yr, mo, dy, hh, mm, ss;
X char timbuf[24]; /* length = first entry in "stupid" + 1 */
X
X rab = cc$rms_rab; /* fill FAB & RAB with default values */
X fileblk = cc$rms_fab;
X
X text_output = cflag; /* extract the file in text (variable-length)
X * format; ignore -a when attributes saved */
X hostnum = pInfo -> hostnum;
X
X if (cflag)
X {
X if(!PRINTABLE_FORMAT(rfm=outfab->fab$b_rfm))
X { printf("[ File %s has illegal record format to put to screen ]\n",
X filename);
X free_up();
X return PK_DISK;
X }
X }
X
X if (!cflag) /* Redirect output */
X outfab->fab$l_fna = filename;
X else
X outfab->fab$l_fna = "sys$output:";
X
X outfab->fab$b_fns = strlen(outfab->fab$l_fna);
X
X if (!(xabdat && xabrdt)) /* Use date/time info
X * from zipfile if
X * no attributes given
X */
X {
X static char *month[] =
X {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
X "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
X
X /* fixed-length string descriptor: */
X struct dsc$descriptor stupid =
X {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};
X
X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
X mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
X dy = (lrec.last_mod_file_date & 0x1f);
X hh = (lrec.last_mod_file_time >> 11) & 0x1f;
X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
X ss = (lrec.last_mod_file_time & 0x1f) * 2;
X
X dattim = cc$rms_xabdat; /* fill XABs with default values */
X rdt = cc$rms_xabrdt;
X sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr,
X hh, mm, ss);
X sys$bintim(&stupid, &dattim.xab$q_cdt);
X memcpy(&rdt.xab$q_rdt, &dattim.xab$q_cdt, sizeof(rdt.xab$q_rdt));
X
X if (xabdat == 0L)
X {
X dattim.xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) &dattim;
X }
X }
X
X outfab->fab$w_ifi = 0; /* Clear IFI. It may be nonzero after ZIP */
X
X ierr = sys$create(outfab);
X if (ierr == RMS$_FEX)
X ierr = replace();
X
X if (ierr == 0) /* Canceled */
X return free_up(), 1;
X
X if (ERR(ierr))
X {
X char buf[256];
X
X sprintf(buf, "[ Cannot create output file %s ]\n", filename);
X message(buf, ierr);
X message("", outfab->fab$l_stv);
X free_up();
X return PK_WARN;
X }
X
X if (!text_output) /* Do not reopen text files and stdout
X * Just open them in right mode */
X {
X /*
X * Reopen file for Block I/O with no XABs.
X */
X if ((ierr = sys$close(outfab)) != RMS$_NORMAL)
X {
X#ifdef DEBUG
X message("[ create_output_file: sys$close failed ]\n", ierr);
X message("", outfab->fab$l_stv);
X#endif
X fprintf(stderr, "Can't create output file: %s\n", filename);
X free_up();
X return PK_WARN;
X }
X
X
X outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT; /* Get ready for block
X * output */
X outfab->fab$l_xab = 0L; /* Unlink all XABs */
X
X if ((ierr = sys$open(outfab)) != RMS$_NORMAL)
X {
X char buf[256];
X
X sprintf(buf, "[ Cannot open output file %s ]\n", filename);
X message(buf, ierr);
X message("", outfab->fab$l_stv);
X free_up();
X return PK_WARN;
X }
X }
X
X outrab = &rab;
X rab.rab$l_fab = outfab;
X if (!text_output)
X { rab.rab$l_rop |= RAB$M_BIO;
X rab.rab$l_rop |= RAB$M_ASY;
X }
X rab.rab$b_rac = RAB$C_SEQ;
X
X if ((ierr = sys$connect(outrab)) != RMS$_NORMAL)
X {
X#ifdef DEBUG
X message("create_output_file: sys$connect failed.\n", ierr);
X message("", outfab->fab$l_stv);
X#endif
X fprintf(stderr, "Can't create output file: %s\n", filename);
X free_up();
X return PK_WARN;
X }
X
X init_buf_ring();
X
X if( text_output )
X switch(rfm)
X {
X case FAB$C_VAR:
X _flush_routine = _flush_varlen;
X break;
X case FAB$C_STM:
X case FAB$C_STMCR:
X case FAB$C_STMLF:
X _flush_routine = _flush_stream;
X got_eol = 0;
X break;
X default:
X _flush_routine = _flush_blocks;


X break;
X }
X else

X _flush_routine = _flush_blocks;
X _close_routine = _close_rms;


X return PK_COOL;
X}
X

X
X
Xstatic int pka_devchn;
Xstatic int pka_vbn;
X
Xstatic struct
X{ short status;
X long count;
X short dummy;
X} pka_io_sb;
X
Xstatic struct
X{ short status;
X short dummy;
X void *addr;
X} pka_acp_sb;
X
Xstatic struct fibdef pka_fib;
Xstatic struct atrdef pka_atr[VMS_MAX_ATRCNT];
Xstatic int pka_idx;
Xstatic ulg pka_uchar;
Xstatic struct fatdef pka_rattr;
X
Xstatic struct dsc$descriptor pka_fibdsc =
X{ sizeof(pka_fib), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (void *) &pka_fib };
X
Xstatic struct dsc$descriptor_s pka_devdsc =
X{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &nam.nam$t_dvi[1] };
X
Xstatic struct dsc$descriptor_s pka_fnam =
X{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 };
X
X
X
Xstatic int create_qio_output()
X{ int status;
X static char exp_nam[NAM$C_MAXRSS];
X static char res_nam[NAM$C_MAXRSS];
X int i;
X
X if( cflag )
X { fprintf(stderr,"[ Cannot put to screen ]\n");
X return PK_DISK;
X }
X
X fileblk = cc$rms_fab;
X fileblk.fab$l_fna = filename;
X fileblk.fab$b_fns = strlen(filename);
X
X nam = cc$rms_nam;
X fileblk.fab$l_nam = &nam;
X nam.nam$l_esa = exp_nam;
X nam.nam$b_ess = sizeof(exp_nam);
X nam.nam$l_rsa = res_nam;
X nam.nam$b_rss = sizeof(res_nam);
X
X if( ERR(status = sys$parse(&fileblk)) )
X { message("create_output_file: sys$parse failed.\n", status);
X return PK_DISK;
X }
X
X pka_devdsc.dsc$w_length = (unsigned short)nam.nam$t_dvi[0];
X
X if( ERR(status = sys$assign(&pka_devdsc,&pka_devchn,0,0)) )
X { message("sys$assign failed.\n",status);
X return PK_DISK;
X }
X
X pka_fnam.dsc$a_pointer = nam.nam$l_name;
X pka_fnam.dsc$w_length = nam.nam$b_name + nam.nam$b_type;
X if( V_flag /* keep versions */ )
X pka_fnam.dsc$w_length += nam.nam$b_ver;
X
X for (i=0;i<3;i++)
X { pka_fib.FIB$W_DID[i]=nam.nam$w_did[i];
X pka_fib.FIB$W_FID[i]=0;
X }
X
X pka_fib.FIB$L_ACCTL = FIB$M_WRITE;
X /* Allocate space for the file */
X pka_fib.FIB$W_EXCTL = FIB$M_EXTEND;
X if( pka_uchar & FCH$M_CONTIG )
X pka_fib.FIB$W_EXCTL |= FIB$M_ALCON | FIB$M_FILCON;
X if( pka_uchar & FCH$M_CONTIGB )
X pka_fib.FIB$W_EXCTL |= FIB$M_ALCONB;
X
X#define SWAPW(x) ( (((x)>>16)&0xFFFF) + ((x)<<16) )
X
X pka_fib.fib$l_exsz = SWAPW(pka_rattr.fat$r_hiblk_overlay.fat$l_hiblk);
X
X status = sys$qiow(0, pka_devchn, IO$_CREATE|IO$M_CREATE|IO$M_ACCESS,
X &pka_acp_sb, 0, 0,
X &pka_fibdsc, &pka_fnam, 0, 0, &pka_atr, 0);
X
X if( !ERR(status) )
X status = pka_acp_sb.status;
X
X if( ERR(status) )
X { message("[ Create file QIO failed.\n",status);
X return PK_DISK;
X sys$dassgn(pka_devchn);
X }
X
X pka_vbn = 1;
X _flush_routine = _flush_qio;
X _close_routine = _close_qio;


X return PK_COOL;
X}
X

X
X
Xstatic int replace()
X{ /*
X * File exists. Inquire user about further action.
X */
X char answ[10];
X struct NAM nam;
X int ierr;
X
X if (query == 0)
X {
X do
X {
X fprintf(stderr,
X "%s exists: [o]verwrite, new [v]ersion or [n]o extract?\n\
X (uppercase response [O,V,N] = do same for all files): ",
X filename);
X fflush(stderr);
X } while (fgets(answ, 9, stderr) == NULL && !isalpha(answ[0])
X && tolower(answ[0]) != 'o'
X && tolower(answ[0]) != 'v'
X && tolower(answ[0]) != 'n');
X
X if (isupper(answ[0]))
X query = answ[0] = tolower(answ[0]);
X }
X else
X answ[0] = query;
X
X switch (answ[0])
X {
X case 'n':
X ierr = 0;
X break;
X case 'v':
X nam = cc$rms_nam;
X nam.nam$l_rsa = filename;
X nam.nam$b_rss = FILNAMSIZ - 1;
X
X outfab->fab$l_fop |= FAB$M_MXV;
X outfab->fab$l_nam = &nam;
X
X ierr = sys$create(outfab);
X if (!ERR(ierr))
X {
X outfab->fab$l_nam = 0L;
X filename[outfab->fab$b_fns = nam.nam$b_rsl] = 0;
X }
X break;
X case 'o':
X outfab->fab$l_fop |= FAB$M_SUP;
X ierr = sys$create(outfab);
X break;
X }
X return ierr;
X}
X
X
X
X#define W(p) (*(unsigned short*)(p))
X#define L(p) (*(unsigned long*)(p))
X#define EQL_L(a,b) ( L(a) == L(b) )
X#define EQL_W(a,b) ( W(a) == W(b) )
X
X/****************************************************************
X * Function find_vms_attrs scans ZIP entry extra field if any *
X * and looks for VMS attribute records. Returns 0 if either no *
X * attributes found or no fab given. *
X ****************************************************************/
Xint find_vms_attrs()
X{
X uch *scan = extra_field;
X struct EB_header *hdr;
X int len;
X int type=VAT_NONE;
X
X outfab = NULL;
X xabfhc = NULL;
X xabdat = NULL;
X xabrdt = NULL;
X xabpro = NULL;
X first_xab = last_xab = NULL;
X
X if (scan == NULL)
X return PK_COOL;
X len = lrec.extra_field_length;
X
X#define LINK(p) { /* Link xaballs and xabkeys into chain */ \
X if( first_xab == 0L ) \
X first_xab = (void *) p; \
X if( last_xab != 0L ) \
X last_xab -> xab$l_nxt = (void *) p; \
X last_xab = (void *) p; \
X p -> xab$l_nxt = 0; \
X }
X /* End of macro LINK */
X
X while (len > 0)
X {
X hdr = (struct EB_header *) scan;
X if (EQL_W(&hdr->tag, IZ_SIGNATURE))
X {
X /*
X * INFO-ZIP style extra block decoding
X */
X struct IZ_block *blk;
X uch *block_id;
X
X type = VAT_IZ;
X
X blk = (struct IZ_block *)hdr;
X block_id = (uch *) &blk->bid;
X if (EQL_L(block_id, FABSIG))
X {
X outfab = (struct FAB *) extract_block(blk, 0,
X &cc$rms_fab, FABL);
X }
X else if (EQL_L(block_id, XALLSIG))
X {
X xaball = (struct XABALL *) extract_block(blk, 0,
X &cc$rms_xaball, XALLL);
X LINK(xaball);
X }
X else if (EQL_L(block_id, XKEYSIG))
X {
X xabkey = (struct XABKEY *) extract_block(blk, 0,
X &cc$rms_xabkey, XKEYL);
X LINK(xabkey);
X }
X else if (EQL_L(block_id, XFHCSIG))
X {
X xabfhc = (struct XABFHC *) extract_block(blk, 0,
X &cc$rms_xabfhc, XFHCL);
X }
X else if (EQL_L(block_id, XDATSIG))
X {
X xabdat = (struct XABDAT *) extract_block(blk, 0,
X &cc$rms_xabdat, XDATL);
X }
X else if (EQL_L(block_id, XRDTSIG))
X {
X xabrdt = (struct XABRDT *) extract_block(blk, 0,
X &cc$rms_xabrdt, XRDTL);
X }
X else if (EQL_L(block_id, XPROSIG))
X {
X xabpro = (struct XABPRO *) extract_block(blk, 0,
X &cc$rms_xabpro, XPROL);
X }
X else if (EQL_L(block_id, VERSIG))
X {
X#ifdef CHECK_VERSIONS
X char verbuf[80];
X int verlen = 0;
X uch *vers;
X char *m;
X
X get_vms_version(verbuf, 80);
X vers = extract_block(blk, &verlen, 0, 0);
X if ((m = strrchr((char *) vers, '-')) != NULL)
X *m = 0; /* Cut out release number */
X if (strcmp(verbuf, (char *) vers) && qflag < 2)
X {
X printf("[ Warning: VMS version mismatch.");
X
X printf(" This version %s --", verbuf);
X strncpy(verbuf, (char *) vers, verlen);
X verbuf[verlen] = 0;
X printf(" version made by %s ]\n", verbuf);
X }
X free(vers);
X#endif
X }
X else
X fprintf(stderr, "[ Warning: Unknown block signature %s ]\n",
X block_id);
X }
X else if (hdr->tag == PK_SIGNATURE || hdr->tag == IZ_NEW_SIGNATURE)
X {
X /*
X * PKWARE style extra block decoding
X */
X struct PK_header *blk;
X register byte *scn;
X register int len;
X
X type = VAT_PK;
X
X blk = (struct PK_header *)hdr;
X len = blk -> size;
X scn = (byte *)(&blk->data);
X pka_idx = 0;
X
X while(len > PK_FLDHDR_SIZE)
X { register struct PK_field *fld;
X int skip=0;
X
X fld = (struct PK_field *)scn;
X switch(fld->tag)
X { case ATR$C_UCHAR:
X pka_uchar = L(&fld->value);
X break;
X case ATR$C_RECATTR:
X pka_rattr = *(struct fatdef *)(&fld->value);
X break;
X case ATR$C_UIC:
X case ATR$C_ADDACLENT:
X skip = !secinf;
X break;
X }
X
X if( !skip )
X { pka_atr[pka_idx].atr$w_size = fld->size;
X pka_atr[pka_idx].atr$w_type = fld->tag;
X pka_atr[pka_idx].atr$l_addr = &fld->value;
X ++pka_idx;
X }
X len -= fld->size + PK_FLDHDR_SIZE;
X scn += fld->size + PK_FLDHDR_SIZE;
X }
X pka_atr[pka_idx].atr$w_size = 0; /* End of list */
X pka_atr[pka_idx].atr$w_type = 0;
X pka_atr[pka_idx].atr$l_addr = 0L;
X }
X len -= hdr->size + 4;
X scan += hdr->size + 4;
X }
X
X
X if( type == VAT_IZ )
X { if (outfab != 0)
X { /* Do not link XABPRO,XABRDT now. Leave them for sys$close() */
X
X outfab->fab$l_xab = 0L;
X if (xabfhc != 0L)
X {
X xabfhc->xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) xabfhc;
X }
X if (xabdat != 0L)
X {
X xabdat->xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) xabdat;
X }
X if (first_xab != 0L) /* Link xaball,xabkey subchain */
X {
X last_xab->xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) first_xab;
X }
X }
X else
X type = VAT_NONE;
X }
X return type;
X}
X
X
X
Xstatic void free_up()
X{ /*
X * Free up all allocated xabs
X */
X if (xabdat != 0L) free(xabdat);
X if (xabpro != 0L) free(xabpro);
X if (xabrdt != 0L) free(xabrdt);
X if (xabfhc != 0L) free(xabfhc);
X while (first_xab != 0L)
X {
X struct XAB *x;
X
X x = (struct XAB *) first_xab->xab$l_nxt;
X free(first_xab);
X first_xab = x;
X }
X if (outfab != 0L && outfab != &fileblk)
X free(outfab);
X}
X
X
X
X#ifdef CHECK_VERSIONS
X
Xstatic int get_vms_version(verbuf, len)
X char *verbuf;
X int len;
X{
X int i = SYI$_VERSION;
X int verlen = 0;
X struct dsc$descriptor version;
X char *m;
X
X version.dsc$a_pointer = verbuf;
X version.dsc$w_length = len - 1;
X version.dsc$b_dtype = DSC$K_DTYPE_B;
X version.dsc$b_class = DSC$K_CLASS_S;
X
X if (ERR(lib$getsyi(&i, 0, &version, &verlen, 0, 0)) || verlen == 0)
X return 0;
X
X /* Cut out trailing spaces "V5.4-3 " -> "V5.4-3" */
X for (m = verbuf + verlen, i = verlen - 1; i > 0 && verbuf[i] == ' '; --i)
X --m;
X *m = 0;
X
X /* Cut out release number "V5.4-3" -> "V5.4" */
X if ((m = strrchr(verbuf, '-')) != NULL)
X *m = 0;
X return strlen(verbuf) + 1; /* Transmit ending 0 too */
X}
X
X#endif /* CHECK_VERSIONS */
X
X
X
X/*
X * Extracts block from p. If resulting length is less then needed, fill
X * extra space with corresponding bytes from 'init'.
X * Currently understands 3 formats of block compression:
X * - Simple storing
X * - Compression of zero bytes to zero bits
X * - Deflation (see memextract() in extract.c)
X */
Xstatic uch *extract_block(p, retlen, init, needlen)
X struct IZ_block *p;
X int *retlen;
X uch *init;
X int needlen;
X{
X uch *block; /* Pointer to block allocated */
X int cmptype;
X int usiz, csiz, max;
X
X cmptype = p->flags & BC_MASK;
X csiz = p->size - EXTBSL - RESL;
X usiz = (cmptype == BC_STORED ? csiz : p->length);
X
X if (needlen == 0)
X needlen = usiz;
X
X if (retlen)
X *retlen = usiz;
X
X#ifndef MAX
X#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
X#endif
X
X if ((block = (uch *) malloc(MAX(needlen, usiz))) == NULL)
X return NULL;
X
X if (init && (usiz < needlen))
X memcpy(block, init, needlen);
X
X switch (cmptype)
X {
X case BC_STORED: /* The simplest case */
X memcpy(block, &(p->body[0]), usiz);
X break;
X case BC_00:
X decompress_bits(block, usiz, &(p->body[0]));
X break;
X case BC_DEFL:
X memextract(block, usiz, &(p->body[0]), csiz);
X break;
X default:
X free(block);
X block = NULL;
X }
X return block;
X}
X
X
X
X/*
X * Simple uncompression routine. The compression uses bit stream.
X * Compression scheme:
X *
X * if(byte!=0)
X * putbit(1),putbyte(byte)
X * else
X * putbit(0)
X */
Xstatic void decompress_bits(outptr, needlen, bitptr)
X uch *bitptr; /* Pointer into compressed data */
X uch *outptr; /* Pointer into output block */
X int needlen; /* Size of uncompressed block */
X{
X ulg bitbuf = 0;
X int bitcnt = 0;
X
X#define _FILL if(bitcnt+8 <= 32) \
X { bitbuf |= (*bitptr++) << bitcnt;\
X bitcnt += 8; \
X }
X
X while (needlen--)
X {
X if (bitcnt <= 0)
X _FILL;
X
X if (bitbuf & 1)
X {
X bitbuf >>= 1;
X if ((bitcnt -= 1) < 8)
X _FILL;
X *outptr++ = (uch) bitbuf;
X bitcnt -= 8;
X bitbuf >>= 8;
X }
X else
X {
X *outptr++ = 0;
X bitcnt -= 1;
X bitbuf >>= 1;


X }
X }
X}
X
X
X

Xstatic void UpdateCRC(s, len)
X register uch *s;
X register int len;
X{
X register ulg crcval = crc32val;
X
X /* update running CRC calculation with contents of a buffer */
X while (len--)
X crcval = crc_32_tab[((uch)crcval ^ (*s++)) & 0xff] ^ (crcval >> 8);
X crc32val = crcval;
X}
X
X
X
X/* flush contents of output buffer */
Xint flush(rawbuf, size, unshrink) /* return PK-type error code */
X uch *rawbuf;
X ulg size;
X int unshrink;
X{
X UpdateCRC(rawbuf, size);
X if (tflag)
X return PK_COOL; /* Do not output. Update CRC only */
X else
X return (*_flush_routine)(rawbuf, size, 0);
X}
X
X
X
Xstatic int _flush_blocks(rawbuf, size, final_flag) /* Asynchronous version */
X uch *rawbuf;
X unsigned size;
X int final_flag; /* 1 if this is the final flushout */
X{
X int round;
X int rest;
X int off = 0;
X int status;
X
X while (size > 0)
X {
X if (curbuf->bufcnt < BUFS512)
X {
X int ncpy;
X
X ncpy = size > (BUFS512 - curbuf->bufcnt) ?
X BUFS512 - curbuf->bufcnt :
X size;
X memcpy(curbuf->buf + curbuf->bufcnt, rawbuf + off, ncpy);
X size -= ncpy;
X curbuf->bufcnt += ncpy;
X off += ncpy;
X }
X if (curbuf->bufcnt == BUFS512)
X {
X status = WriteBuffer(curbuf->buf, curbuf->bufcnt);
X if (status)
X return status;
X curbuf = curbuf->next;
X curbuf->bufcnt = 0;
X }
X }
X
X return (final_flag && (curbuf->bufcnt > 0)) ?
X WriteBuffer(curbuf->buf, curbuf->bufcnt) :
X PK_COOL;
X}
X
X
X
Xstatic int _flush_qio(rawbuf, size, final_flag)
X uch *rawbuf;
X unsigned size;
X int final_flag; /* 1 if this is the final flushout -- currently ignored */
X{
X int status;
X uch *out_ptr=rawbuf;
X
X if( final_flag )
X {
X if( loccnt > 0 )
X { status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,
X &pka_io_sb, 0, 0,
X locbuf, ((loccnt+1)/2)*2, /* Round to event byte count */
X pka_vbn,
X 0, 0, 0);
X if(!ERR(status))
X status = pka_io_sb.status;
X if(ERR(status))
X { message("[ Write QIO failed ]\n",status);
X return PK_DISK;


X }
X }
X return PK_COOL;
X }
X

X if( loccnt > 0 )
X { /*
X * Fill local buffer upto 512 bytes then put it out
X */
X int ncpy;
X
X ncpy = 512-loccnt;
X if( ncpy > size )
X ncpy = size;
X
X memcpy(locptr,rawbuf,ncpy);
X locptr += ncpy;
X loccnt += ncpy;
X size -= ncpy;
X out_ptr += ncpy;
X if( loccnt == 512 )
X {
X status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,
X &pka_io_sb, 0, 0,
X locbuf, loccnt, pka_vbn,
X 0, 0, 0);
X if(!ERR(status))
X status = pka_io_sb.status;
X if(ERR(status))
X { message("[ Write QIO failed ]\n",status);
X return PK_DISK;
X }
X
X pka_vbn++;
X loccnt = 0;
X locptr = locbuf;
X }
X }
X
X if( size >= 512 )
X { int nblk,put_cnt;
X
X /*
X * Put rest of buffer as a single VB
X */
X put_cnt = (nblk = size>>9)<<9;
X status = sys$qiow(0, pka_devchn, IO$_WRITEVBLK,
X &pka_io_sb, 0, 0,
X out_ptr, put_cnt, pka_vbn,
X 0, 0, 0);
X if(!ERR(status))
X status = pka_io_sb.status;
X if(ERR(status))
X { message("[ Write QIO failed ]\n",status);
X return PK_DISK;
X }
X
X pka_vbn += nblk;
X out_ptr += put_cnt;
X size -= put_cnt;
X }
X
X if( size > 0 )
X { memcpy(locptr,out_ptr,size);
X loccnt += size;
X locptr += size;
X }


X
X
X return PK_COOL;
X}
X

X
X
Xstatic int _flush_varlen(rawbuf, size, final_flag)
X uch *rawbuf;
X unsigned size;
X int final_flag;
X{
X ush nneed;
X ush reclen;
X uch *inptr=rawbuf;
X
X /*
X * Flush local buffer
X */
X
X if( loccnt > 0 )
X { reclen = *(ush*)locbuf;
X if( (nneed = reclen + 2 - loccnt) > 0 )
X { if( nneed > size )
X { if( size+loccnt > BUFS512 )
X { fprintf(stderr,"[ Record too long (%d bytes) ]\n",reclen );
X return PK_DISK;
X }
X memcpy(locbuf+loccnt,rawbuf,size);
X loccnt += size;
X size = 0;
X }
X else
X { memcpy(locbuf+loccnt,rawbuf,nneed);
X loccnt += nneed;
X size -= nneed;
X inptr += nneed;
X if( reclen & 1 )
X { size--;
X inptr++;
X }
X if( WriteRecord(locbuf+2,reclen) )
X return PK_DISK;
X loccnt = 0;
X }
X }
X else
X { if(WriteRecord(locbuf+2,reclen))
X return PK_DISK;
X loccnt -= reclen+2;
X }
X }
X /*
X * Flush incoming records
X */
X while(size > 0)
X { reclen = *(ush*)inptr;
X if( reclen+2 <= size )
X { if(WriteRecord(inptr+2,reclen))
X return PK_DISK;
X size -= 2+reclen;
X inptr += 2+reclen;
X if( reclen & 1)
X { --size;
X ++inptr;
X }
X }
X else
X { memcpy(locbuf,inptr,size);
X loccnt = size;
X size = 0;
X }
X
X }
X /*
X * Final flush rest of local buffer
X */
X if( final_flag && loccnt > 0 )
X { fprintf(stderr,
X "[ Warning, incomplete record of length %d ]\n",
X *(ush*)locbuf);
X if( WriteRecord(locbuf+2,loccnt-2) )
X return PK_DISK;


X }
X return PK_COOL;
X}
X

X
X
X/*
X* Routine _flush_stream breaks decompressed stream into records
X* depending on format of the stream (fab->rfm, pInfo->textmode, etc.)
X* and puts out these records. It also handles CR LF sequences.
X* Should be used when extracting *text* files.
X*/
X
X#define VT 0x0B
X#define FF 0x0C
X
X/* The file is from MSDOS/OS2/NT -> handle CRLF as record end, throw out ^Z */
X
X/* GRR NOTES: cannot depend on hostnum! May have "flip'd" file or re-zipped
X * a Unix file, etc. */
X
X#ifdef USE_ORIG_DOS
X# define ORG_DOS (hostnum==FS_FAT_ || hostnum==FS_HPFS_ || hostnum==FS_NTFS_)
X#else
X# define ORG_DOS 1
X#endif
X
X/* Record delimiters */
X#ifdef undef
X#define RECORD_END(c,f) \
X( ( ORG_DOS || pInfo->textmode ) && c==CTRLZ \
X || ( f == FAB$C_STMLF && c==LF ) \
X || ( f == FAB$C_STMCR || ORG_DOS || pInfo->textmode ) && c==CR \
X || ( f == FAB$C_STM && (c==CR || c==LF || c==FF || c==VT) ) \
X)
X#else
X# define RECORD_END(c,f) ((c) == LF || (c) == (CR))
X#endif
X
Xstatic int find_eol(p,n,l)
X/*
X * Find first CR,LF,CR-LF or LF-CR in string 'p' of length 'n'.
X * Return offset of the sequence found or 'n' if not found.
X * If found, return in '*l' length of the sequence (1 or 2) or
X * zero if sequence end not seen, i.e. CR or LF is last char
X * in the buffer.
X */
Xchar *p;
Xint n;
Xint *l;
X{ int off = n;
X char *q;
X
X *l = 0;
X
X for(q=p ; n > 0 ; --n,++q)
X if( RECORD_END(*q,rfm) )
X { off = q-p;
X break;
X }
X
X if( n > 1 )
X {
X *l = 1;
X if( ( q[0] == CR && q[1] == LF ) || ( q[0] == LF && q[1] == CR ) )
X *l = 2;
X }
X
X return off;
X}
X
X/* Record delimiters that must be put out */
X#define PRINT_SPEC(c) ( (c)==FF || (c)==VT )
X
X
X
Xstatic int _flush_stream(rawbuf, size, final_flag)
X uch *rawbuf;
X unsigned size;
X int final_flag; /* 1 if this is the final flushout */
X{
X int rest;
X int end = 0, start = 0;
X int off = 0;
X
X if (size == 0 && loccnt == 0)
X return PK_COOL; /* Nothing to do ... */
X
X if( final_flag )
X { int recsize;
X
X /*
X * This is flush only call. size must be zero now.
X * Just eject everything we have in locbuf.
X */
X recsize = loccnt - (got_eol ? 1:0);
X /*
X * If the last char of file was ^Z ( end-of-file in MSDOS ),
X * we will see it now.
X */
X if( recsize==1 && locbuf[0] == CTRLZ )
X return PK_COOL;
X
X return WriteRecord(locbuf, recsize) ? PK_DISK : PK_COOL;
X }
X
X
X if ( loccnt > 0 )
X { /* Find end of record partialy saved in locbuf */
X
X int recsize;
X int complete=0;
X
X if( got_eol )
X { recsize = loccnt - 1;
X complete = 1;
X
X if( (got_eol == CR && rawbuf[0] == LF) || (got_eol == LF && rawbuf[0] == CR) )
X end = 1;
X
X got_eol = 0;
X }
X else
X { int eol_len;
X int eol_off;
X
X eol_off = find_eol(rawbuf,size,&eol_len);
X
X if( loccnt+eol_off > BUFS512 )
X { /*
X * No room in locbuf. Dump it and clear
X */
X recsize = loccnt;
X start = 0;
X fprintf(stderr, "[ Warning: Record too long (%d) ]\n",
X loccnt+eol_off);
X complete = 1;
X end = 0;
X }
X else
X { if( eol_off >= size )
X { end = size;
X complete = 0;
X }
X else if( eol_len == 0 )
X { got_eol = rawbuf[eol_off];
X end = size;
X complete = 0;
X }
X else
X { memcpy(locptr, rawbuf, eol_off);
X recsize = loccnt + eol_off;
X locptr += eol_off;
X loccnt += eol_off;
X end = eol_off + eol_len;
X complete = 1;
X }
X }
X }
X
X if( complete )
X { if (WriteRecord(locbuf, recsize))
X return PK_DISK;
X loccnt = 0;
X locptr = locbuf;
X }
X } /* end if( loccnt ) */
X
X for(start = end; start < size && end < size; )
X { int eol_off,eol_len;
X
X got_eol = 0;
X
X#ifdef undef
X if (cflag)
X /* skip CR's at the beginning of record */
X while (start < size && rawbuf[start] == CR)
X ++start;
X#endif
X
X if( start >= size )
X continue;
X
X /* Find record end */
X end = start+(eol_off = find_eol(rawbuf+start, size-start, &eol_len));
X
X if( end >= size )
X continue;
X
X if( eol_len > 0 )
X { if( WriteRecord(rawbuf+start, end-start) )
X return PK_DISK;
X start = end + eol_len;
X }
X else
X { got_eol = rawbuf[end];
X end = size;
X continue;
X }
X }
X
X rest = size - start;
X
X if (rest > 0)
X { if( rest > BUFS512 )
X { int recsize;
X
X recsize = rest - (got_eol ? 1:0 );
X fprintf(stderr, "[ Warning: Record too long (%d) ]\n", recsize);
X got_eol = 0;
X return WriteRecord(rawbuf+start,recsize) ? PK_DISK : PK_COOL;
X }
X else
X { memcpy(locptr, rawbuf + start, rest);
X locptr += rest;
X loccnt += rest;


X }
X }
X return PK_COOL;
X}
X

X
X
Xstatic int WriteBuffer(buf, len)
X unsigned char *buf;
X int len;
X{
X int status;
X
X status = sys$wait(outrab);
X if (ERR(status))
X {
X message("[ WriteBuffer failed ]\n", status);
X message("", outrab->rab$l_stv);
X }
X outrab->rab$w_rsz = len;
X outrab->rab$l_rbf = (char *) buf;
X
X if (ERR(status = sys$write(outrab)))
X {
X message("[ WriteBuffer failed ]\n", status);
X message("", outrab->rab$l_stv);
X return PK_DISK;


X }
X return PK_COOL;
X}
X

X
X
Xstatic int WriteRecord(rec, len)
X unsigned char *rec;
X int len;
X{
X int status;
X
X if (ERR(status = sys$wait(outrab)))
X {
X message("[ WriteRecord failed ]\n", status);
X message("", outrab->rab$l_stv);
X }
X outrab->rab$w_rsz = len;
X outrab->rab$l_rbf = (char *) rec;
X
X if (ERR(status = sys$put(outrab)))
X {
X message("[ WriteRecord failed ]\n", status);
X message("", outrab->rab$l_stv);
X return PK_DISK;


X }
X return PK_COOL;
X}
X

X
X
Xvoid close_outfile()
X{
X int status;
X
X status = (*_flush_routine)(0, 0, 1);
X if (status)
X return /* PK_DISK */;
X if (cflag)
X return; /* Don't close stdout */
X /* return */ (*_close_routine)();
X}
X
X
X
Xstatic int _close_rms()
X{
X int status;
X struct XABPRO pro;
X
X /* Link XABRDT,XABDAT and optionaly XABPRO */
X if (xabrdt != 0L)
X {
X xabrdt->xab$l_nxt = 0L;
X outfab->fab$l_xab = (void *) xabrdt;
X }
X else
X {
X rdt.xab$l_nxt = 0L;
X outfab->fab$l_xab = (void *) &rdt;
X }
X if (xabdat != 0L)
X {
X xabdat->xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *)xabdat;
X }
X
X if( xabpro != 0L )
X {
X if( !secinf )
X xabpro->xab$l_uic = 0; /* Use default (user's) uic */
X xabpro->xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) xabpro;
X }
X else
X { pro = cc$rms_xabpro;
X pro.xab$w_pro = pInfo->file_attr;
X pro.xab$l_nxt = outfab->fab$l_xab;
X outfab->fab$l_xab = (void *) &pro;
X }
X
X sys$wait(outrab);
X
X status = sys$close(outfab);
X#ifdef DEBUG
X if (ERR(status))
X {
X message("\r[ Warning: cannot set owner/protection/time attributes ]\n",
X status);
X message("", outfab->fab$l_stv);
X }
X#endif
X free_up();


X return PK_COOL;
X}
X

X
X
Xstatic int _close_qio()
X{ int status;
X
X pka_fib.FIB$L_ACCTL =
X FIB$M_WRITE | FIB$M_NOTRUNC ;
X pka_fib.FIB$W_EXCTL = 0;
X
X pka_fib.FIB$W_FID[0] =
X pka_fib.FIB$W_FID[1] =
X pka_fib.FIB$W_FID[2] =
X pka_fib.FIB$W_DID[0] =
X pka_fib.FIB$W_DID[1] =
X pka_fib.FIB$W_DID[2] = 0;
X
X status = sys$qiow(0, pka_devchn, IO$_DEACCESS, &pka_acp_sb,
X 0, 0,
X &pka_fibdsc, 0, 0, 0,
X &pka_atr, 0);
X
X sys$dassgn(pka_devchn);
X if( !ERR(status) )
X status = pka_acp_sb.status;
X if( ERR(status) )
X { message("[ Deaccess QIO failed ]\n",status);
X return PK_DISK;


X }
X return PK_COOL;
X}
X

X
X
X#ifdef DEBUG
Xdump_rms_block(p)
X unsigned char *p;
X{
X unsigned char bid, len;
X int err;
X char *type;
X char buf[132];
X int i;
X
X err = 0;
X bid = p[0];
X len = p[1];
X switch (bid)
X {
X case FAB$C_BID:
X type = "FAB";
X break;
X case XAB$C_ALL:
X type = "xabALL";
X break;
X case XAB$C_KEY:
X type = "xabKEY";
X break;
X case XAB$C_DAT:
X type = "xabDAT";
X break;
X case XAB$C_RDT:
X type = "xabRDT";
X break;
X case XAB$C_FHC:
X type = "xabFHC";
X break;
X case XAB$C_PRO:
X type = "xabPRO";
X break;
X default:
X type = "Unknown";
X err = 1;
X break;
X }
X printf("Block @%08X of type %s (%d).", p, type, bid);
X if (err)
X {
X printf("\n");
X return;
X }
X printf(" Size = %d\n", len);
X printf(" Offset - Hex - Dec\n");
X for (i = 0; i < len; i += 8)
X {
X int j;
X
X printf("%3d - ", i);
X for (j = 0; j < 8; j++)
X if (i + j < len)
X printf("%02X ", p[i + j]);
X else
X printf(" ");
X printf(" - ");
X for (j = 0; j < 8; j++)
X if (i + j < len)
X printf("%03d ", p[i + j]);
X else
X printf(" ");
X printf("\n");
X }
X}
X
X#endif /* DEBUG */
X
X
X
Xstatic void message(string, status)
X int status;
Xchar *string;
X{
X char msgbuf[256];
X
X $DESCRIPTOR(msgd, msgbuf);
X int msglen = 0;
X
X if (ERR(lib$sys_getmsg(&status, &msglen, &msgd, 0, 0)))
X fprintf(stderr, "%s[ VMS status = %d ]\n", string, status);
X else
X {
X msgbuf[msglen] = 0;
X fprintf(stderr, "%s[ %s ]\n", string, msgbuf);


X }
X}
X
X
X

X#ifndef SFX
X
Xchar *do_wild( wld )
X char *wld;
X{
X int status;
X
X static char filename[256];
X static char efn[256];
X static char last_wild[256];
X static struct FAB fab;
X static struct NAM nam;
X static int first_call=1;
X static char deflt[] = "*.zip";
X
X if( first_call || strcmp(wld, last_wild) )
X { /* (Re)Initialize everything */
X
X strcpy( last_wild, wld );
X first_call = 1; /* New wild spec */
X
X fab = cc$rms_fab;
X fab.fab$l_fna = last_wild;
X fab.fab$b_fns = strlen(last_wild);
X fab.fab$l_dna = deflt;
X fab.fab$b_dns = strlen(deflt);
X fab.fab$l_nam = &nam;
X nam = cc$rms_nam;
X nam.nam$l_esa = efn;
X nam.nam$b_ess = sizeof(efn)-1;
X nam.nam$l_rsa = filename;
X nam.nam$b_rss = sizeof(filename)-1;
X
X if(!OK(sys$parse(&fab)))
X return (char *)NULL; /* Initialization failed */
X first_call = 0;
X if( !OK(sys$search(&fab)) )
X {
X strcpy( filename, wld );
X return filename;
X }
X }
X else
X {
X if( !OK(sys$search(&fab)) )
X {
X first_call = 1; /* Reinitialize next time */
X return (char *)NULL;
X }
X }
X filename[nam.nam$b_rsl] = 0;
X return filename;
X
X} /* end function do_wild() */


X
X#endif /* !SFX */
X
X

X
Xstatic ulg unix_to_vms[8]={ /* Map from UNIX rwx to VMS rwed */
X /* Note that unix w bit is mapped to VMS wd bits */
X XAB$M_NOREAD | XAB$M_NOWRITE | XAB$M_NODEL | XAB$M_NOEXE, /* --- no access*/
X XAB$M_NOREAD | XAB$M_NOWRITE | XAB$M_NODEL, /* --x */
X XAB$M_NOREAD | XAB$M_NOEXE, /* -w- */
X XAB$M_NOREAD, /* -wx */
X XAB$M_NOWRITE | XAB$M_NODEL | XAB$M_NOEXE, /* r-- */
X XAB$M_NOWRITE | XAB$M_NODEL, /* r-x */
X XAB$M_NOEXE, /* rw- */
X 0 /* rwx full access*/
X};
X
X#define SETDFPROT /* We are using undocumented VMS System Service */
X /* SYS$SETDFPROT here. If your version of VMS does */
X /* not have that service, undef SETDFPROT. */
X /* IM: Maybe it's better to put this to Makefile */
X /* and DESCRIP.MMS */
X
X
X
Xint mapattr()
X{
X ulg tmp=crec.external_file_attributes, theprot;
X static ulg defprot = -1L,
X sysdef,owndef,grpdef,wlddef; /* Default protection fields */
X
X
X /* IM: The only field of XABPRO we need to set here is */
X /* file protection, so we need not to change type */
X /* of pInfo->file_attr. WORD is quite enough. */
X
X if( defprot == -1L )
X {
X /*
X * First time here -- Get user default settings
X */
X
X#ifdef SETDFPROT /* Undef this if linker cat't resolve SYS$SETDFPROT */
X defprot = 0L;
X if( !ERR(SYS$SETDFPROT(0,&defprot)) )
X {
X sysdef = defprot & ( (1L<<XAB$S_SYS)-1 ) << XAB$V_SYS;
X owndef = defprot & ( (1L<<XAB$S_OWN)-1 ) << XAB$V_OWN;
X grpdef = defprot & ( (1L<<XAB$S_GRP)-1 ) << XAB$V_GRP;
X wlddef = defprot & ( (1L<<XAB$S_WLD)-1 ) << XAB$V_WLD;
X }
X else
X {
X#endif /* ?SETDFPROT */
X umask(defprot = umask(0));
X defprot = ~defprot;
X wlddef = unix_to_vms[defprot & 07] << XAB$V_WLD;
X grpdef = unix_to_vms[(defprot>>3) & 07] << XAB$V_GRP;
X owndef = unix_to_vms[(defprot>>6) & 07] << XAB$V_OWN;
X sysdef = owndef << (XAB$V_SYS - XAB$V_OWN);
X defprot = sysdef | owndef | grpdef | wlddef;
X#ifdef SETDFPROT
X }
X#endif /* ?SETDFPROT */
X }
X
X switch (pInfo->hostnum) {
X case UNIX_:
X case VMS_: /*IM: ??? Does VMS Zip store protection in UNIX format ?*/
X /* GRR: Yup. Bad decision on my part... */
X tmp = (unsigned)(tmp >> 16); /* drwxrwxrwx */
X theprot = (unix_to_vms[tmp & 07] << XAB$V_WLD)
X | (unix_to_vms[(tmp>>3) & 07] << XAB$V_GRP)
X | (unix_to_vms[(tmp>>6) & 07] << XAB$V_OWN);
X
X if( tmp & 0x4000 )
X /* Directory -- set D bits */
X theprot |= (XAB$M_NODEL << XAB$V_SYS)
X | (XAB$M_NODEL << XAB$V_OWN)
X | (XAB$M_NODEL << XAB$V_GRP)
X | (XAB$M_NODEL << XAB$V_WLD);
X pInfo->file_attr = theprot;
X break;
X
X case AMIGA_:
X tmp = (unsigned)(tmp>>16 & 0x0f); /* Amiga RWED bits */
X pInfo->file_attr = (tmp << XAB$V_OWN) | grpdef | sysdef | wlddef;
X break;
X
X /* all remaining cases: expand MSDOS read-only bit into write perms */
X case FS_FAT_:
X case FS_HPFS_:
X case FS_NTFS_:
X case MAC_:
X case ATARI_: /* (used to set = 0666) */
X case TOPS20_:
X default:
X theprot = defprot;
X if( tmp & 1 ) /* Test read-only bit */
X { /* Bit is set -- set bits in all fields */
X tmp = XAB$M_NOWRITE | XAB$M_NODEL;
X theprot |= (tmp << XAB$V_SYS) | (tmp << XAB$V_OWN) |
X (tmp << XAB$V_GRP) | (tmp << XAB$V_WLD);
X }
X pInfo->file_attr = theprot;
X break;
X } /* end switch (host-OS-created-by) */


X
X return 0;
X

X} /* end function mapattr() */
X
X
X
X#ifndef EEXIST
X# include <errno.h> /* For mkdir() status codes */
X#endif
X
X#include <fscndef.h> /* for filescan */
X
X# define FN_MASK 7
X# define USE_DEFAULT (FN_MASK+1)
X
X/*
X * Checkdir function codes:
X * ROOT - set root path from unzip qq d:[dir]
X * INIT - get ready for "filename"
X * APPEND_DIR - append pathcomp
X * APPEND_NAME - append filename
X * APPEND_NAME | USE_DEFAULT - expand filename using collected path
X * GETPATH - return resulting filespec
X */
X
Xstatic int created_dir;
X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc),*/
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
X{ /* 3 if error (skip file), 10 if no memory (skip file) */
X char pathcomp[FILNAMSIZ]; /* path-component buffer */
X char *pp, *cp=NULL; /* character pointers */
X char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */
X char *last_dot = NULL; /* last dot not converted to underscore */
X int quote = FALSE; /* flag: next char is literal */
X int dotname = FALSE; /* flag: path component begins with dot */
X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X if( renamed )
X {
X if( !(error = checkdir(pathcomp, APPEND_NAME | USE_DEFAULT)) )
X strcpy(filename, pathcomp);


X return error;
X }
X

X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X
X /* can create path as long as not just freshening, or if user told us */


X create_dirs = !fflag;
X

X created_dir = FALSE; /* not yet */
X
X/* GRR: for VMS, convert to internal format now or later? or never? */
X if (checkdir(pathcomp, INIT) == 10)
X return 10; /* initialize path buffer, unless no memory */
X
X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */
X if (jflag) /* junking directories */
X/* GRR: watch out for VMS version... */
X cp = (char *)strrchr(filename, '/');
X if (cp == NULL) /* no '/' or not junking dirs */
X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X
X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';
X if (last_dot) { /* one dot in directory name is legal */
X *last_dot = '.';
X last_dot = NULL;
X }
X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */
X lastsemi = NULL; /* leave directory semi-colons alone */
X break;
X
X case ':':
X *pp++ = '_'; /* drive names not stored in zipfile, */
X break; /* so no colons allowed */
X
X case '.':
X if (pp == pathcomp) { /* nothing appended yet... */
X if (*cp == '/') { /* don't bother appending a "./" */
X ++cp; /* component to the path: skip */
X break; /* to next char after the '/' */
X } else if (*cp == '.' && cp[1] == '/') { /* "../" */
X *pp++ = '.'; /* add first dot, unchanged... */
X ++cp; /* skip second dot, since it will */
X } /* added next (as '_' for now) */
X }
X last_dot = pp; /* point at last dot so far... */
X *pp++ = '_'; /* convert dot to underscore for now */
X break;
X
X case ';': /* start of VMS version? */
X if (lastsemi)
X *lastsemi = '_'; /* convert previous one to underscore */
X lastsemi = pp;
X *pp++ = ';'; /* keep for now; remove VMS vers. later */
X break;
X
X case ' ':
X *pp++ = '_';


X break;
X
X default:

X if( isalpha(workch) || isdigit(workch) ||
X workch=='$' || workch=='-' )
X *pp++ = (char)workch;
X else
X *pp++ = '_'; /* convert everything else to underscore */
X break;


X } /* end switch */
X

X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X
X /* if not saving them, remove VMS version numbers (appended "###") */
X if (lastsemi) {
X pp = lastsemi + 1; /* expect all digits after semi-colon */
X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp) /* not version number: convert ';' to '_' */
X *lastsemi = '_';
X else if (!V_flag) /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X /* else only digits and we're saving version number: do nothing */
X }
X
X if (last_dot != NULL) /* one dot is OK: put it back in */
X *last_dot = '.'; /* (already done for directories) */
X
X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.
X ---------------------------------------------------------------------------*/
X
X if (filename[strlen(filename) - 1] == '/') {
X checkdir("", APPEND_NAME); /* create directory, if not found */
X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {
X fprintf(stdout, " creating: %s\n", filename);
X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X
X if (*pathcomp == '\0') {
X fprintf(stderr, "mapname: conversion of %s failed\n", filename);
X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);


X
X return error;
X

X} /* end function mapname() */
X
X
X
Xint checkdir(pathcomp,fcn)
X/*
X * returns: 1 - (on APPEND_NAME) truncated filename
X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be
X * 4 - path is too long
X * 10 - can't allocate memory for filename buffers
X */
X char *pathcomp;
X int fcn;
X{
X int function=fcn & FN_MASK;
X static char pathbuf[FILNAMSIZ];
X static char lastdir[FILNAMSIZ]="\t"; /* directory created last time */
X /* initially - impossible dir. spec. */
X static char *pathptr=pathbuf; /* For debugger */
X static char *devptr, *dirptr, *namptr;
X static int devlen, dirlen, namlen;
X static int root_dirlen;
X static char *end;
X static int first_comp,root_has_dir;
X static int rootlen=0;
X static char *rootend;
X static int mkdir_failed=0;
X int status;
X
X/************
X *** ROOT ***
X ************/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if(function==ROOT)
X { /* Assume VMS root spec */
X char *p = pathcomp;
X char *q;
X
X struct
X { short len;
X short code;
X char *addr;
X } itl [4] =
X {
X { 0, FSCN$_DEVICE, 0 },
X { 0, FSCN$_ROOT, 0 },
X { 0, FSCN$_DIRECTORY, 0 },
X { 0, 0, 0 } /* End of itemlist */
X };
X int fields = 0;
X struct dsc$descriptor pthcmp;
X
X /*
X * Initialize everything
X */
X end = devptr = dirptr = rootend = pathbuf;
X devlen = dirlen = rootlen = 0;
X
X pthcmp.dsc$a_pointer = pathcomp;
X if( (pthcmp.dsc$w_length = strlen(pathcomp)) > 255 )
X return 4;
X
X status = sys$filescan(&pthcmp, itl, &fields);
X if( !OK(status) )
X return 3;
X
X if( fields & FSCN$M_DEVICE )
X { strncpy(devptr = end, itl[0].addr, itl[0].len);
X dirptr = (end += (devlen = itl[0].len));
X }
X
X root_has_dir = 0;
X
X if( fields & FSCN$M_ROOT )
X { int len;
X
X strncpy(dirptr = end, itl[1].addr,
X len = itl[1].len - 1); /* Cut out trailing ']' */
X end += len;
X root_has_dir = 1;
X }
X
X if( fields & FSCN$M_DIRECTORY )
X { char *ptr;
X int len;
X
X len = itl[2].len-1;
X ptr = itl[2].addr;
X
X if( root_has_dir /* i.e. root specified */ )
X { --len; /* Cut out leading dot */
X ++ptr; /* ??? [a.b.c.][.d.e] */
X }
X
X strncpy(dirptr=end, ptr, len); /* Replace trailing ']' */
X *(end+=len) = '.'; /* ... with dot */
X ++end;
X root_has_dir = 1;
X }
X
X /* When user specified "[a.b.c.]" or "[qq...]", we have too many
X * trailing dots. Let's cut them out. Now we surely have at least
X * one trailing dot and "end" points just behind it. */
X
X dirlen = end - dirptr;
X while( dirlen > 1 && end[-2] == '.' )
X --dirlen,--end;
X
X first_comp = !root_has_dir;
X root_dirlen = end - dirptr;
X *(rootend = end) = 0;
X rootlen = rootend - devptr;
X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X
X
X/************
X *** INIT ***
X ************/
X
X if( function == INIT )
X {
X if( strlen(filename) + rootlen + 13 > 255 )
X return 4;
X
X if( rootlen == 0 ) /* No root given, reset everything. */
X { devptr = dirptr = rootend = pathbuf;
X devlen = dirlen = 0;
X }
X end = rootend;
X first_comp = !root_has_dir;
X if( dirlen = root_dirlen )
X end[-1] = '.';
X *end = 0;


X return 0;
X }
X

X
X/******************
X *** APPEND_DIR ***
X ******************/
X if( function == APPEND_DIR )
X { int cmplen;
X
X cmplen = strlen(pathcomp);
X
X if( first_comp )
X { *end++ = '[';
X if( cmplen )
X *end++ = '.'; /* "dir/..." --> "[.dir...]" */
X /* else "/dir..." --> "[dir...]" */
X first_comp = 0;
X }
X
X if( cmplen == 1 && *pathcomp == '.' )
X ; /* "..././..." -- ignore */
X
X else if( cmplen == 2 && pathcomp[0] == '.' && pathcomp[1] == '.' )
X { /* ".../../..." -- convert to "...-..." */
X *end++ = '-';
X *end++ = '.';
X }
X
X else if( cmplen + (end-pathptr) > 255 )
X return 4;
X
X else
X { strcpy(end, pathcomp);
X *(end+=cmplen) = '.';
X ++end;
X }
X dirlen = end - dirptr;
X *end = 0;


X return 0;
X }
X

X
X/*******************
X *** APPEND_NAME ***
X *******************/
X if( function == APPEND_NAME )
X { if( fcn & USE_DEFAULT )
X { /* Expand renamed filename using collected path, return
X * at pathcomp */
X struct FAB fab;
X struct NAM nam;
X
X fab = cc$rms_fab;
X fab.fab$l_fna = filename;
X fab.fab$b_fns = strlen(filename);
X fab.fab$l_dna = pathptr;
X fab.fab$b_dns = end-pathptr;
X
X fab.fab$l_nam = &nam;
X nam = cc$rms_nam;
X nam.nam$l_esa = pathcomp;
X nam.nam$b_ess = 255; /* Assume large enaugh */
X
X if(!OK(status = sys$parse(&fab)) && status == RMS$_DNF ) /* Directory not found: */
X { char save; /* ... try to create it */
X char *dirend;
X int mkdir_failed;
X
X dirend = (char*)nam.nam$l_dir + nam.nam$b_dir;
X save = *dirend;
X *dirend = 0;
X if( (mkdir_failed = mkdir(nam.nam$l_dev, 0)) && errno == EEXIST )
X mkdir_failed = 0;
X *dirend = save;
X if( mkdir_failed )
X return 3;
X created_dir = TRUE;
X } /* if (sys$parse... */
X pathcomp[nam.nam$b_esl] = 0;
X return 0;
X } /* if (USE_DEFAULT) */
X else
X {
X *end = 0;
X if( dirlen )
X { dirptr[dirlen-1] = ']'; /* Close directory */
X
X /*
X * Try to create the target directory.
X * Don't waste time creating directory that was created
X * last time.
X */
X if( STRICMP(lastdir,pathbuf) )
X {
X mkdir_failed = 0;
X if( mkdir(pathbuf,0) )
X { if( errno != EEXIST )
X mkdir_failed = 1; /* Mine for GETPATH */
X }
X else
X created_dir = TRUE;
X strcpy(lastdir,pathbuf);
X }
X }
X else
X { /*
X * Target directory unspecified.
X * Try to create "sys$disk:[]"
X */
X if( strcmp(lastdir,"sys$disk:[]") )
X { strcpy(lastdir,"sys$disk:[]");
X mkdir_failed = 0;
X if( mkdir(lastdir,0) && errno != EEXIST )
X mkdir_failed = 1; /* Mine for GETPATH */
X }
X }
X if( strlen(pathcomp) + (end-pathbuf) > 255 )
X return 1;
X strcpy(end, pathcomp);
X end += strlen(pathcomp);


X return 0;
X }
X }

X
X
X/***************
X *** GETPATH ***
X ***************/
X if( function == GETPATH )
X {
X if( mkdir_failed )
X return 3;
X *end = 0; /* To be safe */
X strcpy( pathcomp, pathbuf );
X return 0;


X }
X}
X
X
X

Xint check_for_newer(filename) /* return 1 if existing file newer or equal; */
X char *filename; /* 0 if older; -1 if doesn't exist yet */
X{
X unsigned short timbuf[7];
X int dy, mo, yr, hh, mm, ss, dy2, mo2, yr2, hh2, mm2, ss2;
X struct FAB fab;
X struct XABDAT xdat;
X
X
X if (stat(filename, &statbuf))
X return DOES_NOT_EXIST;
X
X fab = cc$rms_fab;
X xdat = cc$rms_xabdat;
X
X fab.fab$l_xab = (char *) &xdat;
X fab.fab$l_fna = filename;
X fab.fab$b_fns = strlen(filename);
X fab.fab$l_fop = FAB$M_GET | FAB$M_UFO;
X
X if ((sys$open(&fab) & 1) == 0) /* open failure: report exists and */
X return EXISTS_AND_OLDER; /* older so new copy will be made */
X sys$numtim(&timbuf,&xdat.xab$q_cdt);
X fab.fab$l_xab = 0L;
X
X sys$dassgn(fab.fab$l_stv);
X sys$close(&fab); /* be sure file is closed and RMS knows about it */
X
X yr = timbuf[0];
X yr2 = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
X if (yr > yr2)
X return EXISTS_AND_NEWER;
X else if (yr < yr2)
X return EXISTS_AND_OLDER;
X
X mo = timbuf[1];
X mo2 = ((lrec.last_mod_file_date >> 5) & 0x0f);
X if (mo > mo2)
X return EXISTS_AND_NEWER;
X else if (mo < mo2)
X return EXISTS_AND_OLDER;
X
X dy = timbuf[2];
X dy2 = (lrec.last_mod_file_date & 0x1f);
X if (dy > dy2)
X return EXISTS_AND_NEWER;
X else if (dy < dy2)
X return EXISTS_AND_OLDER;
X
X hh = timbuf[3];
X hh2 = (lrec.last_mod_file_time >> 11) & 0x1f;
X if (hh > hh2)
X return EXISTS_AND_NEWER;
X else if (hh < hh2)
X return EXISTS_AND_OLDER;
X
X mm = timbuf[4];
X mm2 = (lrec.last_mod_file_time >> 5) & 0x3f;
X if (mm > mm2)
X return EXISTS_AND_NEWER;
X else if (mm < mm2)
X return EXISTS_AND_OLDER;
X
X /* round to nearest 2 secs--may become 60, but doesn't matter for compare */
X ss = (int)((float)timbuf[5] + (float)timbuf[6]*.01 + 1.) & -2;
X ss2 = (lrec.last_mod_file_time & 0x1f) * 2;
X if (ss >= ss2)
X return EXISTS_AND_NEWER;
X
X return EXISTS_AND_OLDER;
X}
X
X
X
Xvoid return_VMS(ziperr)
X int ziperr;
X{
X#ifdef RETURN_CODES
X/*---------------------------------------------------------------------------
X Do our own, explicit processing of error codes and print message, since
X VMS misinterprets return codes as rather obnoxious system errors ("access
X violation," for example).
X ---------------------------------------------------------------------------*/
X
X switch (ziperr) {
X
X case PK_COOL:
X break; /* life is fine... */
X case PK_WARN:
X fprintf(stderr, "\n[return-code 1: warning error \
X(e.g., failed CRC or unknown compression method)]\n");
X break;
X case PK_ERR:
X case PK_BADERR:
X fprintf(stderr, "\n[return-code %d: error in zipfile \
X(e.g., can't find local file header sig)]\n", ziperr);
X break;
X case PK_MEM:
X case PK_MEM2:
X case PK_MEM3:
X case PK_MEM4:
X case PK_MEM5:
X fprintf(stderr, "\n[return-code %d: insufficient memory]\n", ziperr);
X break;
X case PK_NOZIP:
X fprintf(stderr, "\n[return-code 9: zipfile not found]\n");
X break;
X case PK_PARAM: /* the one that gives "access violation," I think */
X fprintf(stderr, "\n[return-code 10: bad or illegal parameters \
Xspecified on command line]\n");
X break;
X case PK_FIND:
X fprintf(stderr,
X "\n[return-code 11: no files found to extract/view/etc.]\n");
X break;
X case PK_DISK:
X fprintf(stderr,
X "\n[return-code 50: disk full or other I/O error]\n");
X break;
X case PK_EOF:
X fprintf(stderr,
X "\n[return-code 51: unexpected EOF in zipfile (i.e., truncated)]\n");
X break;
X default:
X fprintf(stderr, "\n[return-code %d: unknown return-code (screw-up)]\n",
X ziperr);
X break;
X }
X#endif /* RETURN_CODES */
X
X/*---------------------------------------------------------------------------
X Return an intelligent status/severity level if RETURN_SEVERITY defined:
X
X $STATUS $SEVERITY = $STATUS & 7
X 31 .. 16 15 .. 3 2 1 0
X -----
X VMS 0 0 0 0 Warning
X FACILITY 0 0 1 1 Success
X Number 0 1 0 2 Error
X MESSAGE 0 1 1 3 Information
X Number 1 0 0 4 Severe (fatal) error
X
X 0x7FFF0000 was chosen (by experimentation) to be outside the range of
X VMS FACILITYs that have dedicated message numbers. Hopefully this will
X always result in silent exits--it does on VMS 5.4. Note that the C li-
X brary translates exit arguments of zero to a $STATUS value of 1 (i.e.,
X exit is both silent and has a $SEVERITY of "success").
X ---------------------------------------------------------------------------*/
X
X#ifdef RETURN_SEVERITY
X {
X int severity = (ziperr == 2 || (ziperr >= 9 && ziperr <= 11))? 2 : 4;
X
X exit( /* $SEVERITY: */
X (ziperr == PK_COOL) ? 1 : /* success */
X (ziperr == PK_WARN) ? 0x7FFF0000 : /* warning */
X (0x7FFF0000 | (ziperr << 4) | severity) /* error or fatal */
X );
X }
X#else
X exit(0); /* everything okey-dokey as far as VMS concerned */
X#endif
X
X} /* end function return_VMS() */


X
X
X
X
X

X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()
X{
X extern char Far CompiledWith[];
X#ifdef VMS_VERSION
X char buf[40];
X#endif
X
X printf(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else
X# if 0
X "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
X# else
X# if defined(DECC) || defined(__DECC) || defined (__DECC__)
X "DEC C", "",
X# else
X# ifdef VAXC
X "VAX C", "",
X# else
X "unknown compiler", "",


X# endif
X# endif
X# endif

X#endif
X
X#ifdef VMS_VERSION
X# if defined(__alpha)
X "OpenVMS", /* version has trailing spaces ("V6.1 "), so truncate: */
X (sprintf(buf, " (%.4s for Alpha)", VMS_VERSION), buf),
X# else /* VAX */
X (VMS_VERSION[1] >= '6')? "OpenVMS" : "VMS",
X (sprintf(buf, " (%.4s for VAX)", VMS_VERSION), buf),
X# endif
X#else
X "VMS",
X "",
X#endif /* ?VMS_VERSION */
X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X
X} /* end function version() */
X
X#endif /* !SFX */
X#endif /* VMS */
END_OF_FILE
if test 66172 -ne `wc -c <'unzip-5.12/vms/vms.c'`; then
echo shar: \"'unzip-5.12/vms/vms.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/vms.c'
fi
echo shar: End of archive 3 \(of 20\).
cp /dev/null ark3isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:14:35 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 69
Archive-name: unzip/part04

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/amiga/makefile.azt unzip-5.12/zipinfo.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:37 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 4 (of 20)."'
if test -f 'unzip-5.12/amiga/makefile.azt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/makefile.azt'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/makefile.azt'\" \(2163 characters\)
sed "s/^X//" >'unzip-5.12/amiga/makefile.azt' <<'END_OF_FILE'
X# Makefile for UnZip 5.11+ using Manx Aztec C 5.2 10 July 1994
X#
X# You may need to change directory names for stat.c, filedate.c and amiga.c.
X
X
XCC = cc
XCFLAGS = -d AMIGA -ps -sabfmnpu -wcpr0u
X# -ps means short ints, -s... is optimizations, -w... is type checking
XLD = ln
XLDFLAGS = +q -m
XLDLIBS = -lc16
X
XOBJS = unzip.o crypt.o envargs.o explode.o unshrink.o \
X extract.o zipinfo.o file_io.o inflate.o match.o unreduce.o \
X amiga/amiga.o amiga/crc_68.o amiga/flate.o
XXOBJS = unzip.xo crypt.o extract.xo file_io.o inflate.o amiga/flate.o \
X match.o amiga/amiga.xo
XFOBJS = funzip.o crypt.fo inflate.fo amiga/flate.fo
X
X
X.c.o :
X $(CC) -o $@ $(CFLAGS) $*.c
X
X.c.xo:
X $(CC) -o $@ -d SFX $(CFLAGS) $*.c
X
X.c.fo:
X $(CC) -o $@ -d FUNZIP $(CFLAGS) $*.c
X
XUnZip : $(OBJS)
X $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
X
XUnZipSFX : $(FOBJS)
X $(LD) $(LDFLAGS) -o $@ $(FOBJS) $(LDLIBS)
X
XfUnZip : $(FOBJS)
X $(LD) $(LDFLAGS) -o $@ $(XOBJS) $(LDLIBS)
X
Xf : fUnZip
X
Xall : UnZip UnZipSFX fUnZip
X
Xclean :
X delete #?.(o|xo|fo) quiet
X
X
X$(OBJS) $(XOBJS) $(FOBJS) : unzip.h amiga/amiga.h amiga/z-stat.h
X
Xcrypt.o crypt.fo : zip.h
X
Xinflate.o inflate.fo : inflate.h
X
Xfile_io.o funzip.o : tables.h
X
Xcrypt.o crypt.fo unzip.o unzip.xo funzip.o file_io.o : crypt.h
Xextract.o extract.xo inflate.o inflate.fo : crypt.h
X
Xunzip.o unzip.xo : version.h
X
Xfile_io.o : file_io.c
X $(CC) -o file_io.o $(CFLAGS) -d ASM_CRC file_io.c
X
Xinflate.o : inflate.c
X $(CC) -o inflate.o $(CFLAGS) -d ASM_INFLATECODES inflate.c
X
Xinflate.fo : inflate.c
X $(CC) -o inflate.fo $(CFLAGS) -d FUNZIP -d ASM_INFLATECODES inflate.c
X
Xamiga/amiga.o : amiga/filedate.c amiga/stat.c amiga/amiga.c
X $(CC) -o amiga/amiga.o -d __VERSION__=5 -d __REVISION__=2 \
X $(CFLAGS) amiga/amiga.c
X
Xamiga/amiga.xo : amiga/filedate.c amiga/stat.c amiga/amiga.c
X $(CC) -o amiga/amiga.xo -d __VERSION__=5 -d __REVISION__=2 -d SFX \
X $(CFLAGS) amiga/amiga.c
X
Xamiga/crc_68.o : amiga/crc_68.a
X as -n -o amiga/crc_68.o -eREGARGS amiga/crc_68.a
X
Xamiga/flate.o : amiga/flate.a
X as -n -o amiga/flate.o amiga/flate.a
X
Xamiga/flate.fo : amiga/flate.a
X as -n -o amiga/flate.fo -eCRYPT -eFUNZIP amiga/flate.a
END_OF_FILE
if test 2163 -ne `wc -c <'unzip-5.12/amiga/makefile.azt'`; then
echo shar: \"'unzip-5.12/amiga/makefile.azt'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/makefile.azt'
fi
if test -f 'unzip-5.12/zipinfo.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/zipinfo.c'\"
else
echo shar: Extracting \"'unzip-5.12/zipinfo.c'\" \(64797 characters\)
sed "s/^X//" >'unzip-5.12/zipinfo.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X zipinfo.c
X
X This file contains all of the zipfile-listing routines for UnZip, inclu-
X ding the bulk of what used to be the separate program ZipInfo. All of
X the ZipInfo routines are by Greg Roelofs; list_files is by the usual mish-
X mash of Info-ZIP contributors (see the listing in CONTRIBS).
X
X Contains: zi_opts()
X zi_end_central()
X zipinfo()
X zi_long()
X zi_short()
X zi_time()
X list_files()
X ratio()
X fnprint()


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
X
Xstatic char unkn[16];
X
Xstatic int ratio OF((ulg uc, ulg c));
Xstatic void fnprint OF((void));
X
X
X/********************************************/
X/* Strings used in zipinfo.c (UnZip half) */
X/********************************************/
X
X/* also referenced in UpdateListBox() in updatelb.c (Windows version) */
Xchar Far HeadersS[] = " Length Date Time Name";
Xchar Far HeadersS1[] = " ------ ---- ---- ----";
Xchar Far HeadersL[] = " Length Method Size Ratio Date Time CRC-32 Name";
Xchar Far HeadersL1[] = " ------ ------ ---- ----- ---- ---- ------ ----";
Xchar Far *Headers[][2] = { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
X
Xstatic char Far CaseConversion[] = "%s (\"^\" ==> case\n%s conversion)\n";
Xstatic char Far CompFactorStr[] = "%c%d%%";
Xstatic char Far CompMethodUnknown[] = "Unk:%03d";
X#ifdef MSWIN
X static char Far LongHdrStats[] =
X "%7lu %-7s%7lu %4s %02u-%02u-%02u %02u:%02u %08lx %c%s";
X static char Far LongFileHeader[] =
X "%7lu %7lu %4s %-7u";
X static char Far ShortHdrStats[] = "%7lu %02u-%02u-%02u %02u:%02u %c%s";
X static char Far ShortFileHeader[] = "%7lu %-7u";
X#else /* !MSWIN */
X static char Far LongHdrStats[] =
X "%7lu %-7s%7lu %4s %02u-%02u-%02u %02u:%02u %08lx %c";
X static char Far ShortHdrStats[] = "%7lu %02u-%02u-%02u %02u:%02u %c";
X static char Far LongFileHeader[] =
X " ------ ------ --- \
X -------\n%7lu %7lu %4s %-7u\n";
X static char Far ShortFileHeader[] =
X " ------ -------\n%7lu %-7u\n";
X#endif /* ?MSWIN */
X
X
X
X#ifndef NO_ZIPINFO /* strings use up too much space in small-memory systems */
X
X/* Define OS-specific attributes for use on ALL platforms--the S_xxxx
X * versions of these are defined differently (or not defined) by different
X * compilers and operating systems. */
X
X#define UNX_IFMT 0170000 /* Unix file type mask */
X#define UNX_IFDIR 0040000 /* Unix directory */
X#define UNX_IFREG 0100000 /* Unix regular file */
X#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
X#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
X#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
X#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
X#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
X#define UNX_ISUID 04000 /* Unix set user id on execution */
X#define UNX_ISGID 02000 /* Unix set group id on execution */
X#define UNX_ISVTX 01000 /* Unix directory permissions control */
X#define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */
X#define UNX_IRWXU 00700 /* Unix read, write, execute: owner */
X#define UNX_IRUSR 00400 /* Unix read permission: owner */
X#define UNX_IWUSR 00200 /* Unix write permission: owner */
X#define UNX_IXUSR 00100 /* Unix execute permission: owner */
X#define UNX_IRWXG 00070 /* Unix read, write, execute: group */
X#define UNX_IRGRP 00040 /* Unix read permission: group */
X#define UNX_IWGRP 00020 /* Unix write permission: group */
X#define UNX_IXGRP 00010 /* Unix execute permission: group */
X#define UNX_IRWXO 00007 /* Unix read, write, execute: other */
X#define UNX_IROTH 00004 /* Unix read permission: other */
X#define UNX_IWOTH 00002 /* Unix write permission: other */
X#define UNX_IXOTH 00001 /* Unix execute permission: other */
X
X#define VMS_IRUSR UNX_IRUSR /* VMS read/owner */
X#define VMS_IWUSR UNX_IWUSR /* VMS write/owner */
X#define VMS_IXUSR UNX_IXUSR /* VMS execute/owner */
X#define VMS_IRGRP UNX_IRGRP /* VMS read/group */
X#define VMS_IWGRP UNX_IWGRP /* VMS write/group */
X#define VMS_IXGRP UNX_IXGRP /* VMS execute/group */
X#define VMS_IROTH UNX_IROTH /* VMS read/other */
X#define VMS_IWOTH UNX_IWOTH /* VMS write/other */
X#define VMS_IXOTH UNX_IXOTH /* VMS execute/other */
X
X#define AMI_IFMT 06000 /* Amiga file type mask */
X#define AMI_IFDIR 04000 /* Amiga directory */
X#define AMI_IFREG 02000 /* Amiga regular file */
X#define AMI_IHIDDEN 00200 /* to be supported in AmigaDOS 3.x */
X#define AMI_ISCRIPT 00100 /* executable script (text command file) */
X#define AMI_IPURE 00040 /* allow loading into resident memory */
X#define AMI_IARCHIVE 00020 /* not modified since bit was last set */
X#define AMI_IREAD 00010 /* can be opened for reading */
X#define AMI_IWRITE 00004 /* can be opened for writing */
X#define AMI_IEXECUTE 00002 /* executable image, a loadable runfile */
X#define AMI_IDELETE 00001 /* can be deleted */
X
X/* extra-field ID values: */
X#define EF_AV 0x0007 /* PKWARE authenticity verification */
X#define EF_OS2 0x0009 /* OS/2 extended attributes */
X#define EF_PKVMS 0x000c /* PKWARE's VMS ID */
X#define EF_IZVMS 0x4d49 /* Info-ZIP's VMS ID ("IM") */
X#define EF_ASIUNIX 0x756e /* ASi/PKWARE's Unix ID ("IM") */
X#define EF_SPARK 0x4341 /* David Pilling's Acorn/SparkFS ID ("AC") */
X
X#define LFLAG 3 /* short "ls -l" type listing */
X
Xstatic int zi_long OF((void));
Xstatic int zi_short OF((void));
Xstatic char *zi_time OF((ush *datez, ush *timez));
X
X
X/**********************************************/
X/* Strings used in zipinfo.c (ZipInfo half) */
X/**********************************************/
X
Xstatic char Far LongHeader[] = "Archive: %s %ld bytes %d file%s\n";
Xstatic char Far ShortHeader[] = "Archive: %s %ld %d\n";
Xstatic char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n";
Xstatic char Far LineSeparators[] = "-------------------------------\n\n";
Xstatic char Far ActOffsetCentDir[] = "\
X Actual offset of end-of-central-dir record: %9ld (%.8lXh)\n\
X Expected offset of end-of-central-dir record: %9ld (%.8lXh)\n\
X (based on the length of the central directory and its expected offset)\n\n";
Xstatic char Far SinglePartArchive[] = "\
X This zipfile constitutes the sole disk of a single-part archive; its\n\
X central directory contains %u %s. The central directory is %lu\n\
X (%.8lXh) bytes long, and its (expected) offset in bytes from the\n\
X beginning of the zipfile is %lu (%.8lXh).\n\n";
Xstatic char Far MultiPartArchive[] = "\
X This zipfile constitutes disk %u of a multi-part archive. The central\n\
X directory starts on disk %u; %u of its entries %s contained within\n\
X this zipfile, out of a total of %u %s. The entire central\n\
X directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n\
X the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n";
Xstatic char Far NoZipfileComment[] = " There is no zipfile comment.\n";
Xstatic char Far ZipfileCommentDesc[] =
X " The zipfile comment is %u bytes long and contains the following text:\n\n";
Xstatic char Far ZipfileCommBegin[] =
X "======================== zipfile comment begins ==========================\n";
Xstatic char Far ZipfileCommEnd[] =
X "========================= zipfile comment ends ===========================\n";
Xstatic char Far ZipfileCommTrunc2[] = "\n The zipfile comment is truncated.\n";
Xstatic char Far ZipfileCommTruncMsg[] =
X "\ncaution: zipfile comment truncated\n";
X
X#ifdef T20_VMS
X static char Far CentralDirEntry[] = "\nCentral directory entry #%d:\n";
X#else
X static char Far CentralDirEntry[] = "%s\nCentral directory entry #%d:\n";
X#endif
X
Xstatic char Far CentralDirLines[] = "---------------------------\n\n";
Xstatic char Far ZipfileStats[] =
X "%d file%s, %lu bytes uncompressed, %lu bytes compressed: %s%d.%d%%\n";
X
X/* zi_long() strings */
Xstatic char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT";
Xstatic char Far OS_Amiga[] = "Amiga";
Xstatic char Far OS_VAXVMS[] = "VAX VMS";
Xstatic char Far OS_Unix[] = "Unix";
Xstatic char Far OS_VMCMS[] = "VM/CMS";
Xstatic char Far OS_AtariST[] = "Atari ST";
Xstatic char Far OS_HPFS[] = "OS/2 or NT HPFS";
Xstatic char Far OS_Macintosh[] = "Macintosh";
Xstatic char Far OS_ZSystem[] = "Z-System";
Xstatic char Far OS_CPM[] = "CP/M";
Xstatic char Far OS_TOPS20[] = "TOPS-20";
Xstatic char Far OS_NTFS[] = "NT NTFS";
Xstatic char Far OS_QDOS[] = "QDOS (maybe)";
Xstatic char Far OS_Acorn[] = "Acorn RISCOS";
X
Xstatic char Far MthdNone[] = "none (stored)";
Xstatic char Far MthdShrunk[] = "shrunk";
Xstatic char Far MthdRedF1[] = "reduced (factor 1)";
Xstatic char Far MthdRedF2[] = "reduced (factor 2)";
Xstatic char Far MthdRedF3[] = "reduced (factor 3)";
Xstatic char Far MthdRedF4[] = "reduced (factor 4)";
Xstatic char Far MthdImplode[] = "imploded";
Xstatic char Far MthdToken[] = "tokenized";
Xstatic char Far MthdDeflate[] = "deflated";
X
Xstatic char Far ExtraBytesPreceding[] =
X " There are an extra %ld bytes preceding this file.\n\n";
X
Xstatic char Far Unknown[] = "unknown (%d)";
X
Xstatic char Far HostOS[] =
X "\n host operating system (created on): %s\n";
Xstatic char Far EncodeSWVer[] =
X " version of encoding software: %d.%d\n";
Xstatic char Far MinOSCompReq[] =
X " minimum operating system compatibility required: %s\n";
Xstatic char Far MinSWVerReq[] =
X " minimum software version required to extract: %d.%d\n";
Xstatic char Far CompressMethod[] =
X " compression method: %s\n";
Xstatic char Far SlideWindowSizeImplode[] =
X " size of sliding dictionary (implosion): %cK\n";
Xstatic char Far ShannonFanoTrees[] =
X " number of Shannon-Fano trees (implosion): %c\n";
Xstatic char Far CompressSubtype[] =
X " compression sub-type (deflation): %s\n";
Xstatic char Far FileSecurity[] =
X " file security status: %sencrypted\n";
Xstatic char Far ExtendedLocalHdr[] =
X " extended local header: %s\n";
Xstatic char Far FileModDate[] =
X " file last modified on: %s\n";
Xstatic char Far CRC32Value[] =
X " 32-bit CRC value (hex): %.8lx\n";
Xstatic char Far CompressedFileSize[] =
X " compressed size: %lu bytes\n";
Xstatic char Far UncompressedFileSize[] =
X " uncompressed size: %lu bytes\n";
Xstatic char Far FilenameLength[] =
X " length of filename: %u characters\n";
Xstatic char Far ExtraFieldLength[] =
X " length of extra field: %u bytes\n";
Xstatic char Far FileCommentLength[] =
X " length of file comment: %u characters\n";
Xstatic char Far FileDiskNum[] =
X " disk number on which file begins: disk %u\n";
Xstatic char Far ApparentFileType[] =
X " apparent file type: %s\n";
Xstatic char Far VMSFileAttributes[] =
X " VMS file attributes (%06o octal): %s\n";
Xstatic char Far AmigaFileAttributes[] =
X " Amiga file attributes (%06o octal): %s\n";
Xstatic char Far UnixFileAttributes[] =
X " Unix file attributes (%06o octal): %s\n";
Xstatic char Far NonMSDOSFileAttributes[] =
X " non-MSDOS external file attributes: %06lX hex\n";
Xstatic char Far MSDOSFileAttributes[] =
X " MS-DOS file attributes (%02X hex): none\n";
Xstatic char Far MSDOSFileAttributesRO[] =
X " MS-DOS file attributes (%02X hex): read-only\n";
Xstatic char Far MSDOSFileAttributesAlpha[] =
X " MS-DOS file attributes (%02X hex): %s%s%s%s%s%s\n";
Xstatic char Far LocalHeaderOffset[] =
X " offset of local header from start of archive: %lu (%.8lXh) bytes\n";
Xstatic char Far ExtraFieldType[] = "\n\
X The central-directory extra field has ID 0x%04x (%s) and has %u\n\
X data bytes";
Xstatic char Far OS2EAs[] = "\
X. The local extra field has %lu bytes of OS/2 extended\n\
X attributes (may not match OS/2 \"dir\" amount due to storage method).";
Xstatic char Far First16[] = ". The first 16 are%s";
Xstatic char Far ColonIndent[] = ":\n ";
Xstatic char Far efFormat[] = " %02x";
Xstatic char Far efAV[] = "PKWARE AV";
Xstatic char Far efOS2[] = "OS/2";
Xstatic char Far efPKVMS[] = "PKWARE VMS";
Xstatic char Far efIZVMS[] = "Info-ZIP VMS";
Xstatic char Far efASiUnix[] = "ASi Unix";
X/* static char Far efIZUnix[] = "Info-ZIP Unix"; */
Xstatic char Far efSpark[] = "Acorn SparkFS";
Xstatic char Far efUnknown[] = "unknown";
Xstatic char Far NoFileComment[] = "\n There is no file comment.\n";
Xstatic char Far FileCommBegin[] = "\n\
X------------------------- file comment begins ----------------------------\n";
Xstatic char Far FileCommEnd[] = "\
X-------------------------- file comment ends -----------------------------\n";
Xstatic char Far JanMonth[] = "Jan";
Xstatic char Far FebMonth[] = "Feb";
Xstatic char Far MarMonth[] = "Mar";
Xstatic char Far AprMonth[] = "Apr";
Xstatic char Far MayMonth[] = "May";
Xstatic char Far JunMonth[] = "Jun";
Xstatic char Far JulMonth[] = "Jul";
Xstatic char Far AugMonth[] = "Aug";
Xstatic char Far SepMonth[] = "Sep";
Xstatic char Far OctMonth[] = "Oct";
Xstatic char Far NovMonth[] = "Nov";
Xstatic char Far DecMonth[] = "Dec";
Xstatic char Far BogusFmt[] = "%03d";
Xstatic char Far DMYHMTime[] = "%2u-%s-%02u %02u:%02u";
Xstatic char Far YMDHMSTime[] = "%u %s %u %02u:%02u:%02u";
Xstatic char Far DecimalTime[] = "%02u%02u%02u.%02u%02u%02u";


X
X
X
X
X

X/************************/
X/* Function zi_opts() */
X/************************/
X
Xint zi_opts(pargc, pargv)


X int *pargc;
X char ***pargv;
X{
X char **argv, *s;
X int argc, c, error=FALSE, negative=0;

X int hflag_slmv=TRUE, hflag_2=FALSE; /* diff options => diff defaults */
X int tflag_slm=TRUE, tflag_2v=FALSE;
X int explicit_h=FALSE, explicit_t=FALSE;
X
X
X#ifdef MACOS
X lflag = LFLAG; /* reset default on each call */
X#endif


X argc = *pargc;
X argv = *pargv;
X
X while (--argc > 0 && (*++argv)[0] == '-') {
X s = argv[0] + 1;
X while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
X switch (c) {

X case '-':
X ++negative;
X break;
X case '1': /* shortest listing: JUST filenames */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 1;
X break;
X case '2': /* just filenames, plus headers if specified */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 2;
X break;
X case 'h': /* header line */
X if (negative)
X hflag_2 = hflag_slmv = FALSE, negative = 0;
X else {
X hflag_2 = hflag_slmv = explicit_h = TRUE;
X if (lflag == -1)
X lflag = 0;
X }
X break;
X case 'l': /* longer form of "ls -l" type listing */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 5;
X break;
X case 'm': /* medium form of "ls -l" type listing */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 4;
X break;
X case 's': /* default: shorter "ls -l" type listing */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 3;
X break;
X case 't': /* totals line */
X if (negative)
X tflag_2v = tflag_slm = FALSE, negative = 0;
X else {
X tflag_2v = tflag_slm = explicit_t = TRUE;
X if (lflag == -1)
X lflag = 0;
X }
X break;
X case ('T'): /* use (sortable) decimal time format */
X if (negative)
X T_flag = FALSE, negative = 0;
X else
X T_flag = TRUE;
X break;
X case 'v': /* turbo-verbose listing */
X if (negative)
X lflag = -2, negative = 0;
X else
X lflag = 10;
X break;
X case 'z': /* print zipfile comment */
X if (negative)
X zflag = negative = 0;
X else
X zflag = 1;
X break;
X case 'Z': /* ZipInfo mode: ignore */
X break;
X default:
X error = TRUE;


X break;
X }
X }
X }

X if ((argc-- == 0) || error) {


X *pargc = argc;
X *pargv = argv;

X return usage(error);
X }
X
X /* if no listing options given (or all negated), or if only -h/-t given
X * with individual files specified, use default listing format */
X if ((lflag < 0) || ((argc > 0) && (lflag == 0)))
X lflag = LFLAG;
X
X /* set header and totals flags to default or specified values */
X switch (lflag) {
X case 0: /* 0: can only occur if either -t or -h explicitly given; */
X case 2: /* therefore set both flags equal to normally false value */
X hflag = hflag_2;
X tflag = tflag_2v;
X break;
X case 1: /* only filenames, *always* */
X hflag = FALSE;
X tflag = FALSE;
X zflag = FALSE;
X break;
X case 3:
X case 4:
X case 5:
X hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
X tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
X break;
X case 10:
X hflag = hflag_slmv;
X tflag = tflag_2v;
X break;
X }
X


X *pargc = argc;
X *pargv = argv;

X return 0;
X
X} /* end function zi_opts() */


X
X
X
X
X

X/*******************************/
X/* Function zi_end_central() */
X/*******************************/
X
Xint zi_end_central() /* return PK-type error code */


X{
X int error = PK_COOL;
X
X
X/*---------------------------------------------------------------------------

X Print out various interesting things about the zipfile.
X ---------------------------------------------------------------------------*/
X
X /* header fits on one line, for anything up to 10GB and 10000 files: */
X if (hflag)
X PRINTF(((int)strlen(zipfn) < 39)?
X LoadFarString(LongHeader) :
X LoadFarString(ShortHeader), zipfn, (long)ziplen,
X ecrec.total_entries_central_dir,
X (ecrec.total_entries_central_dir==1)? "":"s");
X
X /* verbose format */
X if (lflag > 9) {
X PRINTF(LoadFarString(EndCentDirRec));
X PRINTF(LoadFarString(LineSeparators));
X
X PRINTF(LoadFarString(ActOffsetCentDir),
X (long)real_ecrec_offset, (long)real_ecrec_offset,
X (long)expect_ecrec_offset, (long)expect_ecrec_offset);
X
X if (ecrec.number_this_disk == 0) {
X PRINTF(LoadFarString(SinglePartArchive),
X ecrec.total_entries_central_dir,
X (ecrec.total_entries_central_dir == 1)? "entry" : "entries",
X ecrec.size_central_directory, ecrec.size_central_directory,
X ecrec.offset_start_central_directory,
X ecrec.offset_start_central_directory);
X } else {
X PRINTF(LoadFarString(MultiPartArchive),
X ecrec.number_this_disk,
X ecrec.num_disk_with_start_central_dir,
X ecrec.num_entries_centrl_dir_ths_disk,
X (ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are",
X ecrec.total_entries_central_dir,
X (ecrec.total_entries_central_dir == 1) ? "entry" : "entries",
X ecrec.size_central_directory, ecrec.size_central_directory,
X ecrec.offset_start_central_directory,
X ecrec.offset_start_central_directory);
X }
X
X /*-----------------------------------------------------------------------
X Get the zipfile comment, if any, and print it out. (Comment may be
X up to 64KB long. May the fleas of a thousand camels infest the arm-
X pits of anyone who actually takes advantage of this fact.)
X -----------------------------------------------------------------------*/
X
X if (!ecrec.zipfile_comment_length)
X PRINTF(LoadFarString(NoZipfileComment));
X else {
X PRINTF(LoadFarString(ZipfileCommentDesc),
X ecrec.zipfile_comment_length );
X PRINTF(LoadFarString(ZipfileCommBegin));
X if (do_string(ecrec.zipfile_comment_length, DISPLAY))
X error = PK_WARN;
X PRINTF(LoadFarString(ZipfileCommEnd));
X if (error)
X PRINTF(LoadFarString(ZipfileCommTrunc2));
X } /* endif (comment exists) */
X
X /* non-verbose mode: print zipfile comment only if requested */
X } else if (zflag && ecrec.zipfile_comment_length) {
X if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
X FPRINTF(stderr, LoadFarString(ZipfileCommTruncMsg));


X error = PK_WARN;
X }

X } /* endif (verbose) */


X
X return error;
X

X} /* end function zi_end_central() */


X
X
X
X
X

X/************************/
X/* Function zipinfo() */
X/************************/
X
Xint zipinfo() /* return PK-type error code */
X{
X int j, do_this_file=FALSE, error, error_in_archive=PK_COOL;
X int *fn_matched=NULL, *xn_matched=NULL;
X ush members=0;
X ulg tot_csize=0L, tot_ucsize=0L;
X
X
X/*---------------------------------------------------------------------------
X Malloc space for check on unmatched filespecs (no big deal if one or both
X are NULL).
X ---------------------------------------------------------------------------*/
X
X if (filespecs > 0 &&
X (fn_matched=(int *)malloc(filespecs*sizeof(int))) != NULL)
X for (j = 0; j < filespecs; ++j)
X fn_matched[j] = FALSE;
X
X if (xfilespecs > 0 &&
X (xn_matched=(int *)malloc(xfilespecs*sizeof(int))) != NULL)
X for (j = 0; j < xfilespecs; ++j)
X xn_matched[j] = FALSE;
X
X/*---------------------------------------------------------------------------
X Set file pointer to start of central directory, then loop through cen-
X tral directory entries. Check that directory-entry signature bytes are
X actually there (just a precaution), then process the entry. We know
X the entire central directory is on this disk: we wouldn't have any of
X this information unless the end-of-central-directory record was on this
X disk, and we wouldn't have gotten to this routine unless this is also
X the disk on which the central directory starts. In practice, this had
X better be the *only* disk in the archive, but maybe someday we'll add
X multi-disk support.
X ---------------------------------------------------------------------------*/
X
X pInfo->lcflag = 0; /* used in do_string(): never TRUE in zipinfo mode */
X pInfo->textmode = 0; /* so one can read on screen (but is it ever used?) */
X newzip = TRUE; /* for zi_long() check of extra bytes */
X
X for (j = 0; j < (int)ecrec.total_entries_central_dir; ++j) {


X if (readbuf(sig, 4) == 0)

X return PK_EOF;
X if (strncmp(sig, central_hdr_sig, 4)) { /* just to make sure */
X FPRINTF(stderr, LoadFarString(CentSigMsg), j); /* sig not found */
X return PK_BADERR;
X }
X if ((error = get_cdir_ent()) != PK_COOL)
X return error; /* only PK_EOF defined */


X
X /* do Amigas (AMIGA_) also have volume labels? */
X if (IS_VOLID(crec.external_file_attributes) &&
X (pInfo->hostnum == FS_FAT_ || pInfo->hostnum == FS_HPFS_ ||
X pInfo->hostnum == FS_NTFS_ || pInfo->hostnum == ATARI_))

X pInfo->vollabel = TRUE;

X else
X pInfo->vollabel = FALSE;

X
X if ((error = do_string(crec.filename_length, FILENAME)) != PK_COOL) {
X error_in_archive = error; /* might be warning */
X if (error > PK_WARN) /* fatal */


X return error;
X }
X

X if (!process_all_files) { /* check if specified on command line */
X char **pfn = pfnames-1;
X
X do_this_file = FALSE;
X while (*++pfn)
X if (match(filename, *pfn, 0)) {
X do_this_file = TRUE;
X if (fn_matched)
X fn_matched[pfn-pfnames] = TRUE;
X break; /* found match, so stop looping */
X }
X if (do_this_file) { /* check if this is an excluded file */
X char **pxn = pxnames-1;
X
X while (*++pxn)
X if (match(filename, *pxn, 0)) {
X do_this_file = FALSE;
X if (xn_matched)
X xn_matched[pxn-pxnames] = TRUE;
X break;
X }
X }
X }
X
X /*-----------------------------------------------------------------------
X If current file was specified on command line, or if no names were
X specified, do the listing for this file. Otherwise, get rid of the
X file comment and go back for the next file.
X -----------------------------------------------------------------------*/
X
X if (process_all_files || do_this_file) {
X
X switch (lflag) {
X case 1:
X case 2:
X fnprint();
X SKIP_(crec.extra_field_length)
X SKIP_(crec.file_comment_length)
X break;
X
X case 3:
X case 4:
X case 5:
X if ((error = zi_short()) != PK_COOL) {
X error_in_archive = error; /* might be warning */
X if (error > PK_WARN) /* fatal */
X return error;
X }
X break;
X
X case 10:
X#ifdef T20_VMS /* GRR: add cbreak-style "more" */
X PRINTF(LoadFarString(CentralDirEntry), j);
X#else
X /* formfeed/CR for piping to "more": */
X PRINTF(LoadFarString(CentralDirEntry), "\014", j);
X#endif
X PRINTF(LoadFarString(CentralDirLines));
X
X if ((error = zi_long()) != PK_COOL) {
X error_in_archive = error; /* might be warning */
X if (error > PK_WARN) /* fatal */
X return error;
X }


X break;
X
X default:

X SKIP_(crec.extra_field_length)
X SKIP_(crec.file_comment_length)
X break;
X
X } /* end switch (lflag) */
X
X tot_csize += crec.csize;
X tot_ucsize += crec.ucsize;
X if (crec.general_purpose_bit_flag & 1)
X tot_csize -= 12; /* don't count encryption header */
X ++members;
X
X } else { /* not listing */
X SKIP_(crec.extra_field_length)
X SKIP_(crec.file_comment_length)
X
X } /* end if (list member?) */
X
X } /* end for-loop (j: member files) */
X
X/*---------------------------------------------------------------------------
X Double check that we're back at the end-of-central-directory record.
X ---------------------------------------------------------------------------*/
X
X if (readbuf(sig, 4) == 0) /* disk error? */
X return PK_EOF;
X if (strncmp(sig, end_central_sig, 4)) { /* just to make sure again */
X FPRINTF(stderr, LoadFarString(EndSigMsg)); /* didn't find sig */


X error_in_archive = PK_WARN;
X }
X

X/*---------------------------------------------------------------------------
X Check that we actually found requested files; if so, print totals.
X ---------------------------------------------------------------------------*/
X
X if (tflag) {
X char *sgn = "";
X int cfactor = ratio(tot_ucsize, tot_csize);
X
X if (cfactor < 0) {
X sgn = "-";
X cfactor = -cfactor;
X }
X PRINTF(LoadFarString(ZipfileStats),
X members, (members==1)? "":"s", tot_ucsize, tot_csize, sgn, cfactor/10,
X cfactor%10);
X }
X
X/*---------------------------------------------------------------------------
X Check for unmatched filespecs on command line and print warning if any
X found.
X ---------------------------------------------------------------------------*/
X
X if (fn_matched) {
X for (j = 0; j < filespecs; ++j)
X if (!fn_matched[j])
X FPRINTF(stderr, LoadFarString(FilenameNotMatched),
X pfnames[j]);
X free(fn_matched);
X }
X if (xn_matched) {
X for (j = 0; j < xfilespecs; ++j)
X if (!xn_matched[j])
X FPRINTF(stderr, LoadFarString(ExclFilenameNotMatched),
X pxnames[j]);
X free(xn_matched);
X }
X if (members == 0 && error_in_archive <= PK_WARN)
X error_in_archive = PK_FIND;
X
X return error_in_archive;
X
X} /* end function zipinfo() */


X
X
X
X
X

X#define OS_unkn unkn
X
X/************************/
X/* Function zi_long() */
X/************************/
X
Xstatic int zi_long() /* return PK-type error code */
X{
X int error, error_in_archive=PK_COOL;
X ush hostnum, hostver, extnum, extver, methnum, xattr;
X char workspace[12], attribs[22];
X static char meth_unkn[16];
X static char Far *os[NUM_HOSTS+1] = {
X OS_FAT, OS_Amiga, OS_VAXVMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS,
X OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS,
X OS_Acorn, OS_unkn
X };
X static char Far *method[NUM_METHODS+1] = {
X MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4,
X MthdImplode, MthdToken, MthdDeflate, meth_unkn
X };
X static char *dtype[4] = {"normal", "maximum", "fast", "superfast"};
X static ulg endprev;
X
X
X/*---------------------------------------------------------------------------
X Check whether there's any extra space inside the zipfile.
X ---------------------------------------------------------------------------*/
X
X if (newzip) { /* reset if new zipfile; account for multi-part archives */
X endprev = (crec.relative_offset_local_header == 4L)? 4L : 0L;
X newzip = FALSE;
X }
X
X if (crec.relative_offset_local_header != endprev)
X PRINTF(LoadFarString(ExtraBytesPreceding),
X (long)crec.relative_offset_local_header - (long)endprev);
X
X /* calculate endprev for next time around */
X endprev = crec.relative_offset_local_header + 4L + LREC_SIZE +
X crec.filename_length + crec.extra_field_length + crec.file_comment_length
X + crec.csize;
X
X/*---------------------------------------------------------------------------
X Print out various interesting things about the compressed file.
X ---------------------------------------------------------------------------*/
X
X hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
X hostver = crec.version_made_by[0];
X extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS);
X extver = crec.version_needed_to_extract[0];
X methnum = MIN(crec.compression_method, NUM_METHODS);
X
X if (hostnum == NUM_HOSTS)
X sprintf(OS_unkn, LoadFarString(Unknown), (int)crec.version_made_by[1]);
X if (methnum == NUM_METHODS)
X sprintf(meth_unkn, LoadFarString(Unknown), crec.compression_method);
X
X PRINTF(" "); fnprint();
X
X PRINTF(LoadFarString(HostOS), LoadFarStringSmall(os[hostnum]));
X PRINTF(LoadFarString(EncodeSWVer), hostver/10, hostver%10);
X PRINTF(LoadFarString(MinOSCompReq), LoadFarStringSmall(os[extnum]));
X PRINTF(LoadFarString(MinSWVerReq), extver/10, extver%10);
X PRINTF(LoadFarString(CompressMethod), LoadFarStringSmall(method[methnum]));
X if (methnum == IMPLODED) {
X PRINTF(LoadFarString(SlideWindowSizeImplode),
X (crec.general_purpose_bit_flag & 2)? '8' : '4');
X PRINTF(LoadFarString(ShannonFanoTrees),
X (crec.general_purpose_bit_flag & 4)? '3' : '2');
X } else if (methnum == DEFLATED) {
X ush dnum=(crec.general_purpose_bit_flag>>1) & 3;
X PRINTF(LoadFarString(CompressSubtype), dtype[dnum]);
X }
X PRINTF(LoadFarString(FileSecurity),
X (crec.general_purpose_bit_flag & 1)? "" : "not ");
X PRINTF(LoadFarString(ExtendedLocalHdr),
X (crec.general_purpose_bit_flag & 8)? "yes" : "no");
X /* print upper 3 bits for amusement? */
X PRINTF(LoadFarString(FileModDate),
X zi_time(&crec.last_mod_file_date, &crec.last_mod_file_time));
X PRINTF(LoadFarString(CRC32Value), crec.crc32);
X PRINTF(LoadFarString(CompressedFileSize), crec.csize);
X PRINTF(LoadFarString(UncompressedFileSize), crec.ucsize);
X PRINTF(LoadFarString(FilenameLength), crec.filename_length);
X PRINTF(LoadFarString(ExtraFieldLength), crec.extra_field_length);
X PRINTF(LoadFarString(FileCommentLength), crec.file_comment_length);
X PRINTF(LoadFarString(FileDiskNum), crec.disk_number_start);
X PRINTF(LoadFarString(ApparentFileType),
X (crec.internal_file_attributes & 1)? "text" : "binary");
X/*
X PRINTF(" external file attributes (hex): %.8lx\n",
X crec.external_file_attributes);
X */
X xattr = (ush)((crec.external_file_attributes >> 16) & 0xFFFF);
X if (hostnum == VMS_) {
X char *p=attribs, *q=attribs+1;
X int i, j, k;
X
X for (k = 0; k < 12; ++k)
X workspace[k] = 0;
X if (xattr & VMS_IRUSR)
X workspace[0] = 'R';
X if (xattr & VMS_IWUSR) {
X workspace[1] = 'W';
X workspace[3] = 'D';
X }
X if (xattr & VMS_IXUSR)
X workspace[2] = 'E';
X if (xattr & VMS_IRGRP)
X workspace[4] = 'R';
X if (xattr & VMS_IWGRP) {
X workspace[5] = 'W';
X workspace[7] = 'D';
X }
X if (xattr & VMS_IXGRP)
X workspace[6] = 'E';
X if (xattr & VMS_IROTH)
X workspace[8] = 'R';
X if (xattr & VMS_IWOTH) {
X workspace[9] = 'W';
X workspace[11] = 'D';
X }
X if (xattr & VMS_IXOTH)
X workspace[10] = 'E';
X
X *p++ = '(';
X for (k = j = 0; j < 3; ++j) { /* loop over groups of permissions */
X for (i = 0; i < 4; ++i, ++k) /* loop over perms within a group */
X if (workspace[k])
X *p++ = workspace[k];
X *p++ = ','; /* group separator */
X if (j == 0)
X while ((*p++ = *q++) != ','); /* system, owner perms are same */
X }
X *p-- = 0;
X *p = ')'; /* overwrite last comma */
X PRINTF(LoadFarString(VMSFileAttributes), xattr, attribs);
X
X } else if (hostnum == AMIGA_) {
X switch (xattr & AMI_IFMT) {
X case AMI_IFDIR: attribs[0] = 'd'; break;
X case AMI_IFREG: attribs[0] = '-'; break;
X default: attribs[0] = '?'; break;
X }
X attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-';
X attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-';
X attribs[3] = (xattr & AMI_IPURE)? 'p' : '-';
X attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-';
X attribs[5] = (xattr & AMI_IREAD)? 'r' : '-';
X attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-';
X attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-';
X attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-';
X attribs[9] = 0; /* better dlm the string */
X PRINTF(LoadFarString(AmigaFileAttributes), xattr, attribs);
X
X } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) &&
X (hostnum != FS_NTFS_) && (hostnum != ATARI_) &&
X (hostnum != ACORN_))
X { /* assume Unix-like */
X switch (xattr & UNX_IFMT) {
X case UNX_IFDIR: attribs[0] = 'd'; break;
X case UNX_IFREG: attribs[0] = '-'; break;
X case UNX_IFLNK: attribs[0] = 'l'; break;
X case UNX_IFBLK: attribs[0] = 'b'; break;
X case UNX_IFCHR: attribs[0] = 'c'; break;
X case UNX_IFIFO: attribs[0] = 'p'; break;
X case UNX_IFSOCK: attribs[0] = 's'; break;
X default: attribs[0] = '?'; break;
X }
X attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
X attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
X attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
X
X attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
X attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
X attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
X
X if (xattr & UNX_IXUSR)
X attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
X else
X attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S = undefined */
X if (xattr & UNX_IXGRP)
X attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
X else
X attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
X if (xattr & UNX_IXOTH)
X attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */
X else
X attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T = undefined */
X attribs[10] = 0;
X
X PRINTF(LoadFarString(UnixFileAttributes), xattr, attribs);
X
X } else {
X PRINTF(LoadFarString(NonMSDOSFileAttributes),
X crec.external_file_attributes >> 8);
X
X } /* endif (hostnum: external attributes format) */
X
X if ((xattr=(ush)(crec.external_file_attributes & 0xFF)) == 0)
X PRINTF(LoadFarString(MSDOSFileAttributes), xattr);
X else if (xattr == 1)
X PRINTF(LoadFarString(MSDOSFileAttributesRO), xattr);
X else
X PRINTF(LoadFarString(MSDOSFileAttributesAlpha),
X xattr, (xattr&1)?"rdo ":"", (xattr&2)?"hid ":"", (xattr&4)?"sys ":"",
X (xattr&8)?"lab ":"", (xattr&16)?"dir ":"", (xattr&32)?"arc":"");
X PRINTF(LoadFarString(LocalHeaderOffset),
X crec.relative_offset_local_header, crec.relative_offset_local_header);
X
X/*---------------------------------------------------------------------------
X Skip the extra field, if any, and print the file comment, if any (the
X filename has already been printed, above). That finishes up this file
X entry...
X ---------------------------------------------------------------------------*/
X
X if (crec.extra_field_length > 0) {
X ush ef_id, ef_datalen;
X
X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
X error_in_archive = error;
X if (error > PK_WARN) /* fatal: can't continue */
X return error;
X }
X if (extra_field == (uch *)NULL)
X return PK_ERR; /* not consistent with crec length */
X ef_id = makeword(extra_field);
X ef_datalen = makeword(&extra_field[2]);
X switch (ef_id) {
X case EF_AV:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efAV), ef_datalen);
X break;
X case EF_OS2:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efOS2), ef_datalen);
X/* GRR: should check that ef_datalen really 4 and not 2 before doing this: */
X PRINTF(LoadFarString(OS2EAs), makelong(&extra_field[4]));
X break;
X case EF_PKVMS:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efPKVMS), ef_datalen);
X break;
X case EF_IZVMS:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efIZVMS), ef_datalen);
X break;
X case EF_ASIUNIX:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efASiUnix), ef_datalen);
X break;
X case EF_SPARK:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efSpark), ef_datalen);
X break;
X default:
X PRINTF(LoadFarString(ExtraFieldType), ef_id,
X LoadFarStringSmall(efUnknown), ef_datalen);
X break;
X }
X if (ef_id != EF_OS2) {
X ush i, n;
X
X if (ef_datalen <= 16) {
X PRINTF(LoadFarString(ColonIndent));
X/* GRR: should double-check that datalen <= crec.extra_field_length - 4 */
X n = ef_datalen;
X } else {
X PRINTF(LoadFarString(First16),
X LoadFarStringSmall(ColonIndent));
X n = 16;
X }
X for (i = 0; i < n; ++i)
X PRINTF(LoadFarString(efFormat), extra_field[i+4]);
X }
X PRINTF("\n");
X }
X
X if (!crec.file_comment_length)
X PRINTF(LoadFarString(NoFileComment));
X else {
X PRINTF(LoadFarString(FileCommBegin));
X if ((error = do_string(crec.file_comment_length, DISPLAY)) != PK_COOL) {
X error_in_archive = error; /* might be warning */
X if (error > PK_WARN) /* fatal */
X return error;
X }
X PRINTF(LoadFarString(FileCommEnd));
X }
X
X return error_in_archive;
X
X} /* end function zi_long() */


X
X
X
X
X

X/*************************/
X/* Function zi_short() */
X/*************************/
X
Xstatic int zi_short() /* return PK-type error code */
X{
X int k, error, error_in_archive=PK_COOL;
X ush methnum, hostnum, hostver, xattr;
X char *p, workspace[12], attribs[16];
X static char impl[5]="i#:#", defl[5]="def#";
X static char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
X static char *os[NUM_HOSTS+1] = {
X "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
X "cpm", "t20", "ntf", "qds", "aco", "???"
X };
X static char *method[NUM_METHODS+1] = {
X "stor", "shrk", "re:1", "re:2", "re:3", "re:4", impl, "tokn",
X defl, unkn
X };
X
X
X/*---------------------------------------------------------------------------
X Print out various interesting things about the compressed file.
X ---------------------------------------------------------------------------*/
X
X methnum = MIN(crec.compression_method, NUM_METHODS);
X hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
X hostver = crec.version_made_by[0];
X/*
X extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS);
X extver = crec.version_needed_to_extract[0];
X */
X
X if (methnum == IMPLODED) {
X impl[1] = (char) ((crec.general_purpose_bit_flag & 2)? '8' : '4');
X impl[3] = (char) ((crec.general_purpose_bit_flag & 4)? '3' : '2');
X } else if (methnum == DEFLATED) {
X ush dnum=(crec.general_purpose_bit_flag>>1) & 3;
X defl[3] = dtype[dnum];
X } else if (methnum == NUM_METHODS) { /* unknown */
X sprintf(unkn, "u%03d", crec.compression_method);
X }
X
X for (k = 0; k < 15; ++k)
X attribs[k] = ' ';
X attribs[15] = 0;
X
X xattr = (ush)((crec.external_file_attributes >> 16) & 0xFFFF);
X switch (hostnum) {
X case VMS_:
X { int i, j;
X
X for (k = 0; k < 12; ++k)
X workspace[k] = 0;
X if (xattr & VMS_IRUSR)
X workspace[0] = 'R';
X if (xattr & VMS_IWUSR) {
X workspace[1] = 'W';
X workspace[3] = 'D';
X }
X if (xattr & VMS_IXUSR)
X workspace[2] = 'E';
X if (xattr & VMS_IRGRP)
X workspace[4] = 'R';
X if (xattr & VMS_IWGRP) {
X workspace[5] = 'W';
X workspace[7] = 'D';
X }
X if (xattr & VMS_IXGRP)
X workspace[6] = 'E';
X if (xattr & VMS_IROTH)
X workspace[8] = 'R';
X if (xattr & VMS_IWOTH) {
X workspace[9] = 'W';
X workspace[11] = 'D';
X }
X if (xattr & VMS_IXOTH)
X workspace[10] = 'E';
X
X p = attribs;
X for (k = j = 0; j < 3; ++j) { /* groups of permissions */
X for (i = 0; i < 4; ++i, ++k) /* perms within a group */
X if (workspace[k])
X *p++ = workspace[k];
X *p++ = ','; /* group separator */
X }
X *--p = ' '; /* overwrite last comma */
X if ((p - attribs) < 12)
X sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
X }
X break;
X


X case FS_FAT_:
X case FS_HPFS_:
X case FS_NTFS_:

X case ATARI_:
X case ACORN_:
X xattr = (ush)(crec.external_file_attributes & 0xFF);
X sprintf(attribs, ".r.-... %d.%d", hostver/10, hostver%10);
X attribs[2] = (xattr & 0x01)? '-' : 'w';
X attribs[5] = (xattr & 0x02)? 'h' : '-';
X attribs[6] = (xattr & 0x04)? 's' : '-';
X attribs[4] = (xattr & 0x20)? 'a' : '-';
X if (xattr & 0x10) {
X attribs[0] = 'd';
X attribs[3] = 'x';
X } else
X attribs[0] = '-';
X if (IS_VOLID(xattr))
X attribs[0] = 'V';
X else if ((p = strrchr(filename, '.')) != (char *)NULL) {
X ++p;
X if (STRNICMP(p, "com", 3) == 0 || STRNICMP(p, "exe", 3) == 0 ||
X STRNICMP(p, "btm", 3) == 0 || STRNICMP(p, "cmd", 3) == 0 ||
X STRNICMP(p, "bat", 3) == 0)
X attribs[3] = 'x';
X }


X break;
X
X case AMIGA_:

X switch (xattr & AMI_IFMT) {
X case AMI_IFDIR: attribs[0] = 'd'; break;
X case AMI_IFREG: attribs[0] = '-'; break;
X default: attribs[0] = '?'; break;
X }
X attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-';
X attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-';
X attribs[3] = (xattr & AMI_IPURE)? 'p' : '-';
X attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-';
X attribs[5] = (xattr & AMI_IREAD)? 'r' : '-';
X attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-';
X attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-';
X attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-';
X sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
X break;
X
X default: /* assume Unix-like */
X switch (xattr & UNX_IFMT) {
X case UNX_IFDIR: attribs[0] = 'd'; break;
X case UNX_IFREG: attribs[0] = '-'; break;
X case UNX_IFLNK: attribs[0] = 'l'; break;
X case UNX_IFBLK: attribs[0] = 'b'; break;
X case UNX_IFCHR: attribs[0] = 'c'; break;
X case UNX_IFIFO: attribs[0] = 'p'; break;
X case UNX_IFSOCK: attribs[0] = 's'; break;
X default: attribs[0] = '?'; break;
X }
X attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
X attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
X attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
X attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
X attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
X attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
X
X if (xattr & UNX_IXUSR)
X attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
X else
X attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S==undefined */
X if (xattr & UNX_IXGRP)
X attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
X else
X /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; real 4.3BSD */
X attribs[6] = (xattr & UNX_ISGID)? 'S' : '-'; /* SunOS 4.1.x */
X if (xattr & UNX_IXOTH)
X attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */
X else
X attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */
X
X sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
X break;
X
X } /* end switch (hostnum: external attributes format) */
X
X PRINTF("%s %s %7lu %c%c", attribs, os[hostnum], crec.ucsize,
X (crec.general_purpose_bit_flag & 1)?
X ((crec.internal_file_attributes & 1)? 'T' : 'B') : /* encrypted */
X ((crec.internal_file_attributes & 1)? 't' : 'b'), /* plaintext */
X (crec.general_purpose_bit_flag & 8)? (crec.extra_field_length? 'X' : 'l')
X : (crec.extra_field_length? 'x' : '-'));
X if (lflag == 4) {
X ulg csiz = crec.csize;
X
X if (crec.general_purpose_bit_flag & 1)
X csiz -= 12; /* if encrypted, don't count encryption header */
X PRINTF("%3d%%", (ratio(crec.ucsize,csiz) + 5)/10);
X } else if (lflag == 5)
X PRINTF(" %7lu", crec.csize);
X
X PRINTF(" %s %s ", method[methnum],
X zi_time(&crec.last_mod_file_date, &crec.last_mod_file_time));
X fnprint();
X
X/*---------------------------------------------------------------------------
X Skip the extra field and/or the file comment, if any (the filename has
X already been printed, above). That finishes up this file entry...
X ---------------------------------------------------------------------------*/
X
X SKIP_(crec.extra_field_length)
X SKIP_(crec.file_comment_length)
X
X return error_in_archive;
X
X} /* end function zi_short() */


X
X
X
X
X

X/************************/
X/* Function zi_time() */
X/************************/
X
Xstatic char *zi_time(datez, timez)
X ush *datez, *timez;
X{
X ush yr, mo, dy, hh, mm, ss;
X static char d_t_str[21], bogus[4];
X static char Far *month[13] = {
X bogus, JanMonth, FebMonth, MarMonth, AprMonth, MayMonth, JunMonth,
X JulMonth, AugMonth, SepMonth, OctMonth, NovMonth, DecMonth
X };
X
X
X
X/*---------------------------------------------------------------------------
X Convert the file-modification date and time info to a string of the form
X "1991 Feb 23 17:15:00" or "23-Feb-91 17:15," depending on value of lflag.
X ---------------------------------------------------------------------------*/
X
X yr = ((*datez >> 9) & 0x7f) + 80;
X mo = ((*datez >> 5) & 0x0f);
X dy = *datez & 0x1f;
X
X hh = (*timez >> 11) & 0x1f;
X mm = (*timez >> 5) & 0x3f;
X ss = (*timez & 0x1f) * 2;
X
X if (mo == 0 || mo > 12) {
X sprintf(bogus, LoadFarString(BogusFmt), mo);
X mo = 0;
X }
X
X if (lflag > 9) /* verbose listing format */
X sprintf(d_t_str, LoadFarString(YMDHMSTime), yr+1900,
X LoadFarStringSmall(month[mo]), dy, hh, mm, ss);
X else if (T_flag)
X sprintf(d_t_str, LoadFarString(DecimalTime), yr%100, mo, dy, hh, mm,
X ss);
X else /* was: if ((lflag >= 3) && (lflag <= 5)) */
X sprintf(d_t_str, LoadFarString(DMYHMTime), dy,
X LoadFarStringSmall(month[mo]), yr%100, hh, mm);
X
X return d_t_str;
X
X} /* end function zi_time() */
X
X#endif /* !NO_ZIPINFO */


X
X
X
X
X

X/*************************/
X/* Function list_files() */
X/*************************/
X
Xint list_files() /* return PK-type error code */
X{
X char sgn, cfactorstr[10];
X int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
X int longhdr=(vflag>1), date_format, methnum;
X ush j, yr, mo, dy, hh, mm, members=0;
X ulg csiz, tot_csize=0L, tot_ucsize=0L;
X#ifdef OS2
X ulg ea_size, tot_easize=0L, tot_eafiles=0L;
X#endif
X#ifdef MSWIN
X PSTR psLBEntry; /* list box entry */
X#endif
X min_info info;
X static char defl[]="Defl:#", dtype[]="NXFS"; /* see zi_short() */
X static char *method[NUM_METHODS+1] =
X {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
X "Implode", "Token", defl, unkn};
X
X
X
X/*---------------------------------------------------------------------------
X Unlike extract_or_test_files(), this routine confines itself to the cen-
X tral directory. Thus its structure is somewhat simpler, since we can do
X just a single loop through the entire directory, listing files as we go.
X
X So to start off, print the heading line and then begin main loop through
X the central directory. The results will look vaguely like the following:
X
X Length Method Size Ratio Date Time CRC-32 Name ("^" ==> case
X ------ ------ ---- ----- ---- ---- ------ ---- conversion)
X 44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
X 3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 ^dos-file.ext
X ---------------------------------------------------------------------------*/
X
X pInfo = &info;
X date_format = DATE_FORMAT;
X
X#ifndef MSWIN
X if (qflag < 2)
X if (L_flag)
X PRINTF(LoadFarString(CaseConversion),
X LoadFarStringSmall(Headers[longhdr][0]),
X LoadFarStringSmall2(Headers[longhdr][1]));
X else
X PRINTF("%s\n%s\n", LoadFarString(Headers[longhdr][0]),
X LoadFarStringSmall(Headers[longhdr][1]));
X#endif /* !MSWIN */
X
X for (j = 0; j < ecrec.total_entries_central_dir; ++j) {
X


X if (readbuf(sig, 4) == 0)

X return PK_EOF;
X if (strncmp(sig, central_hdr_sig, 4)) { /* just to make sure */
X FPRINTF(stderr, LoadFarString(CentSigMsg), j); /* sig not found */
X FPRINTF(stderr, LoadFarString(ReportMsg)); /* check binary xfers */
X return PK_BADERR;
X }
X /* process_cdir_file_hdr() sets pInfo->lcflag: */
X if ((error = process_cdir_file_hdr()) != PK_COOL)
X return error; /* only PK_EOF defined */
X
X /*
X * We could DISPLAY the filename instead of storing (and possibly trun-
X * cating, in the case of a very long name) and printing it, but that
X * has the disadvantage of not allowing case conversion--and it's nice
X * to be able to see in the listing precisely how you have to type each
X * filename in order for unzip to consider it a match. Speaking of
X * which, if member names were specified on the command line, check in
X * with match() to see if the current file is one of them, and make a
X * note of it if it is.
X */
X
X if ((error = do_string(crec.filename_length, FILENAME)) != PK_COOL) {
X error_in_archive = error; /* ^--(uses pInfo->lcflag) */
X if (error > PK_WARN) /* fatal: can't continue */
X return error;
X }
X if (extra_field != (uch *)NULL) {
X free(extra_field);
X extra_field = (uch *)NULL;
X }
X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
X error_in_archive = error;
X if (error > PK_WARN) /* fatal */
X return error;
X }
X if (!process_all_files) { /* check if specified on command line */
X char **pfn = pfnames-1;
X
X do_this_file = FALSE;
X while (*++pfn)
X if (match(filename, *pfn, C_flag)) {
X do_this_file = TRUE;
X break; /* found match, so stop looping */
X }
X if (do_this_file) { /* check if this is an excluded file */
X char **pxn = pxnames-1;
X
X while (*++pxn)
X if (match(filename, *pxn, C_flag)) {
X do_this_file = FALSE; /* ^-- ignore case in match */
X break;
X }
X }
X }
X /*
X * If current file was specified on command line, or if no names were
X * specified, do the listing for this file. Otherwise, get rid of the
X * file comment and go back for the next file.
X */
X
X if (process_all_files || do_this_file) {
X
X yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)100;
X mo = (crec.last_mod_file_date >> 5) & 0x0f;
X dy = crec.last_mod_file_date & 0x1f;
X
X /* permute date so it displays according to national convention */
X switch (date_format) {
X case DF_YMD:
X hh = mo; mo = yr; yr = dy; dy = hh;
X break;
X case DF_DMY:
X hh = mo; mo = dy; dy = hh;
X }
X hh = (crec.last_mod_file_time >> 11) & 0x1f;
X mm = (crec.last_mod_file_time >> 5) & 0x3f;
X
X csiz = crec.csize;
X if (crec.general_purpose_bit_flag & 1)
X csiz -= 12; /* if encrypted, don't count encryption header */
X if ((cfactor = ratio(crec.ucsize, csiz)) < 0) {
X sgn = '-';
X cfactor = (-cfactor + 5) / 10;
X } else {
X sgn = ' ';
X cfactor = (cfactor + 5) / 10;
X }
X sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
X
X methnum = MIN(crec.compression_method, NUM_METHODS);
X if (methnum == DEFLATED)
X defl[5] = dtype[(crec.general_purpose_bit_flag>>1) & 3];
X else if (methnum == NUM_METHODS)
X sprintf(unkn, LoadFarString(CompMethodUnknown),
X crec.compression_method);
X
X#if 0 /* GRR/Euro: add this? */
X#if defined(DOS_NT_OS2) || defined(UNIX)
X for (p = filename; *p; ++p)
X if (!isprint(*p))
X *p = '?'; /* change non-printable chars to '?' */
X#endif /* DOS_NT_OS2 || UNIX */


X#endif /* 0 */
X

X#ifdef MSWIN
X#ifdef NEED_EARLY_REDRAW
X /* turn on listbox redrawing just before adding last line */
X if (j == (ecrec.total_entries_central_dir-1))
X (void)SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L);
X#endif /* NEED_EARLY_REDRAW */
X psLBEntry =
X (PSTR)LocalAlloc(LMEM_FIXED, FILNAMSIZ+LONG_FORM_FNAME_INX);
X /* GRR: does OemToAnsi filter out escape and CR characters? */
X OemToAnsi(filename, filename); /* translate to ANSI */
X if (longhdr) {
X wsprintf(psLBEntry, LoadFarString(LongHdrStats),
X crec.ucsize, (LPSTR)method[methnum], csiz, cfactorstr,
X mo, dy, yr, hh, mm, crec.crc32, (pInfo->lcflag?'^':' '),
X (LPSTR)filename);
X SendMessage(hWndList, LB_ADDSTRING, 0,
X (LONG)(LPSTR)psLBEntry);
X } else {
X wsprintf(psLBEntry, LoadFarString(ShortHdrStats),
X crec.ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '),
X (LPSTR)filename);
X SendMessage(hWndList, LB_ADDSTRING, 0,
X (LONG)(LPSTR)psLBEntry);
X }
X LocalFree((HANDLE)psLBEntry);
X#else /* !MSWIN */
X if (longhdr)
X PRINTF(LoadFarString(LongHdrStats),
X crec.ucsize, method[methnum], csiz, cfactorstr, mo, dy, yr,
X hh, mm, crec.crc32, (pInfo->lcflag?'^':' '));
X else
X PRINTF(LoadFarString(ShortHdrStats), crec.ucsize,
X mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '));
X fnprint();


X#endif /* ?MSWIN */
X

X error = do_string(crec.file_comment_length, QCOND? DISPLAY : SKIP);
X if (error) {
X error_in_archive = error; /* might be just warning */
X if (error > PK_WARN) /* fatal */
X return error;
X }
X tot_ucsize += crec.ucsize;
X tot_csize += csiz;
X ++members;
X#ifdef OS2
X if ((ea_size = SizeOfEAs(extra_field)) != 0) {
X tot_easize += ea_size;
X tot_eafiles++;
X }
X#endif
X } else { /* not listing this file */
X SKIP_(crec.file_comment_length)
X }
X } /* end for-loop (j: files in central directory) */
X
X/*---------------------------------------------------------------------------
X Print footer line and totals (compressed size, uncompressed size, number
X of members in zipfile).
X ---------------------------------------------------------------------------*/
X
X if (qflag < 2) {
X if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
X sgn = '-';
X cfactor = (-cfactor + 5) / 10;
X } else {
X sgn = ' ';
X cfactor = (cfactor + 5) / 10;
X }
X sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
X#ifdef MSWIN
X /* Display just the totals since the dashed lines get displayed
X * in UpdateListBox(). Get just enough space to display total. */
X if (longhdr)
X wsprintf(lpumb->szTotalsLine,LoadFarString(LongFileHeader),
X tot_ucsize, tot_csize, cfactorstr, members);
X else
X wsprintf(lpumb->szTotalsLine, LoadFarString(ShortFileHeader),
X tot_ucsize, members);
X#else /* !MSWIN */
X if (longhdr)
X PRINTF(LoadFarString(LongFileHeader), tot_ucsize, tot_csize, cfactorstr, members);
X else
X PRINTF(LoadFarString(ShortFileHeader), tot_ucsize, members);
X#endif /* ?MSWIN */
X#ifdef OS2
X if (tot_eafiles && tot_easize)
X PRINTF("\n%ld file%s %ld bytes of EA's attached.\n", tot_eafiles,
X tot_eafiles == 1 ? " has" : "s have a total of", tot_easize);
X#endif
X }
X/*---------------------------------------------------------------------------
X Double check that we're back at the end-of-central-directory record.
X ---------------------------------------------------------------------------*/
X


X if (readbuf(sig, 4) == 0)

X return PK_EOF;
X if (strncmp(sig, end_central_sig, 4)) { /* just to make sure again */
X FPRINTF(stderr, LoadFarString(EndSigMsg)); /* didn't find sig */


X error_in_archive = PK_WARN;
X }

X if (members == 0 && error_in_archive <= PK_WARN)
X error_in_archive = PK_FIND;
X
X return error_in_archive;
X
X} /* end function list_files() */


X
X
X
X
X

X/********************/
X/* Function ratio() */
X/********************/
X
Xstatic int ratio(uc, c)
X ulg uc, c;
X{
X ulg denom;
X
X if (uc == 0)
X return 0;
X if (uc > 2000000L) { /* risk signed overflow if multiply numerator */
X denom = uc / 1000L;
X return ((uc >= c) ?
X (int) ((uc-c + (denom>>1)) / denom) :
X -((int) ((c-uc + (denom>>1)) / denom)));
X } else { /* ^^^^^^^^ rounding */
X denom = uc;
X return ((uc >= c) ?
X (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
X -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
X } /* ^^^^^^^^ rounding */


X}
X
X
X
X
X

X/************************/
X/* Function fnprint() */
X/************************/
X
Xstatic void fnprint() /* print filename (after filtering) and newline */
X{
X register uch *p = (uch *)filename-1;
X register uch *q = (uch *)slide;
X
X#ifdef NATIVE
X PRINTF("%s", filename); /* GRR: can ANSI be used with EBCDIC? */
X#else /* ASCII */
X while (*++p) {
X if (*p < 32) { /* ASCII control character */
X *q++ = '^';
X *q++ = *p + 64;
X } else
X *q++ = *p;
X } /* filename better not be longer than slide[] ... */
X *q = '\0';
X PRINTF("%s\n", slide);
X#endif /* ?NATIVE */
X
X} /* end function fnprint() */
END_OF_FILE
if test 64797 -ne `wc -c <'unzip-5.12/zipinfo.c'`; then
echo shar: \"'unzip-5.12/zipinfo.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/zipinfo.c'
fi
echo shar: End of archive 4 \(of 20\).
cp /dev/null ark4isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:14:49 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 70
Archive-name: unzip/part05

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/Where unzip-5.12/os2/os2.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:37 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 5 (of 20)."'
if test -f 'unzip-5.12/Where' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/Where'\"
else
echo shar: Extracting \"'unzip-5.12/Where'\" \(9912 characters\)
sed "s/^X//" >'unzip-5.12/Where' <<'END_OF_FILE'
X__________________________________________________________________________
X
X This is the Info-ZIP file ``Where,'' last updated on 7 September 1994.
X__________________________________________________________________________
X
X Note that some ftp sites may not yet have the latest versions of
X Zip and UnZip when you read this. The latest versions, including
X the crypt sources, always appear in ftp.uu.net:/pub/archiving/zip
X (and subdirectories thereof) first.
X
X IF YOU FIND AN ERROR: please let us know! We don't have time to
X check each and every site personally (or even collectively), so any
X number of the sites listed below may have moved or disappeared en-
X tirely. E-mail to zip-...@wkuvx1.wku.edu and we'll update this file.
X__________________________________________________________________________
X
X
XSource-code archives for Info-ZIP's portable Zip, UnZip, and related
Xutilities (on some ftp sites, the .zip files for UnZip may have a .zoo
Xequivalent in Zoo 2.10 format):
X
X zip201.zip Zip 2.0.1 (deflation; includes zipnote, zipsplit)
X zip201.tar.Z ditto, compress'd tar format
X
X zip11.zip Zip 1.1 (shrinking, implosion; compatible with PKUNZIP 1.1)
X zip11.tar.Z ditto, compress'd tar format
X
X unzip512.zip UnZip 5.12 (all methods supported; zipinfo, funzip, unzipsfx)
X unzip512.tar.Z ditto, compress'd tar format
X
X wunz20sr.zip WizUnZip 2.0 sources for Windows 3.x; based on UnZip 5.0p1
X
X zcrypt23.zip encryption/decryption support (includes zipcloak)
X
XExecutables archives (and related files) for Info-ZIP's software; see BBS
Xsection below for special CompuServe (6.3) filenames:
X
X zip201x.zip MSDOS executables and docs for zip, zipnote, zipsplit
X zcryp20x.zip MSDOS encryption executables and docs for zip, zipcloak
X zip201x1.zip OS/2 1.x (16-bit) executables and docs (no encryption)
X zip201x2.zip OS/2 2.x (32-bit) executables and docs (no encryption)
X zip201c2.zip OS/2 2.x (32-bit) executables and docs (with encryption)
X zip201-vax.zip VMS exes (VAX) and docs
X zip201-axp.zip VMS exes (Alpha) and docs
X zip201x.lha Amiga executables and docs
X
X unz512x.exe MSDOS self-extracting executable (16-bit unzip, ..., docs)
X unz512x3.exe MSDOS self-extracting executable (16-, 32-bit unzip, docs)
X unz512x1.exe OS/2 1.x (16-bit) self-extracting executables and docs
X unz512x2.exe OS/2 2.x (32-bit) self-extracting executables and docs
X unz512xN.exe Windows NT (and Chicago) self-extracting Intel exes and docs
X (unz512xN-mips.exe, unz512xN-axp.exe: Windows NT exes/docs for MIPS & Alpha)
X unz512x-vax.exe VMS self-extracting executables and docs for VAX unzip
X unz512x-axp.exe VMS self-extracting executables and docs for Alpha unzip
X unz512x.lha Amiga executables and docs for unzip
X unz512x.tos Atari self-extracting executables and docs for unzip
X unz512x.hqx Macintosh BinHex'd executables and docs for unzip
X (unz512x.tar.Z or .gz: Unix exes/docs for Solaris 2.x, SCO Unix or Linux,
X depending on directory/location)
X
X UnzpHist.zip complete changes history of UnZip and its precursors
X
X wunz20x.zip WizUnZip 2.0 executable/docs for Windows & NT 3.1, OS/2 2.1
X wunl20x.zip same as wunz20x.zip, plus two DLLs for Win 3.0 and OS/2 2.0
X
XThe latest from PKWARE (the guys who started it all):
X
X pkz204g.exe MS-DOS PKZIP/PKUNZIP 2.04g (self-extracting archive)
X pkz110eu.exe MS-DOS PKZIP/PKUNZIP 1.1 (self-extracting)
X pkz206-2.exe OS/2 PKZIP/PKUNZIP 2.06 (IBM internal only; same as 2.04g)
X pkz102-2.exe OS/2 PKZIP/PKUNZIP 1.02 (self-extracting)
X
XThird-party software which is based on or uses (or can use) Info-ZIP software:
X
X zipme11.zip, zipctl.zip, wuz131.zip, zpfly91b.zip, pmzip01.zip (OS/2)
X winzip5b.zip, z101.zip (Windows)
X
Xftp sites for the US-exportable sources and executables:
X
X NOTE: Look for the file names given above in the following directories.
X Some sites like to use slightly different names, such as zip-2.0.1.tar.gz
X instead of zip201.tar.Z. In the case of some comp.sources.misc archive
X sites, directories may be used (zip201/part01.Z, ..., zip201/part11.Z,
X zip201/patch01.Z, etc.).
X
X ftp.uu.net:/pub/archiving/zip [THIS MIRRORS THE INFO-ZIP HOME SITE]
X
X oak.oakland.edu:/pub/msdos/{zip,windows3} [AND OTHER SIMTEL MIRRORS]
X oak.oakland.edu:/pub/misc/{unix,vaxvms}
X garbo.uwasa.fi:/{unix,pc}/arcers [AND OTHER GARBO MIRRORS]
X ftp-os2.cdrom.com:/pub/os2/{2_x,all}/archiver
X ftp-os2.nmsu.edu:/os2/{2_x,all}/archiver
X ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/archiver
X sumex-aim.stanford.edu:/info-mac/util
X ftp.wustl.edu:/pub/aminet/util/arc [AND OTHER AMINET MIRRORS]
X atari.archive.umich.edu:/pub/Archivers (?) [AND OTHER UMICH MIRRORS]
X lpuds.oea.ihep.su:/ ... ?
X
Xftp sites for the encryption and decryption sources and/or executables:
X
X NOTE 1: Non-US users, please do NOT ftp from the US sites (US
X regulations and all that). Likewise, US users, please do not
X ftp from the European sites (it's not illegal, but it sure is
X a waste of expensive bandwidth).
X
X NOTE 2: Some sites may carry both encryption and non-encryption
X executables with slightly different names; for example, zip201c2.zip
X instead of zip201x2.zip ("c" == crypt version). Other sites may
X include *only* the encryption-related executables (zip and zipcloak)
X in a second archive (e.g., zcryp20x.zip).
X
X From the US:
X wuarchive.wustl.edu:/mirrors/garbo.uwasa.fi/arcutil
X ftp.uu.net:/pub/archiving/zip
X
X Outside the US:
X garbo.uwasa.fi:/pc/arcutil
X ftp.inria.fr:/system/arch-compr
X ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/archiver
X (mail server at ftp-m...@informatik.tu-muenchen.de)
X
X ftp.win.tue.nl:/pub/compression/zip/...
X ftp.uni-erlangen.de:/pub/pc/msdos/utilities/zip/...
X
Xftp sites for VMS-format Zip and UnZip packages (sources, object files and
Xexecutables, no encryption/decryption--see also "Mail servers" section below):
X
X ftp.spc.edu [192.107.46.27] and ftp.wku.edu:
X
X [.MACRO32]AAAREADME.TXT
X [.MACRO32.SAVESETS]UNZIP.BCK or UNZIP.ZIP (if already have older version)
X [.MACRO32.SAVESETS]ZIP20.ZIP (to be renamed to ZIP.ZIP in next release)
X
XTo find other ftp sites:
X
X The "archie" ftp database utility can be used to find an ftp site
X near you (although it always seems to find old versions...). If
X you don't know how to use it, DON'T ASK US--check the Usenet groups
X news.announce.newusers or news.answers or some such, or ask your
X system administrator (or just RTFM :-) ).
X
XUUCP sites:
X
X uunet!~/pub/archiving/zip/ ...
X
XBulletin boards (commercial and otherwise):
X
X Sources, MS-DOS executables:
X CompuServe IBMPRO forum, Library 10, Data Compression (unz512.zip,
X sources; unz512.exe, self-extracting executables and docs)
X CompuServe (ZiffNet) PBSUTIL forum and Public Brand Software BBS
X [US, membership required; V.32 line, (317) 856-1490]
X (unz512.zip, sources; unz512.exe, self-extracting exes and docs)
X America Online OS/2 Forum, Free Uploading area; also Top Picks lib-
X rary, File/Disk Utilities library, and OS/2 1.x library (do key-
X word search via ctrl-K: FILE SEARCH on "INFOZIP")
X FidoNet node 1:124/2113, Lunatic Fringe [Richardson, Texas; BBS
X (214) 235-5288; sysop john.s...@lunatic.com; complete mirror
X of Info-ZIP home site]
X FidoNet node 1:246/74, Metal Shoppe BBS [Windsor, Ontario; CLink
X node 911:6510/0; BBS (519) 256-0278; sysop ra...@cyberspace.net
X (Ray Akey); micro-based files but no Unix/VMS/NT stuff]
X Drealm Conference System [London, UK; V.22bis, subscriber lines
X to V.32bis, etc.; (+44) 81 568 2204]
X Compulink Information eXchange (CIX) [London, UK; (+44) 181 390 1244
X and 181 390 1255; sources in free_software/sources, executables
X in "the filepool"]
X
X Windows sources and executables:
X CompuServe ZENITH forum (wunzip.zip, WizUnZip exe + libs for
X Win 3.x, NT, OS/2 2.x)
X CompuServe CRAFTS forum (wunz20.exe, WizUnZip bare executable
X for Win 3.1, NT, OS/2 2.1)
X
X OS/2 executables:
X CompuServe OS2USER forum (zip201.zip and unz512.exe, OS/2 16-
X and 32-bit exes and docs)
X
X Amiga executables:
X BIX in AMIGA files section (perform keyword search on "info-zip")
X [requires account; telnet bix.com, or "C BIX" via local Sprint
X X.25 PAD, or dial direct in US at (617) 491-5410]
X
XMail servers:
X
X If you don't have anonymous FTP capability, you can mail one
X of the following commands (in the body of an e-mail message) to
X list...@vm.ecs.rpi.edu or list...@vm1.nodak.edu in order to
X get a copy of the source code via e-mail:
X
X /pdget mail /pub/misc/unix/unzip512.tar.Z uuencode
X /pdget mail /pub/msdos/zip/unzip512.zip uuencode
X /pdget mail /pub/msdos/zip/zip201.zip uuencode
X
X The older, pseudo-TOPS-20 style also works:
X
X /pdget mail pd:<misc.unix>unzip512.tar.Z uuencode
X /pdget mail pd:<misc.unix>zip201.zip uuencode
X
X To get the encryption source by e-mail, send the following commands
X to ftp-m...@informatik.tu-muenchen.de:
X
X get /pub/comp/os/os2/archiver/zcrypt23.zip
X quit
X
X To get the VMS Zip/UnZip package by e-mail, send the following
X commands in the body of a mail message to mxse...@wkuvx1.wku.edu
X (the "HELP" command is also accepted):
X
X SEND UNZIP
X SEND ZIP20 <-- will change to plain "ZIP" in next release
X SEND FILESERV_TOOLS
X
X To get Atari executables by e-mail, send a message to
X at...@atari.archive.umich.edu for information about the mail server.
X__________________________________________________________________________
X
END_OF_FILE
if test 9912 -ne `wc -c <'unzip-5.12/Where'`; then
echo shar: \"'unzip-5.12/Where'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/Where'
fi
if test -f 'unzip-5.12/os2/os2.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/os2.c'\"
else
echo shar: Extracting \"'unzip-5.12/os2/os2.c'\" \(57190 characters\)
sed "s/^X//" >'unzip-5.12/os2/os2.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X os2.c
X
X OS/2-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X This file contains the OS/2 versions of the file name/attribute/time/etc
X code. Most or all of the routines which make direct use of OS/2 system
X calls (i.e., the non-lowercase routines) are Kai Uwe Rommel's. The read-
X dir() suite was written by Michael Rendell and ported to OS/2 by Kai Uwe;
X it is in the public domain.
X
X Contains: GetCountryInfo()
X GetFileTime()
X SetPathInfo()
X IsEA()
X SetEAs()
X SizeOfEAs()
X GetLoadPath()
X opendir()
X closedir()
X readdir()
X [ seekdir() ] not used
X [ telldir() ] not used
X free_dircontents()
X getdirent()
X IsFileSystemFAT()
X do_wild()
X mapattr()
X mapname()
X checkdir()
X isfloppy()
X IsFileNameValid()
X map2fat()
X SetLongNameEA()
X close_outfile()
X check_for_newer()
X dateformat()
X version()
X InitNLS()
X IsUpperNLS()
X ToLowerNLS()
X StringLower()
X DebugMalloc()


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
Xchar *StringLower(char *szArg);
X
X/* local prototypes */
Xstatic int isfloppy __((int nDrive));
Xstatic int IsFileNameValid __((char *name));
Xstatic void map2fat __((char *pathcomp, char **pEndFAT));
Xstatic int SetLongNameEA __((char *name, char *longname));
Xstatic void InitNLS __((void));
X
X#ifndef __EMX__
X# if (_MSC_VER >= 600) || defined(__IBMC__)
X# include <direct.h> /* have special MSC/IBM C mkdir prototype */
X# else /* own prototype because dir.h conflicts? */
X int mkdir(const char *path);
X# endif
X# define MKDIR(path,mode) mkdir(path)
X#else
X# define MKDIR(path,mode) mkdir(path,mode)
X#endif
X
X#define INCL_NOPM
X#define INCL_DOSNLS
X#define INCL_DOSPROCESS
X#define INCL_DOSDEVICES
X#define INCL_DOSDEVIOCTL
X#define INCL_DOSERRORS
X#include <os2.h>
X
X#ifdef __32BIT__
X
XUSHORT DosDevIOCtl32(PVOID pData, USHORT cbData, PVOID pParms, USHORT cbParms,
X USHORT usFunction, USHORT usCategory, HFILE hDevice)
X{
X ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
X return (USHORT) DosDevIOCtl(hDevice, usCategory, usFunction,
X pParms, cbParms, &ulParmLengthInOut,
X pData, cbData, &ulDataLengthInOut);
X}
X
X# define DosDevIOCtl DosDevIOCtl32
X#else
X# define DosDevIOCtl DosDevIOCtl2
X#endif
X
X
X#define EAID 0x0009
X
X
Xtypedef struct
X{
X ush nID;
X ush nSize;
X ulg lSize;
X}
XEAHEADER, *PEAHEADER;
X
X
X#ifndef __32BIT__
X
Xtypedef struct
X{
X ULONG oNextEntryOffset;
X BYTE fEA;
X BYTE cbName;
X USHORT cbValue;
X CHAR szName[1];
X}
XFEA2, *PFEA2;
X
Xtypedef struct
X{
X ULONG cbList;
X FEA2 list[1];
X}
XFEA2LIST, *PFEA2LIST;
X
X
X#define DosSetPathInfo(p1, p2, p3, p4, p5) \
X DosSetPathInfo(p1, p2, p3, p4, p5, 0)
X#define DosQueryPathInfo(p1, p2, p3, p4) \
X DosQPathInfo(p1, p2, p3, p4, 0)
X#define DosMapCase DosCaseMap
X#define DosQueryCtryInfo DosGetCtryInfo
X
X#endif /* !__32BIT__ */


X
X
X
X
X
X/*

X * @(#) dir.h 1.4 87/11/06 Public Domain.
X */
X
X#define MAXNAMLEN 256
X#define MAXPATHLEN 256
X
X#define A_RONLY 0x01
X#define A_HIDDEN 0x02
X#define A_SYSTEM 0x04
X#define A_LABEL 0x08
X#define A_DIR 0x10
X#define A_ARCHIVE 0x20
X
X
Xstruct direct
X{
X ino_t d_ino; /* a bit of a farce */
X int d_reclen; /* more farce */
X int d_namlen; /* length of d_name */
X char d_name[MAXNAMLEN + 1]; /* null terminated */
X /* nonstandard fields */
X long d_size; /* size in bytes */
X unsigned d_mode; /* MS-DOS or OS/2 file attributes */
X unsigned d_time;
X unsigned d_date;
X};
X
X/* The fields d_size and d_mode are extensions by me (Kai Uwe Rommel). The
X * find_first and find_next calls deliver these data without any extra cost.
X * If these data are needed, the fields save a lot of extra calls to stat()
X * (each stat() again performs a find_first call !).
X */
X
Xstruct _dircontents
X{
X char *_d_entry;
X long _d_size;
X unsigned _d_mode, _d_time, _d_date;
X struct _dircontents *_d_next;
X};
X
Xtypedef struct _dirdesc
X{
X int dd_id; /* uniquely identify each open directory */
X long dd_loc; /* where we are in directory entry is this */
X struct _dircontents *dd_contents; /* pointer to contents of dir */
X struct _dircontents *dd_cp; /* pointer to current position */
X}
XDIR;
X
X
Xextern DIR *opendir(char *);
Xextern struct direct *readdir(DIR *);
Xextern void seekdir(DIR *, long);
Xextern long telldir(DIR *);
Xextern void closedir(DIR *);
X#define rewinddir(dirp) seekdir(dirp, 0L)
X
Xint IsFileSystemFAT(char *dir);
Xchar *StringLower(char *);


X
X
X
X
X/*

X * @(#)dir.c 1.4 87/11/06 Public Domain.
X */
X
X#ifdef __32BIT__
X# define DosFindFirst(p1, p2, p3, p4, p5, p6) \
X DosFindFirst(p1, p2, p3, p4, p5, p6, 1)
X#else
X# define DosQueryCurrentDisk DosQCurDisk
X# define DosQueryFSAttach(p1, p2, p3, p4, p5) \
X DosQFSAttach(p1, p2, p3, p4, p5, 0)
X# define DosQueryPathInfo(p1, p2, p3, p4) \
X DosQPathInfo(p1, p2, p3, p4, 0)
X# define DosSetPathInfo(p1, p2, p3, p4, p5) \
X DosSetPathInfo(p1, p2, p3, p4, p5, 0)
X# define DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7) \
X DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7, 0)
X# define DosFindFirst(p1, p2, p3, p4, p5, p6) \
X DosFindFirst(p1, p2, p3, p4, p5, p6, 0)
X# define DosMapCase DosCaseMap
X#endif
X
X#ifndef S_IFMT
X# define S_IFMT 0xF000
X#endif
X
X
X#ifdef __WATCOMC__
X unsigned char __near _osmode = OS2_MODE;
X#endif
X
X#ifndef SFX
X static char *getdirent(char *);
X static void free_dircontents(struct _dircontents *);
X static int attributes = A_DIR | A_HIDDEN | A_SYSTEM;
X# ifdef __32BIT__
X static HDIR hdir;
X static ULONG count;
X static FILEFINDBUF3 find;
X# else
X static HDIR hdir; /* GRR: is there a difference? HDIR2?? */
X static USHORT count;
X static FILEFINDBUF find;
X# endif
X#endif /* !SFX */
X
X
X
X
Xstatic int created_dir; /* used by mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */
Xstatic int fnlen; /* ditto */
X#ifdef __32BIT__
X static ULONG nLabelDrive; /* ditto */
X#else
X static USHORT nLabelDrive;
X#endif
Xstatic int longnameEA; /* checkdir(), close_outfile() */
Xstatic char *lastpathcomp; /* ditto */
X
X
Xint GetCountryInfo(void)
X{
X COUNTRYINFO ctryi;
X COUNTRYCODE ctryc;
X#ifdef __32BIT__
X ULONG cbInfo;
X#else
X USHORT cbInfo;
X#endif
X
X ctryc.country = ctryc.codepage = 0;
X
X if ( DosQueryCtryInfo(sizeof(ctryi), &ctryc, &ctryi, &cbInfo) != NO_ERROR )
X return 0;
X
X return ctryi.fsDateFmt;
X}
X
X
Xlong GetFileTime(char *name)
X{
X#ifdef __32BIT__
X FILESTATUS3 fs;
X#else
X FILESTATUS fs;
X#endif
X USHORT nDate, nTime;
X
X if ( DosQueryPathInfo(name, 1, (PBYTE) &fs, sizeof(fs)) )
X return -1;
X
X nDate = * (USHORT *) &fs.fdateLastWrite;
X nTime = * (USHORT *) &fs.ftimeLastWrite;
X
X return ((ULONG) nDate) << 16 | nTime;
X}
X
X
Xvoid SetPathInfo(char *path, ush moddate, ush modtime, int flags)
X{
X union {
X FDATE fd; /* system file date record */
X ush zdate; /* date word */
X } ud;
X union {
X FTIME ft; /* system file time record */
X ush ztime; /* time word */
X } ut;
X FILESTATUS fs;
X USHORT nLength;
X char szName[CCHMAXPATH];
X
X strcpy(szName, path);
X nLength = strlen(szName);
X if (szName[nLength - 1] == '/')
X szName[nLength - 1] = 0;
X
X if ( DosQueryPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) )
X return;
X
X ud.zdate = moddate;
X ut.ztime = modtime;
X fs.fdateLastWrite = fs.fdateCreation = ud.fd;
X fs.ftimeLastWrite = fs.ftimeCreation = ut.ft;
X
X if ( flags != -1 )
X fs.attrFile = flags; /* hidden, system, archive, read-only */
X
X DosSetPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0);
X}
X
X
Xtypedef struct
X{
X ULONG cbList; /* length of value + 22 */
X#ifdef __32BIT__
X ULONG oNext;
X#endif
X BYTE fEA; /* 0 */
X BYTE cbName; /* length of ".LONGNAME" = 9 */
X USHORT cbValue; /* length of value + 4 */
X BYTE szName[10]; /* ".LONGNAME" */
X USHORT eaType; /* 0xFFFD for length-preceded ASCII */
X USHORT eaSize; /* length of value */
X BYTE szValue[CCHMAXPATH];
X}
XFEALST;
X
X
Xint IsEA(void *extra_field)
X{
X EAHEADER *pEAblock = (PEAHEADER) extra_field;
X return extra_field != NULL && pEAblock -> nID == EAID;
X}
X
X
Xvoid SetEAs(char *path, void *eablock)
X{
X EAHEADER *pEAblock = (PEAHEADER) eablock;
X#ifdef __32BIT__
X EAOP2 eaop;
X PFEA2LIST pFEA2list;
X#else
X EAOP eaop;
X PFEALIST pFEAlist;
X PFEA pFEA;
X PFEA2LIST pFEA2list;
X PFEA2 pFEA2;
X ULONG nLength2;
X#endif
X USHORT nLength;
X char szName[CCHMAXPATH];
X
X if ( !IsEA(eablock) )
X return;
X
X strcpy(szName, path);
X nLength = strlen(szName);
X if (szName[nLength - 1] == '/')
X szName[nLength - 1] = 0;
X
X if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL )
X return;
X
X if ( memextract((char *) pFEA2list, pEAblock -> lSize,
X (char *) (pEAblock + 1),
X pEAblock -> nSize - sizeof(pEAblock -> lSize)) )
X {
X free(pFEA2list);
X return;
X }
X
X#ifdef __32BIT__
X eaop.fpGEA2List = NULL;
X eaop.fpFEA2List = pFEA2list;
X#else
X pFEAlist = (PVOID) pFEA2list;
X pFEA2 = pFEA2list -> list;
X pFEA = pFEAlist -> list;
X
X do
X {
X nLength2 = pFEA2 -> oNextEntryOffset;
X nLength = sizeof(FEA) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue;
X
X memcpy(pFEA, (PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), nLength);
X
X pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength2);
X pFEA = (PFEA) ((PCH) pFEA + nLength);
X }
X while ( nLength2 != 0 );
X
X pFEAlist -> cbList = (PCH) pFEA - (PCH) pFEAlist;
X
X eaop.fpGEAList = NULL;
X eaop.fpFEAList = pFEAlist;
X#endif
X
X eaop.oError = 0;
X DosSetPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &eaop, sizeof(eaop), 0);
X
X if (!tflag && (qflag < 2))
X PRINTF(" (%ld bytes EA's)", pFEA2list -> cbList);
X
X free(pFEA2list);
X}
X
X
Xulg SizeOfEAs(void *extra_field)
X{
X EAHEADER *pEAblock = (PEAHEADER)extra_field;
X
X if (extra_field != NULL && makeword((uch *)&pEAblock->nID) == EAID)
X return makelong((uch *)&pEAblock->lSize);
X
X return 0L;


X}
X
X
X
X
X

X#ifdef SFX
X
Xchar *GetLoadPath(void)
X{
X#ifdef __32BIT__ /* generic for 32-bit API */
X
X PTIB pptib;
X PPIB pppib;
X char *szPath;
X
X DosGetInfoBlocks(&pptib, &pppib);
X szPath = pppib -> pib_pchenv;
X
X while (*szPath) /* find end of process environment */
X szPath = strchr(szPath, 0) + 1;
X
X return szPath + 1; /* .exe file name follows environment */
X
X#else /* 16-bit, specific for MS C 6.00, note: requires large data model */
X
X extern char _far *_pgmptr;
X return _pgmptr;
X
X#endif
X} /* end function GetLoadPath() */


X
X
X
X
X

X#else /* !SFX */
X

XDIR *opendir(char *name)
X{
X struct stat statb;
X DIR *dirp;
X char c;
X char *s;
X struct _dircontents *dp;
X char nbuf[MAXPATHLEN + 1];
X int len;
X
X strcpy(nbuf, name);
X if ((len = strlen(nbuf)) == 0)
X return NULL;
X
X if ( ((c = nbuf[len - 1]) == '\\' || c == '/') && (len > 1) )
X {
X nbuf[len - 1] = 0;
X --len;
X
X if ( nbuf[len - 1] == ':' )
X {
X strcpy(nbuf+len, "\\.");
X len += 2;
X }
X }
X else
X if ( nbuf[len - 1] == ':' )
X {
X strcpy(nbuf+len, ".");
X ++len;
X }
X
X /* GRR: Borland and Watcom C return non-zero on wildcards... < 0 ? */
X if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
X {
X Trace((stderr, "opendir: stat(%s) returns negative or not directory\n",
X nbuf));


X return NULL;
X }
X

X if ( (dirp = malloc(sizeof(DIR))) == NULL )
X return NULL;
X
X if ( nbuf[len - 1] == '.' && (len == 1 || nbuf[len - 2] != '.') )
X strcpy(nbuf+len-1, "*");
X else
X if ( ((c = nbuf[len - 1]) == '\\' || c == '/') && (len == 1) )
X strcpy(nbuf+len, "*");
X else
X strcpy(nbuf+len, "\\*");
X
X /* len is no longer correct (but no longer needed) */
X Trace((stderr, "opendir: nbuf = [%s]\n", nbuf));
X
X dirp -> dd_loc = 0;
X dirp -> dd_contents = dirp -> dd_cp = NULL;
X
X if ((s = getdirent(nbuf)) == NULL)
X return dirp;
X
X do
X {
X if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
X ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) )
X {
X if (dp)
X free(dp);
X free_dircontents(dirp -> dd_contents);
X


X return NULL;
X }
X

X if (dirp -> dd_contents)
X {
X dirp -> dd_cp -> _d_next = dp;
X dirp -> dd_cp = dirp -> dd_cp -> _d_next;
X }
X else
X dirp -> dd_contents = dirp -> dd_cp = dp;
X
X strcpy(dp -> _d_entry, s);
X dp -> _d_next = NULL;
X
X dp -> _d_size = find.cbFile;
X dp -> _d_mode = find.attrFile;
X dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
X dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
X }
X while ((s = getdirent(NULL)) != NULL);
X
X dirp -> dd_cp = dirp -> dd_contents;
X
X return dirp;
X}
X
X
Xvoid closedir(DIR * dirp)
X{
X free_dircontents(dirp -> dd_contents);
X free(dirp);
X}
X
X
Xstruct direct *readdir(DIR * dirp)
X{
X static struct direct dp;
X
X if (dirp -> dd_cp == NULL)
X return NULL;
X
X dp.d_namlen = dp.d_reclen =
X strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
X
X dp.d_ino = 0;
X
X dp.d_size = dirp -> dd_cp -> _d_size;
X dp.d_mode = dirp -> dd_cp -> _d_mode;
X dp.d_time = dirp -> dd_cp -> _d_time;
X dp.d_date = dirp -> dd_cp -> _d_date;
X
X dirp -> dd_cp = dirp -> dd_cp -> _d_next;
X dirp -> dd_loc++;
X
X return &dp;
X}
X
X
X
X#if 0 /* not used in unzip; retained for possibly future use */
X
Xvoid seekdir(DIR * dirp, long off)
X{
X long i = off;
X struct _dircontents *dp;
X
X if (off >= 0)
X {
X for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
X
X dirp -> dd_loc = off - (i + 1);
X dirp -> dd_cp = dp;
X }
X}
X
X
Xlong telldir(DIR * dirp)
X{
X return dirp -> dd_loc;
X}
X


X#endif /* 0 */
X
X

X
Xstatic void free_dircontents(struct _dircontents * dp)
X{
X struct _dircontents *odp;
X
X while (dp)
X {
X if (dp -> _d_entry)
X free(dp -> _d_entry);
X
X dp = (odp = dp) -> _d_next;
X free(odp);
X }
X}
X
X
Xstatic char *getdirent(char *dir)
X{
X int done;
X static int lower;
X
X if (dir != NULL)
X { /* get first entry */
X hdir = HDIR_SYSTEM;
X count = 1;
X done = DosFindFirst(dir, &hdir, attributes, &find, sizeof(find), &count);
X lower = IsFileSystemFAT(dir);
X }
X else /* get next entry */
X done = DosFindNext(hdir, &find, sizeof(find), &count);
X
X if (done == 0)
X {
X if ( lower )
X StringLower(find.achName);
X return find.achName;
X }
X else
X {
X DosFindClose(hdir);
X return NULL;


X }
X}
X
X
X

Xint IsFileSystemFAT(char *dir) /* FAT / HPFS detection */
X{
X static USHORT nLastDrive=(USHORT)(-1), nResult;
X ULONG lMap;
X BYTE bData[64], bName[3];
X#ifdef __32BIT__
X ULONG nDrive, cbData;
X PFSQBUFFER2 pData = (PFSQBUFFER2) bData;
X#else
X USHORT nDrive, cbData;
X PFSQBUFFER pData = (PFSQBUFFER) bData;
X#endif
X
X if ( _osmode == DOS_MODE )
X return TRUE;
X else
X {
X /* We separate FAT and HPFS+other file systems here.
X at the moment I consider other systems to be similar to HPFS,
X i.e. support long file names and case sensitive */
X
X if ( isalpha(dir[0]) && (dir[1] == ':') )
X nDrive = toupper(dir[0]) - '@';
X else
X DosQueryCurrentDisk(&nDrive, &lMap);
X
X if ( nDrive == nLastDrive )
X return nResult;
X
X bName[0] = (char) (nDrive + '@');
X bName[1] = ':';
X bName[2] = 0;
X
X nLastDrive = nDrive;
X cbData = sizeof(bData);
X
X if ( !DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData) )
X nResult = !strcmp(pData -> szFSDName + pData -> cbName, "FAT");
X else
X nResult = FALSE;
X
X /* End of this ugly code */
X return nResult;
X }
X} /* end function IsFileSystemFAT() */


X
X
X
X
X

X/************************/
X/* Function do_wild() */
X/************************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{
X static DIR *dir = NULL;
X static char *dirname, *wildname, matchname[FILNAMSIZ];
X static int firstcall=TRUE, have_dirname, dirnamelen;
X struct direct *file;
X
X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */
X if ((wildname = strrchr(wildspec, '/')) == NULL &&
X (wildname = strrchr(wildspec, ':')) == NULL) {
X dirname = ".";
X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {
X ++wildname; /* point at character after '/' or ':' */
X dirnamelen = wildname - wildspec;
X if ((dirname = (char *)malloc(dirnamelen+1)) == NULL) {
X FPRINTF(stderr, "warning: can't allocate wildcard buffers\n");
X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }
X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
X have_dirname = TRUE;
X }
X Trace((stderr, "do_wild: dirname = [%s]\n", dirname));
X
X if ((dir = opendir(dirname)) != NULL) {
X while ((file = readdir(dir)) != NULL) {
X Trace((stderr, "do_wild: readdir returns %s\n", file->d_name));
X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X Trace((stderr, "do_wild: match() succeeds\n"));
X if (have_dirname) {
X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);
X dir = NULL;
X }
X Trace((stderr, "do_wild: opendir(%s) returns NULL\n", dirname));
X
X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */
X if (dir == NULL) {
X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);


X return (char *)NULL;
X }
X

X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */
X while ((file = readdir(dir)) != NULL)
X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */
X dir = NULL;
X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X


X} /* end function do_wild() */
X

X#endif /* !SFX */


X
X
X
X
X

X/************************/
X/* Function mapattr() */
X/************************/
X
Xint mapattr()
X{
X /* set archive bit (file is not backed up): */
X pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;
X return 0;


X}
X
X
X
X
X

X/************************/
X/* Function mapname() */
X/************************/
X
X/*
X * There are presently two possibilities in OS/2: the output filesystem is
X * FAT, or it is HPFS. If the former, we need to map to FAT, obviously, but
X * we *also* must map to HPFS and store that version of the name in extended
X * attributes. Either way, we need to map to HPFS, so the main mapname
X * routine does that. In the case that the output file system is FAT, an
X * extra filename-mapping routine is called in checkdir(). While it should
X * be possible to determine the filesystem immediately upon entry to mapname(),
X * it is conceivable that the DOS APPEND utility could be added to OS/2 some-
X * day, allowing a FAT directory to be APPENDed to an HPFS drive/path. There-
X * fore we simply check the filesystem at each path component.
X *
X * Note that when alternative IFS's become available/popular, everything will
X * become immensely more complicated. For example, a Minix filesystem would
X * have limited filename lengths like FAT but no extended attributes in which
X * to store the longer versions of the names. A BSD Unix filesystem would
X * support paths of length 1024 bytes or more, but it is not clear that FAT
X * EAs would allow such long .LONGNAME fields or that OS/2 would properly
X * restore such fields when moving files from FAT to the new filesystem.
X *
X * GRR: some or all of the following chars should be checked in either
X * mapname (HPFS) or map2fat (FAT), depending: ,=^+'"[]<>|\t&
X */


X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */

X{ /* 3 if error (skip file), 10 if no memory (skip file), */
X /* IZ_VOL_LABEL if can't do vol label, IZ_CREATED_DIR */


X char pathcomp[FILNAMSIZ]; /* path-component buffer */

X char *pp, *cp=(char *)NULL; /* character pointers */
X char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */


X int quote = FALSE; /* flag: next char is literal */

X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X

X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.

X ---------------------------------------------------------------------------*/
X


X /* can create path as long as not just freshening, or if user told us */

X create_dirs = (!fflag || renamed);


X
X created_dir = FALSE; /* not yet */

X renamed_fullpath = FALSE;
X fnlen = strlen(filename);


X
X/* GRR: for VMS, convert to internal format now or later? or never? */

X if (renamed) {
X cp = filename - 1; /* point to beginning of renamed name... */
X while (*++cp)
X if (*cp == '\\') /* convert backslashes to forward */
X *cp = '/';
X cp = filename;
X /* use temporary rootpath if user gave full pathname */
X if (filename[0] == '/') {
X renamed_fullpath = TRUE;
X pathcomp[0] = '/'; /* copy the '/' and terminate */
X pathcomp[1] = '\0';
X ++cp;
X } else if (isalpha(filename[0]) && filename[1] == ':') {
X renamed_fullpath = TRUE;
X pp = pathcomp;
X *pp++ = *cp++; /* copy the "d:" (+ '/', possibly) */
X *pp++ = *cp++;


X if (*cp == '/')

X *pp++ = *cp++; /* otherwise add "./"? */
X *pp = '\0';
X }
X }
X
X /* pathcomp is ignored unless renamed_fullpath is TRUE: */
X if ((error = checkdir(pathcomp, INIT)) != 0) /* initialize path buffer */
X return error; /* ...unless no mem or vol label on hard disk */
X


X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */

X if (!renamed) { /* cp already set if renamed */


X if (jflag) /* junking directories */
X/* GRR: watch out for VMS version... */
X cp = (char *)strrchr(filename, '/');

X if (cp == (char *)NULL) /* no '/' or not junking dirs */


X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X }
X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X
X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';

X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = (char *)NULL; /* leave directory semi-colons alone */
X break;
X


X case ':':
X *pp++ = '_'; /* drive names not stored in zipfile, */
X break; /* so no colons allowed */
X

X case ';': /* start of VMS version? */

X lastsemi = pp; /* remove VMS version later... */
X *pp++ = ';'; /* but keep semicolon for now */
X break;
X
X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X
X case ' ': /* keep spaces unless specifically */
X if (sflag) /* requested to change to underscore */
X *pp++ = '_';
X else
X *pp++ = ' ';


X break;
X
X default:

X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X


X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X
X /* if not saving them, remove VMS version numbers (appended "###") */

X if (!V_flag && lastsemi) {
X pp = lastsemi + 1; /* semi-colon was kept: expect #'s after */


X while (isdigit((uch)(*pp)))
X ++pp;

X if (*pp == '\0') /* only digits between ';' and end: nuke */


X *lastsemi = '\0';
X }

X
X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.

X ---------------------------------------------------------------------------*/
X
X if (filename[fnlen-1] == '/') {


X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {

X/* GRR: trailing '/'? need to strip or not? */
X FPRINTF(stdout, " creating: %-22s\n", filename);
X if (extra_field) /* zipfile extra field has extended attributes */
X SetEAs(filename, extra_field);
X SetPathInfo(filename, lrec.last_mod_file_date,
X lrec.last_mod_file_time, -1);
X return IZ_CREATED_DIR; /* dir time already set */


X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X
X if (*pathcomp == '\0') {

X FPRINTF(stderr, "mapname: conversion of %s failed\n", filename);


X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);

X Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",
X filename, error));
X
X if (pInfo->vollabel) { /* set the volume label now */
X VOLUMELABEL FSInfoBuf;
X/* GRR: "VOLUMELABEL" defined for IBM C and emx, but haven't checked MSC... */
X
X strcpy(FSInfoBuf.szVolLabel, filename);
X FSInfoBuf.cch = (BYTE)strlen(FSInfoBuf.szVolLabel);
X
X if (QCOND2)
X FPRINTF(stdout, "labelling %c: %-22s\n",
X (char)(nLabelDrive + 'a' - 1), filename);
X if (DosSetFSInfo(nLabelDrive, FSIL_VOLSER, (PBYTE)&FSInfoBuf,
X sizeof(VOLUMELABEL)))
X {
X FPRINTF(stderr, "mapname: error setting volume label\n");
X return 3;
X }
X return 2; /* success: skip the "extraction" quietly */
X }


X
X return error;
X

X} /* end function mapname() */


X
X
X
X
X

X/***********************/
X/* Function checkdir() */
X/***********************/
X
Xint checkdir(pathcomp, flag)
X char *pathcomp;
X int flag;


X/*
X * returns: 1 - (on APPEND_NAME) truncated filename
X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be
X * 4 - path is too long
X * 10 - can't allocate memory for filename buffers
X */

X{
X static int rootlen = 0; /* length of rootpath */
X static char *rootpath; /* user's "extract-to" directory */
X static char *buildpathHPFS; /* full path (so far) to extracted file, */
X static char *buildpathFAT; /* both HPFS/EA (main) and FAT versions */
X static char *endHPFS; /* corresponding pointers to end of */
X static char *endFAT; /* buildpath ('\0') */


X
X# define FN_MASK 7

X# define FUNCTION (flag & FN_MASK)
X
X
X
X/*---------------------------------------------------------------------------
X APPEND_DIR: append the path component to the path being built and check
X for its existence. If doesn't exist and we are creating directories, do
X so for this one; else signal success or error as appropriate.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_DIR) {


X char *p = pathcomp;

X int longdirEA, too_long=FALSE;
X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));
X while ((*endHPFS = *p++) != '\0') /* copy to HPFS filename */
X ++endHPFS;
X if (IsFileNameValid(buildpathHPFS)) {
X longdirEA = FALSE;
X p = pathcomp;
X while ((*endFAT = *p++) != '\0') /* copy to FAT filename, too */
X ++endFAT;
X } else {
X longdirEA = TRUE;
X/* GRR: check error return? */
X map2fat(pathcomp, &endFAT); /* map, put in FAT fn, update endFAT */
X }
X
X /* GRR: could do better check, see if overrunning buffer as we go:
X * check endHPFS-buildpathHPFS after each append, set warning variable
X * if within 20 of FILNAMSIZ; then if var set, do careful check when
X * appending. Clear variable when begin new path. */
X
X /* next check: need to append '/', at least one-char name, '\0' */
X if ((endHPFS-buildpathHPFS) > FILNAMSIZ-3)
X too_long = TRUE; /* check if extracting dir? */
X#ifdef MSC /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */
X if (GetFileTime(buildpathFAT) == -1 || stat(buildpathFAT, &statbuf))
X#else
X if (stat(buildpathFAT, &statbuf)) /* path doesn't exist */
X#endif
X {
X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpathHPFS);
X free(buildpathFAT);
X return 2; /* path doesn't exist: nothing to do */
X }
X if (too_long) { /* GRR: should allow FAT extraction w/o EAs */
X FPRINTF(stderr, "checkdir error: path too long: %s\n",
X buildpathHPFS);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);
X return 4; /* no room for filenames: fatal */
X }
X if (MKDIR(buildpathFAT, 0777) == -1) { /* create the directory */
X FPRINTF(stderr, "checkdir error: can't create %s\n\
X unable to process %s.\n", buildpathFAT, filename);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X /* only set EA if creating directory */
X/* GRR: need trailing '/' before function call? */
X if (longdirEA) {
X#ifdef DEBUG
X int e =
X#endif
X SetLongNameEA(buildpathFAT, pathcomp);
X Trace((stderr, "APPEND_DIR: SetLongNameEA() returns %d\n", e));
X }
X } else if (!S_ISDIR(statbuf.st_mode)) {
X FPRINTF(stderr, "checkdir error: %s exists but is not directory\n\
X unable to process %s.\n", buildpathFAT, filename);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);
X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {
X FPRINTF(stderr, "checkdir error: path too long: %s\n",
X buildpathHPFS);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);
X return 4; /* no room for filenames: fatal */
X }
X *endHPFS++ = '/';
X *endFAT++ = '/';
X *endHPFS = *endFAT = '\0';
X Trace((stderr, "buildpathHPFS now = [%s]\n", buildpathHPFS));
X Trace((stderr, "buildpathFAT now = [%s]\n", buildpathFAT));
X return 0;
X
X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------
X GETPATH: copy full FAT path to the string pointed at by pathcomp (want
X filename to reflect name used on disk, not EAs; if full path is HPFS,
X buildpathFAT and buildpathHPFS will be identical). Also free both paths.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {
X Trace((stderr, "getting and freeing FAT path [%s]\n", buildpathFAT));
X Trace((stderr, "freeing HPFS path [%s]\n", buildpathHPFS));
X strcpy(pathcomp, buildpathFAT);
X free(buildpathFAT);
X free(buildpathHPFS);
X buildpathHPFS = buildpathFAT = endHPFS = endFAT = (char *)NULL;


X return 0;
X }
X

X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {


X char *p = pathcomp;

X int error = 0;
X

X Trace((stderr, "appending filename [%s]\n", pathcomp));
X while ((*endHPFS = *p++) != '\0') { /* copy to HPFS filename */
X ++endHPFS;
X if ((endHPFS-buildpathHPFS) >= FILNAMSIZ) {
X *--endHPFS = '\0';
X FPRINTF(stderr, "checkdir warning: path too long; truncating\n\
X %s\n -> %s\n", filename, buildpathHPFS);
X fflush(stderr);
X error = 1; /* filename truncated */
X }
X }
X
X/* GRR: how can longnameEA ever be set before this point??? we don't want
X * to save the original name to EAs if user renamed it, do we?
X *
X * if (!longnameEA && ((longnameEA = !IsFileNameValid(name)) != 0))
X */
X if (pInfo->vollabel || IsFileNameValid(buildpathHPFS)) {
X longnameEA = FALSE;
X p = pathcomp;
X while ((*endFAT = *p++) != '\0') /* copy to FAT filename, too */
X ++endFAT;
X } else {
X longnameEA = TRUE;
X if ((lastpathcomp = (char *)malloc(strlen(pathcomp)+1)) ==
X (char *)NULL)
X {
X FPRINTF(stderr,
X "checkdir warning: can't save longname EA: out of memory\n");
X longnameEA = FALSE;
X error = 1; /* can't set .LONGNAME extended attribute */
X } else /* used and freed in close_outfile() */
X strcpy(lastpathcomp, pathcomp);
X map2fat(pathcomp, &endFAT); /* map, put in FAT fn, update endFAT */
X }
X Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n",
X buildpathHPFS, buildpathFAT));
X
X return error; /* could check for existence, prompt for new name... */
X
X } /* end if (FUNCTION == APPEND_NAME) */
X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == INIT) {
X Trace((stderr, "initializing buildpathHPFS and buildpathFAT to "));
X if ((buildpathHPFS = (char *)malloc(fnlen+rootlen+1)) == (char *)NULL)
X return 10;
X if ((buildpathFAT = (char *)malloc(fnlen+rootlen+1)) == (char *)NULL) {
X free(buildpathHPFS);
X return 10;
X }
X if (pInfo->vollabel) { /* use root or renamed path, but don't store */
X/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
X if (renamed_fullpath && pathcomp[1] == ':')
X *buildpathHPFS = ToLower(*pathcomp);
X else if (!renamed_fullpath && rootpath && rootpath[1] == ':')
X *buildpathHPFS = ToLower(*rootpath);
X else {
X ULONG lMap;
X DosQueryCurrentDisk(&nLabelDrive, &lMap);
X *buildpathHPFS = (char)(nLabelDrive - 1 + 'a');
X }
X nLabelDrive = *buildpathHPFS - 'a' + 1; /* save for mapname() */
X if (volflag == 0 || *buildpathHPFS < 'a' || /* no labels/bogus? */
X (volflag == 1 && !isfloppy(nLabelDrive))) { /* -$: no fixed */
X free(buildpathHPFS);
X free(buildpathFAT);
X return IZ_VOL_LABEL; /* skipping with message */
X }
X *buildpathHPFS = '\0';
X } else if (renamed_fullpath) /* pathcomp = valid data */
X strcpy(buildpathHPFS, pathcomp);
X else if (rootlen > 0)
X strcpy(buildpathHPFS, rootpath);
X else
X *buildpathHPFS = '\0';
X endHPFS = buildpathHPFS;
X endFAT = buildpathFAT;
X while ((*endFAT = *endHPFS) != '\0') {
X ++endFAT;
X ++endHPFS;
X }
X Trace((stderr, "[%s]\n", buildpathHPFS));


X return 0;
X }
X

X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line. Note that under OS/2 and MS-DOS, if a candidate extract-to
X directory specification includes a drive letter (leading "x:"), it is
X treated just as if it had a trailing '/'--that is, one directory level
X will be created if the path doesn't exist, unless this is otherwise pro-
X hibited (e.g., freshening).
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));
X if (pathcomp == (char *)NULL) {
X rootlen = 0;
X return 0;
X }
X if ((rootlen = strlen(pathcomp)) > 0) {
X int had_trailing_pathsep=FALSE, has_drive=FALSE, xtra=2;
X
X if (isalpha(pathcomp[0]) && pathcomp[1] == ':')
X has_drive = TRUE; /* drive designator */
X if (pathcomp[rootlen-1] == '/') {
X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (has_drive && (rootlen == 2)) {
X if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */
X xtra = 3; /* room for '.' + '/' + 0 at end of "x:" */
X } else if (rootlen > 0) { /* need not check "x:." and "x:/" */
X#ifdef MSC /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */
X if (GetFileTime(pathcomp) == -1 ||
X SSTAT(pathcomp, &statbuf) || !S_ISDIR(statbuf.st_mode))
X#else
X if (SSTAT(pathcomp, &statbuf) || !S_ISDIR(statbuf.st_mode))
X#endif
X { /* path does not exist */
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || (!has_drive && !had_trailing_pathsep)
X#endif
X ) {
X rootlen = 0;
X return 2; /* treat as stored file */
X }
X /* create directory (could add loop here to scan pathcomp
X * and create more than one level, but really necessary?) */
X if (MKDIR(pathcomp, 0777) == -1) {
X FPRINTF(stderr,
X "checkdir: can't create extraction directory: %s\n",
X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, */
X return 3; /* failed: file exists, or need 2+ levels */
X }
X }
X }
X if ((rootpath = (char *)malloc(rootlen+xtra)) == (char *)NULL) {
X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);
X if (xtra == 3) /* had just "x:", make "x:." */
X rootpath[rootlen++] = '.';
X rootpath[rootlen++] = '/';
X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));


X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X

X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);


X return 0;
X }
X

X return 99; /* should never reach */
X
X} /* end function checkdir() */


X
X
X
X
X

X/***********************/
X/* Function isfloppy() */ /* more precisely, is it removable? */
X/***********************/
X
Xstatic int isfloppy(nDrive)
X int nDrive; /* 1 == A:, 2 == B:, etc. */
X{
X uch ParmList[1] = {0};
X uch DataArea[1] = {0};
X char Name[3];
X HFILE handle;
X#ifdef __32BIT__
X ULONG rc;
X ULONG action;
X#else
X USHORT rc;
X UINT action;
X#endif
X
X
X Name[0] = (char) (nDrive + 'A' - 1);
X Name[1] = ':';
X Name[2] = 0;
X
X rc = DosOpen(Name, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN,
X OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
X OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0L);
X
X if (rc == ERROR_NOT_READY) /* must be removable */
X return TRUE;
X else if (rc) { /* other error: do default a/b heuristic instead */
X Trace((stderr, "error in DosOpen(DASD): guessing...\n", rc));
X return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;
X }
X
X rc = DosDevIOCtl(DataArea, sizeof(DataArea), ParmList, sizeof(ParmList),
X DSK_BLOCKREMOVABLE, IOCTL_DISK, handle);
X DosClose(handle);
X
X if (rc) { /* again, just check for a/b */
X Trace((stderr, "error in DosDevIOCtl category IOCTL_DISK, function "
X "DSK_BLOCKREMOVABLE\n (rc = 0x%04x): guessing...\n", rc));
X return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;
X } else {
X return DataArea[0] ? FALSE : TRUE;
X }
X} /* end function isfloppy() */


X
X
X
X
X

Xint IsFileNameValid(char *name)
X{
X HFILE hf;
X#ifdef __32BIT__
X ULONG uAction;
X#else
X USHORT uAction;
X#endif
X
X switch( DosOpen(name, &hf, &uAction, 0, 0, FILE_OPEN,
X OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0) )
X {
X case ERROR_INVALID_NAME:
X case ERROR_FILENAME_EXCED_RANGE:
X return FALSE;
X case NO_ERROR:
X DosClose(hf);
X default:
X return TRUE;


X }
X}
X
X
X
X
X

X/**********************/
X/* Function map2fat() */
X/**********************/
X
Xvoid map2fat(pathcomp, pEndFAT)
X char *pathcomp, **pEndFAT;
X{
X char *ppc = pathcomp; /* variable pointer to pathcomp */
X char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */
X char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */
X char *last_dot = (char *)NULL; /* last dot not converted to underscore */


X int dotname = FALSE; /* flag: path component begins with dot */

X /* ("." and ".." don't count) */


X register unsigned workch; /* hold the character being tested */
X
X

X /* Only need check those characters which are legal in HPFS but not
X * in FAT: to get here, must already have passed through mapname.
X * (GRR: oops, small bug--if char was quoted, no longer have any
X * knowledge of that.) Also must truncate path component to ensure
X * 8.3 compliance...
X */
X while ((workch = (uch)*ppc++) != 0) {
X switch (workch) {
X case '[':
X case ']':
X *pEnd++ = '_'; /* convert brackets to underscores */
X break;
X
X case '.':
X if (pEnd == *pEndFAT) { /* nothing appended yet... */
X if (*ppc == '\0') /* don't bother appending a */
X break; /* "./" component to the path */
X else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */
X *pEnd++ = '.'; /* add first dot, unchanged... */
X ++ppc; /* skip second dot, since it will */
X } else { /* be "added" at end of if-block */
X *pEnd++ = '_'; /* FAT doesn't allow null filename */
X dotname = TRUE; /* bodies, so map .exrc -> _.exrc */
X } /* (extra '_' now, "dot" below) */
X } else if (dotname) { /* found a second dot, but still */
X dotname = FALSE; /* have extra leading underscore: */
X *pEnd = '\0'; /* remove it by shifting chars */
X pEnd = *pEndFAT + 1; /* left one space (e.g., .p1.p2: */
X while (pEnd[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */
X *pEnd = pEnd[1]; /* finished) [opt.: since first */
X ++pEnd; /* two chars are same, can start */
X } /* shifting at second position] */
X }
X last_dot = pEnd; /* point at last dot so far... */
X *pEnd++ = '_'; /* convert dot to underscore for now */
X break;
X
X default:
X *pEnd++ = (char)workch;
X
X } /* end switch */


X } /* end while loop */
X

X *pEnd = '\0'; /* terminate buildpathFAT */
X
X /* NOTE: keep in mind that pEnd points to the end of the path
X * component, and *pEndFAT still points to the *beginning* of it...
X * Also note that the algorithm does not try to get too fancy:
X * if there are no dots already, the name either gets truncated
X * at 8 characters or the last underscore is converted to a dot
X * (only if more characters are saved that way). In no case is
X * a dot inserted between existing characters.
X */
X if (last_dot == (char *)NULL) { /* no dots: check for underscores... */
X char *plu = strrchr(pBegin, '_'); /* pointer to last underscore */
X
X if (plu == (char *)NULL) { /* no dots, no underscores: truncate at 8 */
X *pEndFAT += 8; /* chars (or could insert '.' and keep 11?) */
X if (*pEndFAT > pEnd)
X *pEndFAT = pEnd; /* oops...didn't have 8 chars to truncate */
X else
X **pEndFAT = '\0';
X } else if (MIN(plu - pBegin, 8) + MIN(pEnd - plu - 1, 3) > 8) {
X last_dot = plu; /* be lazy: drop through to next if-blk */
X } else if ((pEnd - *pEndFAT) > 8) {
X *pEndFAT += 8; /* more fits into just basename than if */
X **pEndFAT = '\0'; /* convert last underscore to dot */
X } else
X *pEndFAT = pEnd; /* whole thing fits into 8 chars or less */
X }
X
X if (last_dot != (char *)NULL) { /* one dot (or two, in the case of */
X *last_dot = '.'; /* "..") is OK: put it back in */
X
X if ((last_dot - pBegin) > 8) {
X char *p=last_dot, *q=pBegin+8;
X int i;
X
X for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */
X *q++ = *p++; /* shift .ext left and trun- */
X *q = '\0'; /* cate/terminate it */
X *pEndFAT = q;
X } else if ((pEnd - last_dot) > 4) { /* too many chars in extension */
X *pEndFAT = last_dot + 4;
X **pEndFAT = '\0';
X } else
X *pEndFAT = pEnd; /* filename is fine; point at terminating zero */
X }
X} /* end function map2fat() */


X
X
X
X
X

Xint SetLongNameEA(char *name, char *longname)
X{
X EAOP eaop;
X FEALST fealst;
X
X eaop.fpFEAList = (PFEALIST) &fealst;
X eaop.fpGEAList = NULL;
X eaop.oError = 0;
X
X strcpy(fealst.szName, ".LONGNAME");
X strcpy(fealst.szValue, longname);
X
X fealst.cbList = sizeof(fealst) - CCHMAXPATH + strlen(fealst.szValue);
X fealst.cbName = (BYTE) strlen(fealst.szName);
X fealst.cbValue = sizeof(USHORT) * 2 + strlen(fealst.szValue);
X
X#ifdef __32BIT__
X fealst.oNext = 0;
X#endif
X fealst.fEA = 0;
X fealst.eaType = 0xFFFD;
X fealst.eaSize = strlen(fealst.szValue);
X
X return DosSetPathInfo(name, FIL_QUERYEASIZE,
X (PBYTE) &eaop, sizeof(eaop), 0);


X}
X
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile() /* only for extracted files, not directories */
X{
X fclose(outfile);
X
X /* set extra fields, both stored-in-zipfile and .LONGNAME flavors */
X if (extra_field)
X SetEAs(filename, extra_field);
X
X if (longnameEA) {
X#ifdef DEBUG
X int e =
X#endif
X SetLongNameEA(filename, lastpathcomp);
X Trace((stderr, "close_outfile: SetLongNameEA() returns %d\n", e));
X free(lastpathcomp);
X }
X
X /* set date/time and permissions */
X SetPathInfo(filename, lrec.last_mod_file_date,
X lrec.last_mod_file_time, pInfo->file_attr);
X
X} /* end function close_outfile() */


X
X
X
X
X

X/******************************/
X/* Function check_for_newer() */
X/******************************/


X
Xint check_for_newer(filename) /* return 1 if existing file newer or equal; */
X char *filename; /* 0 if older; -1 if doesn't exist yet */
X{

X long existing, archive;
X
X if ((existing = GetFileTime(filename)) == -1)
X return DOES_NOT_EXIST;
X archive = ((long) lrec.last_mod_file_date) << 16 | lrec.last_mod_file_time;
X
X return (existing >= archive);


X}
X
X
X
X
X

X#ifndef SFX
X
X/*************************/
X/* Function dateformat() */
X/*************************/
X
Xint dateformat()
X{
X/*-----------------------------------------------------------------------------
X For those operating systems which support it, this function returns a value
X which tells how national convention says that numeric dates are displayed.
X Return values are DF_YMD, DF_DMY and DF_MDY.
X -----------------------------------------------------------------------------*/
X
X switch (GetCountryInfo()) {
X case 0:
X return DF_MDY;
X case 1:
X return DF_DMY;
X case 2:
X return DF_YMD;
X }
X return DF_MDY; /* default if error */
X
X} /* end function dateformat() */


X
X
X
X
X

X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER)
X char buf[80];
X#endif
X
X PRINTF(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */
X "emx+gcc ", __VERSION__,
X# else
X "gcc/2 ", __VERSION__,
X# endif
X#else
X#ifdef __IBMC__
X "IBM C Set/2", (sprintf(buf, " %d.%02d", __IBMC__/100,__IBMC__%100), buf),
X#else
X#ifdef __WATCOMC__
X "Watcom C", (sprintf(buf, " (__WATCOMC__ = %d)", __WATCOMC__), buf),
X#else
X#ifdef __TURBOC__
X# ifdef __BORLANDC__
X "Borland C++",
X# if (__BORLANDC__ < 0x0200)
X " 1.0",
X# else
X# if (__BORLANDC__ == 0x0200)
X " 2.0",
X# else
X# if (__BORLANDC__ == 0x0400)
X " 3.0",
X# else
X# if (__BORLANDC__ == 0x0410)
X " 3.1",
X# else
X " later than 3.1",


X# endif
X# endif
X# endif

X# endif
X# else
X "Turbo C",
X# if (__TURBOC__ >= 661)
X "++ 1.0 or later",
X# else
X# if (__TURBOC__ == 661)
X " 3.0?",
X# else
X# if (__TURBOC__ == 397)
X " 2.0",
X# else
X " 1.0 or 1.5?",


X# endif
X# endif
X# endif

X# endif
X#else
X#ifdef MSC
X "Microsoft C ",
X# ifdef _MSC_VER
X (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf),
X# else
X "5.1 or earlier",
X# endif
X#else


X "unknown compiler", "",

X#endif /* MSC */
X#endif /* __TURBOC__ */
X#endif /* __WATCOMC__ */
X#endif /* __IBMC__ */
X#endif /* __GNUC__ */
X
X "OS/2",
X
X/* GRR: does IBM C/2 identify itself as IBM rather than Microsoft? */
X#if (defined(MSC) || (defined(__WATCOMC__) && !defined(__386__)))
X# if defined(M_I86HM) || defined(__HUGE__)
X " (16-bit, huge)",
X# else
X# if defined(M_I86LM) || defined(__LARGE__)
X " (16-bit, large)",
X# else
X# if defined(M_I86MM) || defined(__MEDIUM__)
X " (16-bit, medium)",
X# else
X# if defined(M_I86CM) || defined(__COMPACT__)
X " (16-bit, compact)",
X# else
X# if defined(M_I86SM) || defined(__SMALL__)
X " (16-bit, small)",
X# else
X# if defined(M_I86TM) || defined(__TINY__)
X " (16-bit, tiny)",
X# else
X " (16-bit)",


X# endif
X# endif
X# endif
X# endif
X# endif
X# endif

X#else
X " 2.x (32-bit)",
X#endif


X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X

X /* temporary debugging code for Borland compilers only */
X#ifdef __TURBOC__
X PRINTF("\t(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__, __TURBOC__);
X#ifdef __BORLANDC__
X PRINTF("\t(__BORLANDC__ = 0x%04x)\n", __BORLANDC__);
X#else
X PRINTF("\tdebug(__BORLANDC__ not defined)\n");
X#endif
X#ifdef __TCPLUSPLUS__
X PRINTF("\t(__TCPLUSPLUS__ = 0x%04x)\n", __TCPLUSPLUS__);
X#else
X PRINTF("\tdebug(__TCPLUSPLUS__ not defined)\n");
X#endif
X#ifdef __BCPLUSPLUS__
X PRINTF("\t(__BCPLUSPLUS__ = 0x%04x)\n\n", __BCPLUSPLUS__);
X#else
X PRINTF("\tdebug(__BCPLUSPLUS__ not defined)\n\n");
X#endif
X#endif /* __TURBOC__ */
X


X} /* end function version() */
X

X#endif /* !SFX */


X
X
X
X
X

Xstatic unsigned char cUpperCase[256], cLowerCase[256];
Xstatic BOOL bInitialized;
X
X/* Initialize the tables of upper- and lowercase characters, including
X handling of country-dependent characters. */
X
Xstatic void InitNLS(void)
X{
X unsigned nCnt, nU;
X COUNTRYCODE cc;
X
X bInitialized = TRUE;
X
X for ( nCnt = 0; nCnt < 256; nCnt++ )
X cUpperCase[nCnt] = cLowerCase[nCnt] = (unsigned char) nCnt;
X
X cc.country = cc.codepage = 0;
X DosMapCase(sizeof(cUpperCase), &cc, (PCHAR) cUpperCase);
X
X for ( nCnt = 0; nCnt < 256; nCnt++ )
X {
X nU = cUpperCase[nCnt];
X if (nU != nCnt && cLowerCase[nU] == (unsigned char) nU)
X cLowerCase[nU] = (unsigned char) nCnt;
X }
X
X for ( nCnt = 'A'; nCnt <= 'Z'; nCnt++ )
X cLowerCase[nCnt] = (unsigned char) (nCnt - 'A' + 'a');
X}
X
X
Xint IsUpperNLS(int nChr)
X{
X if (!bInitialized)
X InitNLS();
X return (cUpperCase[nChr] == (unsigned char) nChr);
X}
X
X
Xint ToLowerNLS(int nChr)
X{
X if (!bInitialized)
X InitNLS();
X return cLowerCase[nChr];
X}
X
X
Xchar *StringLower(char *szArg)
X{
X unsigned char *szPtr;
X
X if (!bInitialized)
X InitNLS();
X for ( szPtr = szArg; *szPtr; szPtr++ )
X *szPtr = cLowerCase[*szPtr];
X return szArg;
X}
X
X
X#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
Xvoid DebugMalloc(void)
X{
X _dump_allocated(0); /* print out debug malloc memory statistics */
X}
X#endif
END_OF_FILE
if test 57190 -ne `wc -c <'unzip-5.12/os2/os2.c'`; then
echo shar: \"'unzip-5.12/os2/os2.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/os2.c'
fi
echo shar: End of archive 5 \(of 20\).
cp /dev/null ark5isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:14:56 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 71
Archive-name: unzip/part06

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/extract.c unzip-5.12/vms/cmdline.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:39 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 6 (of 20)."'
if test -f 'unzip-5.12/extract.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/extract.c'\"
else
echo shar: Extracting \"'unzip-5.12/extract.c'\" \(46513 characters\)
sed "s/^X//" >'unzip-5.12/extract.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X extract.c
X
X This file contains the high-level routines ("driver routines") for extrac-
X ting and testing zipfile members. It calls the low-level routines in files
X explode.c, inflate.c, unreduce.c and unshrink.c.


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
X#include "crypt.h"


X#ifdef MSWIN
X# include "wizunzip.h"

X# include "replace.h"
X#endif
X
Xint newfile; /* used also in file_io.c (flush()) */
Xulg *crc_32_tab; /* used also in file_io.c and crypt.c (full version) */
X
Xstatic void makecrc __((void));
Xstatic int store_info __((void));
Xstatic int extract_or_test_member __((void));
X
X
X/*******************************/
X/* Strings used in extract.c */
X/*******************************/
X
Xstatic char Far VersionMsg[] =
X " skipping: %-22s need %s compat. v%u.%u (can do v%u.%u)\n";
Xstatic char Far ComprMsg[] =
X " skipping: %-22s compression method %d\n";
Xstatic char Far FilNamMsg[] =
X "%s: bad filename length (%s)\n";
Xstatic char Far ExtFieldMsg[] =
X "%s: bad extra field length (%s)\n";
Xstatic char Far OffsetMsg[] =
X "file #%d: bad zipfile offset (%s): %ld\n";
Xstatic char Far ExtractMsg[] =
X "%8sing: %-22s %s%s";
X#ifndef SFX
X static char Far LengthMsg[] =
X "%s %s: %ld bytes required to uncompress to %lu bytes;\n %s\
X supposed to require %lu bytes%s%s%s\n";
X#endif
X
Xstatic char Far BadFileCommLength[] = "\n%s: bad file comment length\n";
Xstatic char Far LocalHdrSig[] = "local header sig";
Xstatic char Far BadLocalHdr[] = "\nfile #%d: bad local header\n";
Xstatic char Far AttemptRecompensate[] = " (attempting to re-compensate)\n";
Xstatic char Far SkipVolumeLabel[] = " skipping: %-22s %svolume label\n";
Xstatic char Far ReplaceQuery[] =
X "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
Xstatic char Far AssumeNone[] = " NULL\n(assuming [N]one)\n";
Xstatic char Far NewName[] = "new name: ";
Xstatic char Far InvalidResponse[] = "error: invalid response [%c]\n";
Xstatic char Far ErrorInArchive[] = "At least one %serror was detected in %s.\n";
Xstatic char Far ZeroFilesTested[] = "Caution: zero files tested in %s.\n";
X
X#ifndef VMS
X static char Far VMSFormat[] =
X "\n%s: stored in VMS format. Extract anyway? (y/n) ";
X#endif
X
X#ifdef CRYPT
X static char Far SkipCantGetPasswd[] =
X " skipping: %-22s unable to get password\n";
X static char Far SkipIncorrectPasswd[] =
X " skipping: %-22s incorrect password\n";
X static char Far FilesSkipBadPasswd[] =
X "%d file%s skipped because of incorrect password.\n";
X static char Far MaybeBadPasswd[] =
X " (may instead be incorrect password)\n";
X#else
X static char Far SkipEncrypted[] =
X " skipping: %-22s encrypted (not supported)\n";
X#endif
X
Xstatic char Far NoErrInCompData[] =
X "No errors detected in compressed data of %s.\n";
Xstatic char Far NoErrInTestedFiles[] =
X "No errors detected in %s for the %d file%s tested.\n";
Xstatic char Far FilesSkipped[] =
X "%d file%s skipped because of unsupported compression or encoding.\n";
X
Xstatic char Far ErrUnzipFile[] = " error: %s%s %s\n";
Xstatic char Far ErrUnzipNoFile[] = "\n error: %s%s\n";
Xstatic char Far NotEnoughMem[] = "not enough memory to ";
Xstatic char Far InvalidComprData[] = "invalid compressed data to ";
Xstatic char Far Inflate[] = "inflate";
X
X#ifndef SFX
X static char Far Explode[] = "explode";
X static char Far Unshrink[] = "unshrink";
X#endif
X
Xstatic char Far FileUnknownCompMethod[] = "%s: unknown compression method\n";
Xstatic char Far BadCRC[] = " bad CRC %08lx (should be %08lx)\n";
Xstatic char Far UnsupportedExtraField[] =
X "warning: unsupported extra field compression type--skipping\n";
Xstatic char Far BadExtraFieldCRC[] =
X "error [%s]: bad extra field CRC %08lx (should be %08lx)\n";


X
X
X
X
X

X/**************************************/
X/* Function extract_or_test_files() */
X/**************************************/
X
Xint extract_or_test_files() /* return PK-type error code */
X{
X uch *cd_inptr;
X int cd_incnt, error, error_in_archive=PK_COOL;
X int i, j, renamed, query, len, filnum=(-1), blknum=0;
X int *fn_matched=NULL, *xn_matched=NULL;
X ush members_remaining, num_skipped=0, num_bad_pwd=0;
X long cd_bufstart, bufstart, inbuf_offset, request;
X LONGINT old_extra_bytes=0L;
X static min_info info[DIR_BLKSIZ];
X
X
X/*---------------------------------------------------------------------------
X The basic idea of this function is as follows. Since the central di-
X rectory lies at the end of the zipfile and the member files lie at the
X beginning or middle or wherever, it is not very desirable to simply
X read a central directory entry, jump to the member and extract it, and
X then jump back to the central directory. In the case of a large zipfile
X this would lead to a whole lot of disk-grinding, especially if each mem-
X ber file is small. Instead, we read from the central directory the per-
X tinent information for a block of files, then go extract/test the whole
X block. Thus this routine contains two small(er) loops within a very
X large outer loop: the first of the small ones reads a block of files
X from the central directory; the second extracts or tests each file; and
X the outer one loops over blocks. There's some file-pointer positioning
X stuff in between, but that's about it. Btw, it's because of this jump-
X ing around that we can afford to be lenient if an error occurs in one of
X the member files: we should still be able to go find the other members,
X since we know the offset of each from the beginning of the zipfile.
X ---------------------------------------------------------------------------*/
X
X pInfo = info;
X members_remaining = ecrec.total_entries_central_dir;
X#if (defined(CRYPT) || !defined(NO_ZIPINFO))
X newzip = TRUE;
X#endif
X
X /* malloc space for CRC table and generate it */
X if ((crc_32_tab = (ulg *)malloc(256*sizeof(ulg))) == (ulg *)NULL)
X return PK_MEM2;
X makecrc();
X
X /* malloc space for check on unmatched filespecs (OK if one or both NULL) */


X if (filespecs > 0 &&

X (fn_matched=(int *)malloc(filespecs*sizeof(int))) != (int *)NULL)
X for (i = 0; i < filespecs; ++i)
X fn_matched[i] = FALSE;


X if (xfilespecs > 0 &&

X (xn_matched=(int *)malloc(xfilespecs*sizeof(int))) != (int *)NULL)
X for (i = 0; i < xfilespecs; ++i)
X xn_matched[i] = FALSE;
X
X/*---------------------------------------------------------------------------
X Begin main loop over blocks of member files. We know the entire central
X directory is on this disk: we would not have any of this information un-
X less the end-of-central-directory record was on this disk, and we would
X not have gotten to this routine unless this is also the disk on which
X the central directory starts. In practice, this had better be the ONLY
X disk in the archive, but maybe someday we'll add multi-disk support.
X ---------------------------------------------------------------------------*/
X
X while (members_remaining) {
X j = 0;
X
X /*
X * Loop through files in central directory, storing offsets, file
X * attributes, case-conversion and text-conversion flags until block
X * size is reached.
X */
X
X while (members_remaining && (j < DIR_BLKSIZ)) {
X --members_remaining;
X pInfo = &info[j];


X
X if (readbuf(sig, 4) == 0) {

X error_in_archive = PK_EOF;
X members_remaining = 0; /* ...so no more left to do */
X break;
X }


X if (strncmp(sig, central_hdr_sig, 4)) { /* just to make sure */
X FPRINTF(stderr, LoadFarString(CentSigMsg), j); /* sig not found */

X FPRINTF(stderr, LoadFarString(ReportMsg)); /* check binary transfers */
X error_in_archive = PK_BADERR;
X members_remaining = 0; /* ...so no more left to do */
X break;
X }
X /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
X if ((error = process_cdir_file_hdr()) != PK_COOL) {
X error_in_archive = error; /* only PK_EOF defined */
X members_remaining = 0; /* ...so no more left to do */
X break;
X }
X if ((error = do_string(crec.filename_length,FILENAME)) != PK_COOL) {
X if (error > error_in_archive)
X error_in_archive = error;
X if (error > PK_WARN) { /* fatal: no more left to do */
X FPRINTF(stderr, LoadFarString(FilNamMsg), filename, "central");
X members_remaining = 0;
X break;
X }
X }
X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0)
X {
X if (error > error_in_archive)


X error_in_archive = error;
X if (error > PK_WARN) { /* fatal */

X FPRINTF(stderr, LoadFarString(ExtFieldMsg), filename, "central");
X members_remaining = 0;
X break;
X }
X }
X if ((error = do_string(crec.file_comment_length,SKIP)) != PK_COOL) {
X if (error > error_in_archive)


X error_in_archive = error;
X if (error > PK_WARN) { /* fatal */

X FPRINTF(stderr, LoadFarString(BadFileCommLength),
X filename);
X members_remaining = 0;
X break;
X }
X }
X if (process_all_files) {
X if (store_info())
X ++j; /* file is OK; info[] stored; continue with next */
X else
X ++num_skipped;
X } else {
X int do_this_file = FALSE;


X char **pfn = pfnames-1;
X

X while (*++pfn)
X if (match(filename, *pfn, C_flag)) {

X do_this_file = TRUE; /* ^-- ignore case or not? */


X if (fn_matched)
X fn_matched[pfn-pfnames] = TRUE;
X break; /* found match, so stop looping */
X }
X if (do_this_file) { /* check if this is an excluded file */
X char **pxn = pxnames-1;
X
X while (*++pxn)

X if (match(filename, *pxn, C_flag)) {

X do_this_file = FALSE; /* ^-- ignore case or not? */


X if (xn_matched)
X xn_matched[pxn-pxnames] = TRUE;
X break;
X }
X }

X if (do_this_file)
X if (store_info())
X ++j; /* file is OK */
X else
X ++num_skipped; /* unsupp. compression or encryption */
X } /* end if (process_all_files) */
X
X
X } /* end while-loop (adding files to current block) */
X
X /* save position in central directory so can come back later */
X cd_bufstart = cur_zipfile_bufstart;
X cd_inptr = inptr;
X cd_incnt = incnt;
X
X /*-----------------------------------------------------------------------
X Second loop: process files in current block, extracting or testing
X each one.
X -----------------------------------------------------------------------*/
X
X for (i = 0; i < j; ++i) {
X filnum = i + blknum*DIR_BLKSIZ;
X pInfo = &info[i];
X
X /* if the target position is not within the current input buffer
X * (either haven't yet read far enough, or (maybe) skipping back-
X * ward), skip to the target position and reset readbuf(). */
X
X /* LSEEK(pInfo->offset): */
X request = pInfo->offset + extra_bytes;
X inbuf_offset = request % INBUFSIZ;
X bufstart = request - inbuf_offset;
X
X Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
X request, inbuf_offset));
X Trace((stderr,
X "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
X bufstart, cur_zipfile_bufstart));
X if (request < 0) {
X FPRINTF(stderr, LoadFarStringSmall(SeekMsg), zipfn,
X LoadFarString(ReportMsg));
X error_in_archive = PK_ERR;
X if (filnum == 0 && extra_bytes != 0L) {
X FPRINTF(stderr, LoadFarString(AttemptRecompensate));
X old_extra_bytes = extra_bytes;
X extra_bytes = 0L;
X request = pInfo->offset; /* could also check if this != 0 */
X inbuf_offset = request % INBUFSIZ;
X bufstart = request - inbuf_offset;
X Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
X request, inbuf_offset));
X Trace((stderr,
X "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
X bufstart, cur_zipfile_bufstart));
X } else {
X error_in_archive = PK_BADERR;
X continue; /* this one hosed; try next */
X }
X }
X /* try again */
X if (request < 0) {
X Trace((stderr, "debug: recompensated request still < 0\n"));
X FPRINTF(stderr, LoadFarStringSmall(SeekMsg), zipfn,
X LoadFarString(ReportMsg));
X error_in_archive = PK_BADERR;
X continue;
X } else if (bufstart != cur_zipfile_bufstart) {
X Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
X cur_zipfile_bufstart = lseek(zipfd,(LONGINT)bufstart,SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) <= 0) {
X FPRINTF(stderr, LoadFarString(OffsetMsg), filnum, "lseek",
X bufstart);
X error_in_archive = PK_BADERR;
X continue; /* can still do next file */
X }
X inptr = inbuf + (int)inbuf_offset;
X incnt -= (int)inbuf_offset;
X } else {
X incnt += (inptr-inbuf) - (int)inbuf_offset;
X inptr = inbuf + (int)inbuf_offset;
X }
X
X /* should be in proper position now, so check for sig */
X if (readbuf(sig, 4) == 0) { /* bad offset */
X FPRINTF(stderr, LoadFarString(OffsetMsg), filnum, "EOF",
X request);
X error_in_archive = PK_BADERR;
X continue; /* but can still try next one */
X }
X if (strncmp(sig, local_hdr_sig, 4)) {
X FPRINTF(stderr, LoadFarString(OffsetMsg), filnum,
X LoadFarStringSmall(LocalHdrSig), request);
X error_in_archive = PK_ERR;
X if ((filnum == 0 && extra_bytes != 0L) ||
X (extra_bytes == 0L && old_extra_bytes != 0L)) {
X FPRINTF(stderr, LoadFarString(AttemptRecompensate));
X if (extra_bytes) {
X old_extra_bytes = extra_bytes;
X extra_bytes = 0L;
X } else
X extra_bytes = old_extra_bytes; /* third attempt */
X LSEEK(pInfo->offset)
X if (readbuf(sig, 4) == 0) { /* bad offset */
X FPRINTF(stderr, LoadFarString(OffsetMsg), filnum, "EOF",
X request);
X error_in_archive = PK_BADERR;
X continue; /* but can still try next one */
X }
X if (strncmp(sig, local_hdr_sig, 4)) {
X FPRINTF(stderr, LoadFarString(OffsetMsg), filnum,
X LoadFarStringSmall(LocalHdrSig), request);
X error_in_archive = PK_BADERR;
X continue;
X }
X } else
X continue; /* this one hosed; try next */
X }
X if ((error = process_local_file_hdr()) != PK_COOL) {
X FPRINTF(stderr, LoadFarString(BadLocalHdr), filnum);
X error_in_archive = error; /* only PK_EOF defined */
X continue; /* can still try next one */
X }
X if ((error = do_string(lrec.filename_length,FILENAME)) != PK_COOL) {
X if (error > error_in_archive)
X error_in_archive = error;
X if (error > PK_WARN) {
X FPRINTF(stderr, LoadFarString(FilNamMsg), filename, "local");
X continue; /* go on to next one */
X }
X }


X if (extra_field != (uch *)NULL) {
X free(extra_field);
X extra_field = (uch *)NULL;
X }

X if ((error = do_string(lrec.extra_field_length,EXTRA_FIELD)) != 0) {
X if (error > error_in_archive)
X error_in_archive = error;
X if (error > PK_WARN) {
X FPRINTF(stderr, LoadFarString(ExtFieldMsg), filename, "local");
X continue; /* go on */
X }
X }
X
X /*
X * just about to extract file: if extracting to disk, check if
X * already exists, and if so, take appropriate action according to
X * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
X * loop because we don't store the possibly renamed filename[] in
X * info[])
X */
X if (!tflag && !cflag) {
X renamed = FALSE; /* user hasn't renamed output file yet */
X
Xstartover:
X query = FALSE;
X#ifdef MACOS
X macflag = (pInfo->hostnum == MAC_);
X#endif
X /* mapname can create dirs if not freshening or if renamed */
X if ((error = mapname(renamed)) > PK_WARN) {
X if (error == IZ_CREATED_DIR) {
X
X /* GRR: add code to set times/attribs on dirs--
X * save to list, sort when done (a la zip), set
X * times/attributes on deepest dirs first */
X
X } else if (error == IZ_VOL_LABEL) {
X FPRINTF(stderr,
X LoadFarString(SkipVolumeLabel), filename,
X#ifdef DOS_NT_OS2
X volflag? "hard disk " :
X#endif
X "");
X /* if (!error_in_archive)
X error_in_archive = PK_WARN; */
X } else if (error > PK_ERR && error_in_archive < PK_ERR)
X error_in_archive = PK_ERR;
X Trace((stderr, "mapname(%s) returns error = %d\n", filename,
X error));
X continue; /* go on to next file */
X }
X
X switch (check_for_newer(filename)) {
X case DOES_NOT_EXIST:
X if (fflag && !renamed) /* don't skip if just renamed */
X continue; /* freshen (no new files): skip */
X break;
X case EXISTS_AND_OLDER:
X if (overwrite_none)
X continue; /* never overwrite: skip file */
X if (!overwrite_all && !force_flag)
X query = TRUE;
X break;
X case EXISTS_AND_NEWER: /* (or equal) */
X if (overwrite_none || (uflag && !renamed))
X continue; /* skip if update/freshen & orig name */
X if (!overwrite_all && !force_flag)
X query = TRUE;
X break;
X }
X if (query) {
X#ifdef MSWIN
X FARPROC lpfnprocReplace;
X int ReplaceDlgRetVal; /* replace dialog return value */
X
X ShowCursor(FALSE); /* turn off cursor */
X SetCursor(hSaveCursor); /* restore the cursor */
X lpfnprocReplace = MakeProcInstance(ReplaceProc, hInst);
X ReplaceDlgRetVal = DialogBoxParam(hInst, "Replace",
X hWndMain, lpfnprocReplace, (DWORD)(LPSTR)filename);
X FreeProcInstance(lpfnprocReplace);
X hSaveCursor = SetCursor(hHourGlass);
X ShowCursor(TRUE);
X switch (ReplaceDlgRetVal) {
X case IDM_REPLACE_RENAME:
X renamed = TRUE;
X goto startover;
X case IDM_REPLACE_YES:
X break;
X case IDM_REPLACE_ALL:
X overwrite_all = TRUE;
X overwrite_none = FALSE; /* just to make sure */
X break;
X case IDM_REPLACE_NONE:
X overwrite_none = TRUE;
X overwrite_all = FALSE; /* make sure */
X force_flag = FALSE; /* ditto */
X /* FALL THROUGH, skip */
X case IDM_REPLACE_NO:
X continue;
X }
X#else /* !MSWIN */
Xreprompt:
X FPRINTF(stderr, LoadFarString(ReplaceQuery), filename);
X FFLUSH(stderr);
X if (fgets(answerbuf, 9, stdin) == (char *)NULL) {
X FPRINTF(stderr, LoadFarString(AssumeNone));
X FFLUSH(stderr);
X *answerbuf = 'N';
X if (!error_in_archive)
X error_in_archive = 1; /* not extracted: warning */
X }
X switch (*answerbuf) {
X case 'A': /* dangerous option: force caps */
X overwrite_all = TRUE;
X overwrite_none = FALSE; /* just to make sure */
X break;
X case 'r':
X case 'R':
X do {
X FPRINTF(stderr, LoadFarString(NewName));
X FFLUSH(stderr);
X fgets(filename, FILNAMSIZ, stdin);
X /* usually get \n here: better check for it */
X len = strlen(filename);
X if (filename[len-1] == '\n')
X filename[--len] = 0;
X } while (len == 0);
X renamed = TRUE;
X goto startover; /* sorry for a goto */
X case 'y':
X case 'Y':
X break;
X case 'N':
X overwrite_none = TRUE;
X overwrite_all = FALSE; /* make sure */
X force_flag = FALSE; /* ditto */
X /* FALL THROUGH, skip */
X case 'n':
X continue; /* skip file */
X default:
X FPRINTF(stderr, LoadFarString(InvalidResponse),
X *answerbuf); /* warn the user */
X goto reprompt; /* why not another goto? */
X } /* end switch (*answerbuf) */
X#endif /* ?MSWIN */
X } /* end if (query) */
X } /* end if (extracting to disk) */
X
X#ifdef CRYPT
X if (pInfo->encrypted && (error = decrypt()) != PK_COOL) {
X if (error == PK_MEM2) {
X if (error > error_in_archive)
X error_in_archive = error;
X FPRINTF(stderr,
X LoadFarString(SkipCantGetPasswd), filename);
X } else { /* (error == PK_WARN) */
X if (!((tflag && qflag) || (!tflag && !QCOND2)))
X FPRINTF(stderr,
X LoadFarString(SkipIncorrectPasswd), filename);
X ++num_bad_pwd;
X }
X continue; /* go on to next file */
X }
X#endif /* CRYPT */
X disk_full = 0;
X if ((error = extract_or_test_member()) != PK_COOL) {
X if (error > error_in_archive)
X error_in_archive = error; /* ...and keep going */
X if (disk_full > 1) {
X free(crc_32_tab);
X if (fn_matched)
X free(fn_matched);
X if (xn_matched)
X free(xn_matched);
X return error_in_archive; /* (unless disk full) */
X }
X }
X } /* end for-loop (i: files in current block) */
X
X
X /*
X * Jump back to where we were in the central directory, then go and do
X * the next batch of files.
X */
X
X cur_zipfile_bufstart = lseek(zipfd, (LONGINT)cd_bufstart, SEEK_SET);
X read(zipfd, (char *)inbuf, INBUFSIZ); /* were there b4 ==> no error */
X inptr = cd_inptr;
X incnt = cd_incnt;
X ++blknum;
X
X#ifdef TEST
X printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
X printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
X cur_zipfile_bufstart);
X printf("inptr-inbuf = %d\n", inptr-inbuf);
X printf("incnt = %d\n\n", incnt);
X#endif
X
X } /* end while-loop (blocks of files in central directory) */
X
X/*---------------------------------------------------------------------------


X Check for unmatched filespecs on command line and print warning if any

X found. Free allocated memory.
X ---------------------------------------------------------------------------*/
X
X if (fn_matched) {
X for (i = 0; i < filespecs; ++i)
X if (!fn_matched[i])
X FPRINTF(stderr, LoadFarString(FilenameNotMatched),
X pfnames[i]);


X free(fn_matched);
X }
X if (xn_matched) {

X for (i = 0; i < xfilespecs; ++i)
X if (!xn_matched[i])
X FPRINTF(stderr, LoadFarString(ExclFilenameNotMatched),
X pxnames[i]);
X free(xn_matched);
X }
X free(crc_32_tab);
X
X/*---------------------------------------------------------------------------
X Double-check that we're back at the end-of-central-directory record, and
X print quick summary of results, if we were just testing the archive. We
X send the summary to stdout so that people doing the testing in the back-
X ground and redirecting to a file can just do a "tail" on the output file.
X ---------------------------------------------------------------------------*/
X


X if (readbuf(sig, 4) == 0)

X error_in_archive = PK_EOF;
X if (strncmp(sig, end_central_sig, 4)) { /* just to make sure */


X FPRINTF(stderr, LoadFarString(EndSigMsg)); /* didn't find sig */

X FPRINTF(stderr, LoadFarString(ReportMsg)); /* check binary transfers */
X if (!error_in_archive) /* don't overwrite stronger error */


X error_in_archive = PK_WARN;
X }

X ++filnum; /* initialized to -1, so now zero if no files found */
X if (tflag) {
X int num=filnum - num_bad_pwd;
X
X if (qflag < 2) { /* GRR 930710: was (qflag == 1) */
X if (error_in_archive)
X PRINTF(LoadFarString(ErrorInArchive),
X (error_in_archive == 1)? "warning-" : "", zipfn);
X else if (num == 0)
X PRINTF(LoadFarString(ZeroFilesTested), zipfn);
X else if (process_all_files && (num_skipped+num_bad_pwd == 0))
X PRINTF(LoadFarString(NoErrInCompData), zipfn);
X else
X PRINTF(LoadFarString(NoErrInTestedFiles),
X zipfn, num, (num==1)? "":"s");
X if (num_skipped > 0)
X PRINTF(LoadFarString(FilesSkipped), num_skipped,
X (num_skipped==1)? "":"s");
X#ifdef CRYPT
X if (num_bad_pwd > 0)
X PRINTF(LoadFarString(FilesSkipBadPasswd),
X num_bad_pwd, (num_bad_pwd==1)? "":"s");
X#endif /* CRYPT */
X } else if ((qflag == 0) && !error_in_archive && (num == 0))
X PRINTF(LoadFarString(ZeroFilesTested), zipfn);
X }
X
X /* give warning if files not tested or extracted */
X if ((filnum == 0) && error_in_archive <= PK_WARN)
X error_in_archive = PK_FIND; /* no files found at all */
X else if ((num_skipped > 0) && !error_in_archive)
X error_in_archive = PK_WARN;
X#ifdef CRYPT
X else if ((num_bad_pwd > 0) && !error_in_archive)
X error_in_archive = PK_WARN;
X#endif /* CRYPT */
X
X return error_in_archive;
X
X} /* end function extract_or_test_files() */


X
X
X
X
X

X/**********************/
X/* Function makecrc() */
X/**********************/
X
Xstatic void makecrc()
X/*
X Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
X x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
X
X Polynomials over GF(2) are represented in binary, one bit per coefficient,
X with the lowest powers in the most significant bit. Then adding polynomials
X is just exclusive-or, and multiplying a polynomial by x is a right shift by
X one. If we call the above polynomial p, and represent a byte as the
X polynomial q, also with the lowest power in the most significant bit (so the
X byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
X where a mod b means the remainder after dividing a by b.
X
X This calculation is done using the shift-register method of multiplying and
X taking the remainder. The register is initialized to zero, and for each
X incoming bit, x^32 is added mod p to the register if the bit is a one (where
X x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
X x (which is shifting right by one and adding x^32 mod p if the bit shifted
X out is a one). We start with the highest power (least significant bit) of
X q and repeat for all eight bits of q.
X
X The table is simply the CRC of all possible eight bit values. This is all
X the information needed to generate CRC's on data a byte at a time for all
X combinations of CRC register values and incoming bytes. The table is
X written to stdout as 256 long hexadecimal values in C language format.
X*/
X{
X ulg crc; /* crc shift register */
X ulg xor; /* polynomial exclusive-or pattern */
X int i; /* counter for all possible eight bit values */
X int k; /* byte being shifted into crc apparatus */
X /* terms of polynomial defining this crc (except x^32): */
X static uch p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
X
X /* make exclusive-or pattern from polynomial (0xedb88320) */
X xor = 0L;
X for (i = 0; i < sizeof(p)/sizeof(uch); i++)
X xor |= 1L << (31 - p[i]);
X
X crc_32_tab[0] = 0L;
X Trace((stderr, "makecrc(): crc_32_tab[] = {\n 0x%08lxL", crc_32_tab[0]));
X /* the idea to initialize the register with the byte instead of
X * zero was stolen from Haruhiko Okumura's ar002 */
X for (i = 1; i < 256; i++) {
X crc = i;
X for (k = 8; k; k--)
X crc = crc & 1 ? (crc >> 1) ^ xor : crc >> 1;
X crc_32_tab[i] = crc;
X Trace((stderr, i % 5 ? ", 0x%08lxL" : ",\n 0x%08lxL", crc_32_tab[i]));
X }
X Trace((stderr, "\n};\n"));
X
X} /* end function makecrc() */


X
X
X
X
X

X/***************************/
X/* Function store_info() */
X/***************************/
X
Xstatic int store_info() /* return 0 if skipping, 1 if OK */
X{
X#ifdef SFX
X# define UNKN_COMPR \
X (crec.compression_method!=STORED && crec.compression_method!=DEFLATED)
X#else
X# define UNKN_COMPR \
X (crec.compression_method>IMPLODED && crec.compression_method!=DEFLATED)
X#endif
X
X/*---------------------------------------------------------------------------
X Check central directory info for version/compatibility requirements.
X ---------------------------------------------------------------------------*/
X
X pInfo->encrypted = crec.general_purpose_bit_flag & 1; /* bit field */
X pInfo->ExtLocHdr = (crec.general_purpose_bit_flag & 8) == 8;/* bit field */
X pInfo->textfile = crec.internal_file_attributes & 1; /* bit field */
X pInfo->crc = crec.crc32;
X pInfo->compr_size = crec.csize;
X
X switch (aflag) {
X case 0:
X pInfo->textmode = FALSE; /* bit field */
X break;
X case 1:
X pInfo->textmode = pInfo->textfile; /* auto-convert mode */
X break;
X default: /* case 2: */
X pInfo->textmode = TRUE;
X break;
X }
X
X if (crec.version_needed_to_extract[1] == VMS_) {
X if (crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
X if (!((tflag && qflag) || (!tflag && !QCOND2)))
X FPRINTF(stderr, LoadFarString(VersionMsg), filename, "VMS",
X crec.version_needed_to_extract[0] / 10,
X crec.version_needed_to_extract[0] % 10,
X VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10);
X return 0;
X }
X#ifndef VMS /* won't be able to use extra field, but still have data */
X else if (!tflag && !force_flag) { /* if forcing, extract regardless */
X FPRINTF(stderr, LoadFarString(VMSFormat), filename);
X FFLUSH(stderr);
X fgets(answerbuf, 9, stdin);
X if ((*answerbuf != 'y') && (*answerbuf != 'Y'))
X return 0;
X }
X#endif /* !VMS */
X /* usual file type: don't need VMS to extract */
X } else if (crec.version_needed_to_extract[0] > UNZIP_VERSION) {
X if (!((tflag && qflag) || (!tflag && !QCOND2)))
X FPRINTF(stderr, LoadFarString(VersionMsg), filename, "PK",
X crec.version_needed_to_extract[0] / 10,
X crec.version_needed_to_extract[0] % 10,
X UNZIP_VERSION / 10, UNZIP_VERSION % 10);


X return 0;
X }
X

X if UNKN_COMPR {
X if (!((tflag && qflag) || (!tflag && !QCOND2)))
X FPRINTF(stderr, LoadFarString(ComprMsg), filename,
X crec.compression_method);
X return 0;
X }
X#ifndef CRYPT
X if (pInfo->encrypted) {
X if (!((tflag && qflag) || (!tflag && !QCOND2)))
X FPRINTF(stderr, LoadFarString(SkipEncrypted), filename);
X return 0;
X }
X#endif /* !CRYPT */
X
X /* map whatever file attributes we have into the local format */
X mapattr(); /* GRR: worry about return value later */
X
X pInfo->offset = (long) crec.relative_offset_local_header;
X return 1;
X
X} /* end function store_info() */


X
X
X
X
X

X/***************************************/
X/* Function extract_or_test_member() */
X/***************************************/
X
Xstatic int extract_or_test_member() /* return PK-type error code */
X{
X char *nul="[empty] ", *txt="[text] ", *bin="[binary]";
X register int b;
X int r, error=PK_COOL;
X
X
X
X/*---------------------------------------------------------------------------
X Initialize variables, buffers, etc.
X ---------------------------------------------------------------------------*/
X
X bits_left = 0; /* unreduce and unshrink only */
X bitbuf = 0L; /* unreduce and unshrink only */
X zipeof = 0; /* unreduce and unshrink only */
X newfile = TRUE;
X crc32val = 0xFFFFFFFFL;
X
X#ifdef SYMLINKS
X /* if file came from Unix and is a symbolic link and we are extracting
X * to disk, prepare to restore the link */
X if (S_ISLNK(pInfo->file_attr) && (pInfo->hostnum == UNIX_) && !tflag &&
X !cflag && (lrec.ucsize > 0))
X symlnk = TRUE;
X else
X symlnk = FALSE;
X#endif /* SYMLINKS */
X
X if (tflag) {
X if (!qflag) {
X FPRINTF(stdout, LoadFarString(ExtractMsg), "test", filename, "", "");
X fflush(stdout);
X }
X } else {
X if (cflag) {
X outfile = stdout;
X#ifdef DOS_NT_OS2
X setmode(fileno(outfile), O_BINARY);
X# define NEWLINE "\r\n"
X#else
X# define NEWLINE "\n"
X#endif
X#ifdef VMS
X if (open_outfile()) /* VMS: required even for stdout! */
X return PK_DISK;
X#endif
X } else if (open_outfile())


X return PK_DISK;
X }
X

X/*---------------------------------------------------------------------------
X Unpack the file.
X ---------------------------------------------------------------------------*/
X
X switch (lrec.compression_method) {
X case STORED:
X if (!tflag && QCOND2) {
X#ifdef SYMLINKS
X if (symlnk) /* can also be deflated, but rarer... */
X FPRINTF(stdout, LoadFarString(ExtractMsg), "link", filename,
X "", "");
X else
X#endif /* SYMLINKS */
X FPRINTF(stdout, LoadFarString(ExtractMsg), "extract", filename,
X (aflag != 1 /* && pInfo->textfile == pInfo->textmode */ )? ""
X : (lrec.ucsize == 0L? nul : (pInfo->textfile? txt : bin)),
X cflag? NEWLINE : "");
X fflush(stdout);
X }
X outptr = slide;
X outcnt = 0L;
X while ((b = NEXTBYTE) != EOF && !disk_full) {
X *outptr++ = (uch)b;
X if (++outcnt == WSIZE) {
X flush(slide, outcnt, 0);
X outptr = slide;
X outcnt = 0L;
X }
X }
X if (outcnt) /* flush final (partial) buffer */
X flush(slide, outcnt, 0);
X break;
X
X#ifndef SFX
X case SHRUNK:
X if (!tflag && QCOND2) {
X FPRINTF(stdout, LoadFarString(ExtractMsg),
X LoadFarStringSmall(Unshrink), filename,
X (aflag != 1 /* && pInfo->textfile == pInfo->textmode */ )? ""
X : (pInfo->textfile? txt : bin), cflag? NEWLINE : "");
X fflush(stdout);
X }
X if ((r = unshrink()) != PK_COOL) {
X if ((tflag && qflag) || (!tflag && !QCOND2))
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipFile),
X LoadFarString(NotEnoughMem),
X LoadFarStringSmall2(Unshrink),
X filename);
X else
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipNoFile),
X LoadFarString(NotEnoughMem),
X LoadFarStringSmall2(Unshrink));
X error = r;
X }
X break;
X
X case REDUCED1:
X case REDUCED2:
X case REDUCED3:
X case REDUCED4:
X if (!tflag && QCOND2) {
X FPRINTF(stdout, LoadFarString(ExtractMsg), "unreduc", filename,
X (aflag != 1 /* && pInfo->textfile == pInfo->textmode */ )? ""
X : (pInfo->textfile? txt : bin), cflag? NEWLINE : "");
X fflush(stdout);
X }
X unreduce();
X break;
X
X case IMPLODED:
X if (!tflag && QCOND2) {
X FPRINTF(stdout, LoadFarString(ExtractMsg), "explod", filename,
X (aflag != 1 /* && pInfo->textfile == pInfo->textmode */ )? ""
X : (pInfo->textfile? txt : bin), cflag? NEWLINE : "");
X fflush(stdout);
X }
X if (((r = explode()) != 0) && (r != 5)) { /* treat 5 specially */
X if ((tflag && qflag) || (!tflag && !QCOND2))
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipFile), r == 3?
X LoadFarString(NotEnoughMem) :
X LoadFarString(InvalidComprData),
X LoadFarStringSmall2(Explode), filename);
X else
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipNoFile), r == 3?
X LoadFarString(NotEnoughMem) :
X LoadFarString(InvalidComprData),
X LoadFarStringSmall2(Explode));
X error = (r == 3)? PK_MEM3 : PK_ERR;
X }
X if (r == 5) {
X int warning = ((ulg)used_csize <= lrec.csize);
X
X if ((tflag && qflag) || (!tflag && !QCOND2))
X FPRINTF(stderr, LoadFarString(LengthMsg), "", warning?
X "warning":"error", used_csize, lrec.ucsize, warning?
X " ":"", lrec.csize, " [", filename, "]");
X else
X FPRINTF(stderr, LoadFarString(LengthMsg), "\n", warning?
X "warning":"error", used_csize, lrec.ucsize, warning?
X " ":"", lrec.csize, "", "", ".");
X error = warning? PK_WARN : PK_ERR;
X }
X break;


X#endif /* !SFX */
X

X case DEFLATED:
X if (!tflag && QCOND2) {
X FPRINTF(stdout, LoadFarString(ExtractMsg), "inflat", filename,
X (aflag != 1 /* && pInfo->textfile == pInfo->textmode */ )? ""
X : (pInfo->textfile? txt : bin), cflag? NEWLINE : "");
X fflush(stdout);
X }
X if ((r = inflate()) != 0) {
X if ((tflag && qflag) || (!tflag && !QCOND2))
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipFile), r == 3?
X LoadFarString(NotEnoughMem) :
X LoadFarString(InvalidComprData),
X LoadFarStringSmall2(Inflate), filename);
X else
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipNoFile), r == 3?
X LoadFarString(NotEnoughMem) :
X LoadFarString(InvalidComprData),
X LoadFarStringSmall2(Inflate));
X error = (r == 3)? PK_MEM3 : PK_ERR;
X }
X break;
X
X default: /* should never get to this point */
X FPRINTF(stderr, LoadFarString(FileUnknownCompMethod), filename);
X /* close and delete file before return? */
X return PK_WARN;
X
X } /* end switch (compression method) */
X
X if (disk_full) { /* set by flush() */
X if (disk_full > 1)
X return PK_DISK;


X error = PK_WARN;
X }
X

X/*---------------------------------------------------------------------------
X Close the file and set its date and time (not necessarily in that order),
X and make sure the CRC checked out OK. Logical-AND the CRC for 64-bit
X machines (redundant on 32-bit machines).
X ---------------------------------------------------------------------------*/
X
X#ifdef VMS /* VMS: required even for stdout! (final flush) */
X if (!tflag) /* don't close NULL file */
X#else
X if (!tflag && !cflag) /* don't close NULL file or stdout */
X#endif
X close_outfile();
X
X if (error > PK_WARN) /* don't print redundant CRC error if error already */
X return error;
X
X if ((crc32val = ((~crc32val) & 0xFFFFFFFFL)) != lrec.crc32) {
X /* if quiet enough, we haven't output the filename yet: do it */
X if ((tflag && qflag) || (!tflag && !QCOND2))
X FPRINTF(stderr, "%-22s ", filename);
X FPRINTF(stderr, LoadFarString(BadCRC), crc32val, lrec.crc32);
X#ifdef CRYPT
X if (pInfo->encrypted)
X FPRINTF(stderr, LoadFarString(MaybeBadPasswd));
X#endif
X FFLUSH(stderr);
X error = PK_ERR;
X } else if (tflag) {
X if (!qflag)
X FPRINTF(stdout, " OK\n");
X } else {
X if (QCOND2 && !error)
X FPRINTF(stdout, "\n"); /* GRR: is stdout reset to text mode yet? */


X }
X
X return error;
X

X} /* end function extract_or_test_member() */


X
X
X
X
X

X/***************************/
X/* Function memextract() */
X/***************************/
X
Xint memextract(tgt, tgtsize, src, srcsize) /* extract compressed extra */
X uch *tgt, *src; /* field block; return PK- */
X ulg tgtsize, srcsize; /* type error level */
X{
X uch *old_inptr=inptr;
X int old_incnt=incnt, r, error=PK_OK;
X ush method;
X ulg extra_field_crc;
X
X
X method = makeword(src);
X extra_field_crc = makelong(src+2);
X
X /* compressed extra field exists completely in memory at this location: */
X inptr = src + 2 + 4; /* method and extra_field_crc */
X incnt = (int)(csize = (long)(srcsize - (2 + 4)));
X mem_mode = TRUE;
X
X switch (method) {
X case STORED:
X memcpy((char *)tgt, (char *)inptr, (extent)incnt);
X outcnt = csize; /* for CRC calculation */
X break;
X case DEFLATED:
X if ((r = inflate()) != 0) {
X FPRINTF(stderr, LoadFarStringSmall(ErrUnzipNoFile), r == 3?
X LoadFarString(NotEnoughMem) :
X LoadFarString(InvalidComprData),
X LoadFarStringSmall2(Inflate));
X error = (r == 3)? PK_MEM3 : PK_ERR;
X }
X if (outcnt == 0L) /* inflate's final FLUSH sets outcnt */
X break;
X if (outcnt <= tgtsize)
X memcpy((char *)tgt, (char *)slide, (extent)outcnt);
X else
X error = PK_MEM4; /* GRR: should be passed up via SetEAs() */
X break;
X default:
X FPRINTF(stderr, LoadFarString(UnsupportedExtraField));
X error = PK_WARN; /* GRR: should be passed on up via SetEAs() */
X break;
X }
X
X inptr = old_inptr;
X incnt = old_incnt;
X mem_mode = FALSE;
X
X if (!error) {
X register ulg crcval = 0xFFFFFFFFL;
X register ulg n = outcnt; /* or tgtsize?? */
X register uch *p = tgt;
X
X while (n--)
X crcval = crc_32_tab[((uch)crcval ^ (*p++)) & 0xff] ^ (crcval >> 8);
X crcval = (~crcval) & 0xFFFFFFFFL;
X
X if (crcval != extra_field_crc) {
X FPRINTF(stderr, LoadFarString(BadExtraFieldCRC),
X zipfn, crcval, extra_field_crc);
X error = PK_WARN;


X }
X }
X return error;
X

X} /* end function memextract() */
END_OF_FILE
if test 46513 -ne `wc -c <'unzip-5.12/extract.c'`; then
echo shar: \"'unzip-5.12/extract.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/extract.c'
fi
if test -f 'unzip-5.12/vms/cmdline.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/cmdline.c'\"
else
echo shar: Extracting \"'unzip-5.12/vms/cmdline.c'\" \(20360 characters\)
sed "s/^X//" >'unzip-5.12/vms/cmdline.c' <<'END_OF_FILE'
X#define module_name VMS_UNZIP_CMDLINE
X#define module_ident "02-002"
X/*
X**
X** Facility: UNZIP
X**
X** Module: VMS_UNZIP_CMDLINE
X**
X** Author: Hunter Goatley <goath...@wkuvx1.wku.edu>
X**
X** Date: 12 Jul 94 (orig. Zip version, 30 Jul 93)
X**
X** Abstract: Routines to handle a VMS CLI interface for UnZip. The CLI
X** command line is parsed and a new argc/argv are built and
X** returned to UnZip.
X**
X** Modified by:
X**
X** 02-002 Hunter Goatley 16-JUL-1994 10:20
X** Fixed some typos.
X** 02-001 Cave Newt 14-JUL-1994 15:18
X** Removed obsolete /EXTRACT option; fixed /*TEXT options;
X** wrote VMSCLI usage() function
X** 02-000 Hunter Goatley 12-JUL-1994 00:00
X** Original UnZip version (v5.11).
X** 01-000 Hunter Goatley 30-JUL-1993 07:54
X** Original version (for Zip v1.9p1).
X**
X*/
X
X
X#ifdef __alpha
X#pragma module module_name module_ident
X#else
X#module module_name module_ident
X#endif
X
X#include "unzip.h"
X#include "version.h" /* for usage() */
X
X#include <ssdef.h>
X#include <descrip.h>
X#include <climsgdef.h>
X#include <clidef.h>
X#include <lib$routines.h>
X#include <str$routines.h>
X
X#ifndef CLI$_COMMA
Xglobalvalue CLI$_COMMA;
X#endif
X
X/*
X** "Macro" to initialize a dynamic string descriptor.
X*/
X#define init_dyndesc(dsc) {\
X dsc.dsc$w_length = 0;\
X dsc.dsc$b_dtype = DSC$K_DTYPE_T;\
X dsc.dsc$b_class = DSC$K_CLASS_D;\
X dsc.dsc$a_pointer = 0;}
X
X/*
X** Define descriptors for all of the CLI parameters and qualifiers.
X*/
X#if 0
X$DESCRIPTOR(cli_extract, "EXTRACT"); /* obsolete */
X#endif
X$DESCRIPTOR(cli_autotext, "AUTOTEXT"); /* -a */
X$DESCRIPTOR(cli_text, "TEXT"); /* -aa */
X$DESCRIPTOR(cli_case_insensitive, "CASE_INSENSITIVE"); /* -C */
X$DESCRIPTOR(cli_screen, "SCREEN"); /* -c */
X$DESCRIPTOR(cli_directory, "DIRECTORY"); /* see JUNK */
X$DESCRIPTOR(cli_freshen, "FRESHEN"); /* -f */
X$DESCRIPTOR(cli_junk, "JUNK"); /* -j */
X$DESCRIPTOR(cli_lowercase, "LOWERCASE"); /* -L */
X$DESCRIPTOR(cli_list, "LIST"); /* -l */
X$DESCRIPTOR(cli_brief, "BRIEF"); /* -l */
X$DESCRIPTOR(cli_full, "FULL"); /* -v */
X$DESCRIPTOR(cli_overwrite, "OVERWRITE"); /* -o, -n */
X$DESCRIPTOR(cli_quiet, "QUIET"); /* -q */
X$DESCRIPTOR(cli_super_quiet, "SUPER_QUIET"); /* -qq */
X$DESCRIPTOR(cli_test, "TEST"); /* -t */
X$DESCRIPTOR(cli_type, "TYPE"); /* -c */
X$DESCRIPTOR(cli_pipe, "PIPE"); /* -p */
X$DESCRIPTOR(cli_uppercase, "UPPERCASE"); /* -U */
X$DESCRIPTOR(cli_update, "UPDATE"); /* -u */
X$DESCRIPTOR(cli_version, "VERSION"); /* -V */
X$DESCRIPTOR(cli_verbose, "VERBOSE"); /* -v */
X$DESCRIPTOR(cli_restore, "RESTORE"); /* -X */
X$DESCRIPTOR(cli_comment, "COMMENT"); /* -z */
X$DESCRIPTOR(cli_exclude, "EXCLUDE"); /* -x */
X
X$DESCRIPTOR(cli_information, "ZIPINFO"); /* -Z */
X$DESCRIPTOR(cli_short, "SHORT"); /* -Zs */
X$DESCRIPTOR(cli_medium, "MEDIUM"); /* -Zm */
X$DESCRIPTOR(cli_long, "LONG"); /* -Zl */
X$DESCRIPTOR(cli_header, "HEADER"); /* -Zh */
X$DESCRIPTOR(cli_totals, "TOTALS"); /* -Zt */
X$DESCRIPTOR(cli_times, "TIMES"); /* -ZT */
X$DESCRIPTOR(cli_one_line, "ONE_LINE"); /* -Z2 */
X
X$DESCRIPTOR(cli_yyz, "YYZ");
X
X$DESCRIPTOR(cli_zipfile, "ZIPFILE");
X$DESCRIPTOR(cli_infile, "INFILE");
X$DESCRIPTOR(unzip_command, "unzip ");
X$DESCRIPTOR(blank, " ");
X
X#ifdef __alpha
Xextern void *vms_unzip_cld;
X#else
Xglobalref void *vms_unzip_cld;
X#endif
X
X/* extern unsigned long LIB$GET_INPUT(void), LIB$SIG_TO_RET(void); */
X
Xextern unsigned long cli$dcl_parse ();
Xextern unsigned long cli$present ();
Xextern unsigned long cli$get_value ();
X
Xunsigned long vms_unzip_cmdline (int *, char ***);
Xunsigned long get_list (struct dsc$descriptor_s *, char **,
X struct dsc$descriptor_d *, char);
Xunsigned long check_cli (struct dsc$descriptor_s *);
X
X
X#ifdef TEST
Xunsigned long
Xmain(int argc, char **argv)
X{
X register status;
X return (vms_unzip_cmdline(&argc, &argv));
X}
X#endif /* TEST */
X
X
Xunsigned long
Xvms_unzip_cmdline (int *argc_p, char ***argv_p)
X{
X/*
X** Routine: vms_unzip_cmdline
X**
X** Function:
X**
X** Parse the DCL command line and create a fake argv array to be
X** handed off to Zip.
X**
X** NOTE: the argv[] is built as we go, so all the parameters are
X** checked in the appropriate order!!
X**
X** Formal parameters:
X**
X** argc_p - Address of int to receive the new argc
X** argv_p - Address of char ** to receive the argv address
X**
X** Calling sequence:
X**
X** status = vms_unzip_cmdline (&argc, &argv);
X**
X** Returns:
X**
X** SS$_NORMAL - Success.
X** SS$_INSFMEM - A malloc() or realloc() failed
X** SS$_ABORT - Bad time value
X**
X*/
X register status;
X char options[256];
X char *the_cmd_line;
X char *ptr;
X int x, len, zipinfo;
X
X int new_argc;
X char **new_argv;
X
X struct dsc$descriptor_d work_str;
X struct dsc$descriptor_d foreign_cmdline;
X struct dsc$descriptor_d output_directory;
X
X init_dyndesc (work_str);
X init_dyndesc (foreign_cmdline);
X init_dyndesc (output_directory);
X
X /*
X ** See if the program was invoked by the CLI (SET COMMAND) or by
X ** a foreign command definition. Check for /YYZ, which is a
X ** valid default qualifier solely for this test.
X */
X status = check_cli (&cli_yyz);


X if (!(status & 1)) {

X lib$get_foreign (&foreign_cmdline);
X /*
X ** If nothing was returned or the first character is a "-", then
X ** assume it's a UNIX-style command and return.
X */
X if ((foreign_cmdline.dsc$w_length == 0) || (*(foreign_cmdline.dsc$a_pointer) == '-'))
X return(SS$_NORMAL);
X
X str$concat (&work_str, &unzip_command, &foreign_cmdline);
X status = cli$dcl_parse(&work_str, &vms_unzip_cld, lib$get_input,
X lib$get_input, 0);
X if (!(status & 1)) return(status);
X }
X
X /*
X ** There's always going to be an new_argv[] because of the image name.
X */
X if ((the_cmd_line = (char *) malloc (sizeof("unzip")+1)) == NULL)
X return(SS$_INSFMEM);
X
X strcpy (the_cmd_line, "unzip");
X
X /*
X ** First, check to see if any of the regular options were specified.
X */
X
X options[0] = '-';
X ptr = &options[1]; /* Point to temporary buffer */
X
X /*
X ** Is it Zipinfo??
X */
X zipinfo = 0;
X status = cli$present (&cli_information);
X if (status & 1) {
X
X zipinfo = 1;
X
X *ptr++ = 'Z';
X *ptr++ = ' ';
X *ptr++ = '-';
X
X if (cli$present(&cli_one_line) & 1)
X *ptr++ = '2';
X if (cli$present(&cli_short) & 1)
X *ptr++ = 's';
X if (cli$present(&cli_medium) & 1)
X *ptr++ = 'm';
X if (cli$present(&cli_long) & 1)
X *ptr++ = 'l';
X if (cli$present(&cli_header) & 1)
X *ptr++ = 'h';
X if (cli$present(&cli_comment) & 1)
X *ptr++ = 'c';
X if (cli$present(&cli_totals) & 1)
X *ptr++ = 't';
X if (cli$present(&cli_times) & 1)
X *ptr++ = 'T';
X
X /* If no other options were specified, remove the " -". */
X if (*(ptr - 1) == '-')
X ptr = ptr - 2;


X
X }
X else {
X

X#if 0
X /*
X ** Extract files?
X */
X status = cli$present (&cli_extract);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'x';
X#endif
X
X /*
X ** Convert all files as text (CR LF -> LF, etc.)
X */
X status = cli$present (&cli_text);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT) {
X *ptr++ = 'a';
X *ptr++ = 'a';
X }
X
X /*
X ** Auto-convert only text files as text
X */
X status = cli$present (&cli_autotext);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'a';
X
X /*
X ** Extract files to screen?
X */
X status = cli$present (&cli_screen);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'c';
X
X /*
X ** Re-create directory structure? (default)
X */
X status = cli$present (&cli_directory);
X if (status == CLI$_PRESENT) {
X status = cli$get_value (&cli_directory, &output_directory);
X }
X
X /*
X ** Freshen existing files, create none
X */
X status = cli$present (&cli_freshen);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'f';
X
X /*
X ** Junk stored directory names on unzip
X */
X status = cli$present (&cli_junk);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'j';
X
X /*
X ** List contents (/BRIEF or /FULL (default))
X */
X status = cli$present (&cli_list);
X if (status & 1) {
X if (cli$present(&cli_full) & 1)
X *ptr++ = 'v';
X else
X *ptr++ = 'l';
X }
X
X /*
X ** Overwrite files?
X */
X status = cli$present (&cli_overwrite);
X if (status == CLI$_NEGATED)
X *ptr++ = 'n';
X else if (status != CLI$_ABSENT)
X *ptr++ = 'o';
X
X /*
X ** Pipe files to SYS$OUTPUT with no informationals?
X */
X status = cli$present (&cli_pipe);
X if (status != CLI$_ABSENT)
X *ptr++ = 'p';
X
X /*
X ** Quiet
X */
X status = cli$present (&cli_quiet);
X if (status & 1)
X *ptr++ = 'q';
X
X status = cli$present (&cli_super_quiet);
X if (status & 1)
X *ptr++ = 'q';
X
X /*
X ** Test archive integrity
X */
X status = cli$present (&cli_test);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 't';
X
X /*
X ** Match filenames case-insensitively (-C)
X */
X status = cli$present (&cli_case_insensitive);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'C';
X
X /*
X ** Make (some) names lowercase
X */
X status = cli$present (&cli_lowercase);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'L';
X
X /*
X ** Uppercase (don't convert to lower)
X */
X status = cli$present (&cli_uppercase);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'U';
X
X /*
X ** Update (extract only new and newer files)
X */
X status = cli$present (&cli_update);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'u';
X
X /*
X ** Version (retain VMS/DEC-20 file versions)
X */
X status = cli$present (&cli_version);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'V';
X
X /*
X ** Verbose
X */
X status = cli$present (&cli_verbose);
X if (status & 1)
X *ptr++ = 'v';
X
X /*
X ** Restore owner/protection info
X */
X status = cli$present (&cli_restore);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'X';
X
X /*
X ** Display only the archive comment
X */
X status = cli$present (&cli_comment);
X if (status == CLI$_NEGATED)
X *ptr++ = '-';
X if (status != CLI$_ABSENT)
X *ptr++ = 'z';
X
X } /* Zipinfo check way up there.... */
X
X /*
X ** If the user didn't give any DCL qualifier, assume he wants the
X ** Un*x interface.
X if (ptr == &options[1])
X return(SS$_NORMAL);
X */
X
X /*
X ** Now copy the final options string to the_cmd_line.
X */
X x = ptr - &options[0];
X if (x > 1) {
X options[x] = '\0';
X len = strlen(the_cmd_line) + x + 2;
X if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
X return(SS$_INSFMEM);
X strcat (the_cmd_line, " ");
X strcat (the_cmd_line, options);
X }
X
X /*
X ** Now get the specified zip file name.
X */
X status = cli$present (&cli_zipfile);
X if (status & 1) {
X status = cli$get_value (&cli_zipfile, &work_str);
X
X len = strlen(the_cmd_line) + work_str.dsc$w_length + 2;
X if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
X return(SS$_INSFMEM);
X strcat (the_cmd_line, " ");
X x = strlen(the_cmd_line);
X strncpy(&the_cmd_line[x], work_str.dsc$a_pointer,
X work_str.dsc$w_length);
X the_cmd_line[len] = '\0';


X
X }
X
X /*

X ** Run through the list of files to unzip.
X */
X status = cli$present (&cli_infile);
X if (status & 1) {
X len = strlen(the_cmd_line) + 2;
X if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
X return(SS$_INSFMEM);
X strcat (the_cmd_line, " ");
X status = get_list (&cli_infile, &the_cmd_line, &foreign_cmdline, ' ');
X if (!(status & 1)) return (status);
X }
X
X /*
X ** Get the list of files to exclude, if there are any.
X */
X status = cli$present (&cli_exclude);
X if (status & 1) {
X len = strlen(the_cmd_line) + 5;
X if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
X return(SS$_INSFMEM);
X strcat (the_cmd_line, " -x ");
X status = get_list (&cli_exclude, &the_cmd_line, &foreign_cmdline, ' ');
X if (!(status & 1)) return (status);
X }
X
X /*
X ** Get the output directory, for UnZip.
X **/
X if (output_directory.dsc$w_length != 0) {
X len = strlen(the_cmd_line) + output_directory.dsc$w_length + 5;
X if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
X return(SS$_INSFMEM);
X strcat (the_cmd_line, " -d ");
X x = strlen(the_cmd_line);
X strncpy(&the_cmd_line[x], output_directory.dsc$a_pointer,
X output_directory.dsc$w_length);
X the_cmd_line[len] = '\0';
X }
X
X /*
X ** Now that we've built our new UNIX-like command line, count the
X ** number of args and build an argv array.
X */
X
X#if defined(TEST) || defined(DEBUG)
X printf("%s\n",the_cmd_line);
X#endif /* TEST */
X
X new_argc = 1;
X for (ptr = the_cmd_line;
X (ptr = strchr(ptr,' ')) != NULL;
X ptr++, new_argc++);
X
X /*
X ** Allocate memory for the new argv[]. The last element of argv[]
X ** is supposed to be 0, so allocate enough for new_argc+1.
X */
X if ((new_argv = (char **) calloc (new_argc+1, sizeof(char *))) == NULL)
X return(SS$_INSFMEM);
X
X /*
X ** For each option, store the address in new_argv[] and convert the
X ** separating blanks to nulls so each argv[] string is terminated.
X */
X for (ptr = the_cmd_line, x = 0; x < new_argc; x++) {
X new_argv[x] = ptr;
X if ((ptr = strchr (ptr, ' ')) != NULL)
X *ptr++ = '\0';
X }
X new_argv[new_argc] = 0;
X
X#if defined(TEST) || defined(DEBUG)
X printf("new_argc = %d\n", new_argc);
X for (x = 0; x < new_argc; x++)
X printf("new_argv[%d] = %s\n", x, new_argv[x]);
X#endif /* TEST */
X
X /*
X ** All finished. Return the new argc and argv[] addresses to Zip.
X */
X *argc_p = new_argc;
X *argv_p = new_argv;
X
X return(SS$_NORMAL);
X}
X
X
X
Xunsigned long
Xget_list (struct dsc$descriptor_s *qual, char **str,
X struct dsc$descriptor_d *cmdline, char c)
X{
X/*
X** Routine: get_list
X**
X** Function: This routine runs through a comma-separated CLI list
X** and copies the strings to the command line. The
X** specified separation character is used to separate
X** the strings on the command line.
X**
X** All strings are converted to lower-case.
X**
X** Formal parameters:
X**
X** qual - Address of descriptor for the qualifier name
X** str - Address of pointer pointing to string (command line)
X** c - Character to use to separate the list items
X**
X*/
X
X register status;
X struct dsc$descriptor_d work_str;
X
X init_dyndesc(work_str);
X
X status = cli$present (qual);
X if (status & 1) {
X
X unsigned long len, old_len, lower_it, ind, sind;
X
X len = strlen(*str);
X while ((status = cli$get_value (qual, &work_str)) & 1) {
X /*
X ** Just in case the string doesn't exist yet, though it does.
X */
X if (*str == NULL) {
X len = work_str.dsc$w_length + 1;
X if ((*str = (char *) malloc (work_str.dsc$w_length)) == NULL)
X return(SS$_INSFMEM);
X strncpy(*str,work_str.dsc$a_pointer,len);
X } else {
X char *src, *dst; int x;
X old_len = len;
X len += work_str.dsc$w_length + 1;
X if ((*str = (char *) realloc (*str, len)) == NULL)
X return(SS$_INSFMEM);
X
X /*
X ** Look for the filename in the original foreign command
X ** line to see if it was originally quoted. If so, then
X ** don't convert it to lowercase.
X */
X lower_it = 0;
X str$find_first_substring (cmdline, &ind, &sind, &work_str);
X if (*(cmdline->dsc$a_pointer + ind - 2) == '"')
X lower_it = 1;
X
X /*
X ** Copy the string to the buffer, converting to lowercase.
X */
X src = work_str.dsc$a_pointer;
X dst = *str+old_len;
X for (x = 0; x < work_str.dsc$w_length; x++) {
X if (!lower_it && ((*src >= 'A') && (*src <= 'Z')))
X *dst++ = *src++ + 32;
X else
X *dst++ = *src++;
X }
X }
X if (status == CLI$_COMMA)
X (*str)[len-1] = c;
X else
X (*str)[len-1] = '\0';
X }
X }
X
X return (SS$_NORMAL);
X
X}
X
X
Xunsigned long
Xcheck_cli (struct dsc$descriptor_s *qual)
X{
X/*
X** Routine: check_cli
X**
X** Function: Check to see if a CLD was used to invoke the program.
X**
X** Formal parameters:
X**
X** qual - Address of descriptor for qualifier name to check.
X**
X*/
X lib$establish(lib$sig_to_ret); /* Establish condition handler */
X return (cli$present(qual)); /* Just see if something was given */
X}
X
X
X
X#ifndef SFX
X
X#ifdef VMSWILD
X# define ZI_XMPL "*, %, () (e.g., \"(a-j)*pk.%%\")"
X#else
X# define ZI_XMPL "*, ?, [] (e.g., \"[a-j]*pk.??\")"
X#endif
X
Xint usage( int error) /* VMSCLI version; returns PK-type error code */
X{
X FILE *usagefp;
X extern char UnzipUsageLine1[];


X
X
X/*---------------------------------------------------------------------------
X If user requested usage, send it to stdout; else send to stderr.

X ---------------------------------------------------------------------------*/
X


X if (error)
X usagefp = (FILE *)stderr;
X else
X usagefp = (FILE *)stdout;
X
X/*---------------------------------------------------------------------------
X Print either ZipInfo usage or UnZip usage, depending on incantation.

X ---------------------------------------------------------------------------*/
X


X if (zipinfo_mode) {
X
X#ifndef NO_ZIPINFO
X

X fprintf(usagefp, "\
XZipInfo %s, by Newtware and the fine folks at Info-ZIP.\n\n\


XList name, date/time, attribute, size, compression method, etc., about files\n\
Xin list (excluding those in xlist) contained in the specified .zip archive(s).\

X\n\"file[.zip]\" may be a wildcard name containing %s.\n", ZI_VERSION, ZI_XMPL);
X
X fprintf(usagefp, "\n\
X usage: zipinfo file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\n\
X or: unzip /ZIPINFO file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\
X\n\nmain\
X listing-format options: /SHORT short \"ls -l\" format (def.)\n\
X /ONE_LINE just filenames, one/line /MEDIUM medium Unix \"ls -l\" format\n\
X /VERBOSE verbose, multi-page format /LONG long Unix \"ls -l\" format\n\
X ");
X
X fprintf(usagefp, "\n\
Xmiscellaneous options:\n \
X/HEADER print header line /TOTALS totals for listed files or for all\n\
X /COMMENT print zipfile comment /TIMES times in sortable decimal format\n\
X /EXCLUDE=(file-spec1,etc.) exclude file-specs from listing\n");
X
X fprintf(usagefp, "\nRemember that non-lowercase filespecs must be\


X quoted in VMS (e.g., \"Makefile\").\n");

X
X#endif /* !NO_ZIPINFO */
X

X } else { /* UnZip mode */
X

X fprintf(usagefp, UnzipUsageLine1, UZ_VERSION);
X
X#ifdef BETA
X fprintf(usagefp, "\
X THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n",
X "", "");
X#endif
X
X fprintf(usagefp, "\
XUsage: unzip file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options /modifiers\
X\n Default action is to extract files in list, except those in xlist, to exdir\
X;\n file[.zip] may be a wildcard. %s\n\n",
X#ifdef NO_ZIPINFO


X "(ZipInfo mode is disabled in this version.)"
X#else

X "Type \"unzip /ZIPINFO\" for ZipInfo-mode usage."
X#endif
X );
X
X fprintf(usagefp, "\
XMajor options include:\n\
X /[NO]TEST, /LIST, /[NO]SCREEN, /PIPE, /[NO]FRESHEN, /[NO]UPDATE,\n\
X /[NO]COMMENT, /DIRECTORY=directory-spec, /EXCLUDE=(file-spec1,etc.)\n\n\
XModifiers include:\n\
X /BRIEF, /FULL, /[NO]AUTOTEXT, /[NO]TEXT, /[NO]OVERWRITE, /[NO]JUNK,\n\
X /QUIET, /SUPER_QUIET, /[NO]CASE_INSENSITIVE, /[NO]LOWERCASE,\n\
X /[NO]VERSION, /[NO]RESTORE\n\n");
X
X fprintf(usagefp, "\
XExamples (see unzip.doc or \"HELP UNZIP\" for more info):\n \
Xunzip edit1 /EXCL=joe.jou /CASE_INSENSITIVE => extract all files except\n \
X joe.jou (or JOE.JOU, or any combination of case) from zipfile edit1.zip\n \
Xunzip zip201 \"Makefile.VMS\" vms/*.[ch] => extract VMS Makefile and\n\
X *.c and *.h files; must quote uppercase names if /CASE_INSENS not used\n\
X unzip foo /DIR=tmp:[.test] /JUNK /AUTO /OVER => extract all files to temp.\
X\n directory without paths, auto-converting text files and overwriting\n");
X
X } /* end if (zipinfo_mode) */


X
X if (error)
X return PK_PARAM;
X else

X return PK_COOL; /* just wanted usage screen: no error */
X
X} /* end function usage() */


X
X#endif /* !SFX */

END_OF_FILE
if test 20360 -ne `wc -c <'unzip-5.12/vms/cmdline.c'`; then
echo shar: \"'unzip-5.12/vms/cmdline.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/cmdline.c'
fi
echo shar: End of archive 6 \(of 20\).
cp /dev/null ark6isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:15:13 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 72
Archive-name: unzip/part07

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/msdos/msdos.c unzip-5.12/zipinfo.doc
# Wrapped by kent@sparky on Sat Sep 17 23:33:39 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 7 (of 20)."'
if test -f 'unzip-5.12/msdos/msdos.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/msdos.c'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/msdos.c'\" \(46263 characters\)
sed "s/^X//" >'unzip-5.12/msdos/msdos.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X msdos.c
X
X MSDOS-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X Contains: Opendir() (from zip)
X Readdir() (from zip)


X do_wild()
X mapattr()
X mapname()
X checkdir()
X isfloppy()

X volumelabel() (non-djgpp, non-emx)
X close_outfile()
X dateformat()
X version()
X _dos_getcountryinfo() (djgpp, emx)
X _dos_setftime() (djgpp, emx)
X _dos_setfileattr() (djgpp, emx)
X _dos_getdrive() (djgpp, emx)
X _dos_creat() (djgpp, emx)
X _dos_close() (djgpp, emx)
X volumelabel() (djgpp, emx)


X
X ---------------------------------------------------------------------------*/
X
X
X

X#include "unzip.h"
X#undef FILENAME /* BC++ 3.1 and djgpp 1.11 define FILENAME in <dir.h> */
X
Xstatic int isfloppy OF((int nDrive));
Xstatic int volumelabel OF((char *newlabel));


X
Xstatic int created_dir; /* used by mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */

Xstatic unsigned nLabelDrive; /* ditto, plus volumelabel() */
X
X#if (defined(__GO32__) || defined(__EMX__))
X# define MKDIR(path,mode) mkdir(path,mode)
X# include <dirent.h> /* use readdir() */
X# define direct dirent
X# define Opendir opendir
X# define Readdir readdir
X# ifdef __EMX__
X# include <dos.h>
X# define GETDRIVE(d) d = _getdrive()
X# define FA_LABEL A_LABEL
X# else
X# define GETDRIVE(d) _dos_getdrive(&d)
X# endif
X#else /* !(__GO32__ || __EMX__) */
X# define MKDIR(path,mode) mkdir(path)
X# ifdef __TURBOC__
X# define FATTR FA_HIDDEN+FA_SYSTEM+FA_DIREC
X# define FVOLID FA_VOLID
X# define FFIRST(n,d,a) findfirst(n,(struct ffblk *)d,a)
X# define FNEXT(d) findnext((struct ffblk *)d)
X# define GETDRIVE(d) d=getdisk()+1
X# include <dir.h>
X# else /* !__TURBOC__ */
X# define FATTR _A_HIDDEN+_A_SYSTEM+_A_SUBDIR
X# define FVOLID _A_VOLID
X# define FFIRST(n,d,a) _dos_findfirst(n,a,(struct find_t *)d)
X# define FNEXT(d) _dos_findnext((struct find_t *)d)
X# define GETDRIVE(d) _dos_getdrive(&d)
X# include <direct.h>
X# endif /* ?__TURBOC__ */
X typedef struct direct {
X char d_reserved[30];
X char d_name[13];
X int d_first;
X } DIR;
X# define closedir free
X DIR *Opendir OF((const char *));
X struct direct *Readdir OF((DIR *));


X
X
X
X
X#ifndef SFX
X

X/**********************/ /* Borland C++ 3.x has its own opendir/readdir */
X/* Function Opendir() */ /* library routines, but earlier versions don't, */
X/**********************/ /* so use ours regardless */
X
XDIR *Opendir(name)
X const char *name; /* name of directory to open */
X{
X DIR *dirp; /* malloc'd return value */
X char *nbuf; /* malloc'd temporary string */
X int len = strlen(name); /* path length to avoid strlens and strcats */
X
X
X if ((dirp = (DIR *)malloc(sizeof(DIR))) == (DIR *)NULL)
X return (DIR *)NULL;
X if ((nbuf = malloc(len + 5)) == (char *)NULL) {
X free(dirp);
X return (DIR *)NULL;
X }
X strcpy(nbuf, name);
X if (nbuf[len-1] == ':') {
X nbuf[len++] = '.';
X } else if (nbuf[len-1] == '/' || nbuf[len-1] == '\\')
X --len;
X strcpy(nbuf+len, "/*.*");


X Trace((stderr, "opendir: nbuf = [%s]\n", nbuf));
X

X if (FFIRST(nbuf, dirp, FATTR)) {
X free((voidp *)nbuf);
X return (DIR *)NULL;
X }
X free((voidp *)nbuf);
X dirp->d_first = 1;
X return dirp;


X}
X
X
X
X
X

X/**********************/
X/* Function Readdir() */
X/**********************/
X
Xstruct direct *Readdir(d)
X DIR *d; /* directory stream from which to read */
X{
X /* Return pointer to first or next directory entry, or NULL if end. */
X
X if (d->d_first)
X d->d_first = 0;
X else
X if (FNEXT(d))
X return (struct direct *)NULL;
X return (struct direct *)d;
X}


X
X#endif /* !SFX */

X#endif /* ?(__GO32__ || __EMX__) */


X
X
X
X
X

X#ifndef SFX
X
X/************************/
X/* Function do_wild() */ /* identical to OS/2 version */


X/************************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{

X static DIR *dir = (DIR *)NULL;


X static char *dirname, *wildname, matchname[FILNAMSIZ];

X static char Far CantAllocateWildcard[] =
X "warning: can't allocate wildcard buffers\n";


X static int firstcall=TRUE, have_dirname, dirnamelen;
X struct direct *file;
X
X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, '/')) == (char *)NULL &&
X (wildname = strrchr(wildspec, ':')) == (char *)NULL) {


X dirname = ".";
X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {
X ++wildname; /* point at character after '/' or ':' */
X dirnamelen = wildname - wildspec;

X if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
X FPRINTF(stderr, LoadFarString(CantAllocateWildcard));


X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }

X/* GRR: can't strip trailing char for opendir since might be "d:/" or "d:"
X * (would have to check for "./" at end--let opendir handle it instead) */


X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
X have_dirname = TRUE;
X }
X Trace((stderr, "do_wild: dirname = [%s]\n", dirname));
X

X if ((dir = Opendir(dirname)) != (DIR *)NULL) {
X while ((file = Readdir(dir)) != (struct direct *)NULL) {


X Trace((stderr, "do_wild: readdir returns %s\n", file->d_name));
X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X Trace((stderr, "do_wild: match() succeeds\n"));
X if (have_dirname) {
X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);

X dir = (DIR *)NULL;


X }
X Trace((stderr, "do_wild: opendir(%s) returns NULL\n", dirname));
X
X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */

X if (dir == (DIR *)NULL) {


X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X }
X
X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */

X while ((file = Readdir(dir)) != (struct direct *)NULL)


X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */

X dir = (DIR *)NULL;


X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;

X
X} /* end function do_wild() */
X
X#endif /* !SFX */


X
X
X
X
X

X/**********************/
X/* Function mapattr() */
X/**********************/


X
Xint mapattr()
X{
X /* set archive bit (file is not backed up): */
X pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;

X return 0;
X
X} /* end function mapattr() */


X
X
X
X
X

X/*****************************/
X/* Strings used in msdos.c */
X/*****************************/
X
Xstatic char Far ConversionFailed[] = "mapname: conversion of %s failed\n";
Xstatic char Far ErrSetVolLabel[] = "mapname: error setting volume label\n";
Xstatic char Far PathTooLong[] = "checkdir error: path too long: %s\n";
Xstatic char Far CantCreateDir[] = "checkdir error: can't create %s\n\
X unable to process %s.\n";
Xstatic char Far DirIsntDirectory[] =
X "checkdir error: %s exists but is not directory\n\
X unable to process %s.\n";
Xstatic char Far PathTooLongTrunc[] =
X "checkdir warning: path too long; truncating\n %s\n\
X -> %s\n";
X#if (!defined(SFX) || defined(SFX_EXDIR))
X static char Far CantCreateExtractDir[] =
X "checkdir: can't create extraction directory: %s\n";


X#endif
X
X
X
X
X

X/************************/
X/* Function mapname() */
X/************************/
X

Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */

X{ /* 3 if error (skip file), 10 if no memory (skip file) */


X char pathcomp[FILNAMSIZ]; /* path-component buffer */
X char *pp, *cp=(char *)NULL; /* character pointers */
X char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */

X char *last_dot=(char *)NULL; /* last dot not converted to underscore */


X int quote = FALSE; /* flag: next char is literal */

X int dotname = FALSE; /* flag: path component begins with dot */

X int error = 0;
X register unsigned workch; /* hold the character being tested */

X
X
X/*---------------------------------------------------------------------------


X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X
X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X renamed_fullpath = FALSE;
X

X/* GRR: for VMS, convert to internal format now or later? or never? */
X if (renamed) {
X cp = filename - 1; /* point to beginning of renamed name... */
X while (*++cp)
X if (*cp == '\\') /* convert backslashes to forward */
X *cp = '/';
X cp = filename;
X /* use temporary rootpath if user gave full pathname */
X if (filename[0] == '/') {
X renamed_fullpath = TRUE;
X pathcomp[0] = '/'; /* copy the '/' and terminate */
X pathcomp[1] = '\0';
X ++cp;
X } else if (isalpha(filename[0]) && filename[1] == ':') {
X renamed_fullpath = TRUE;
X pp = pathcomp;
X *pp++ = *cp++; /* copy the "d:" (+ '/', possibly) */
X *pp++ = *cp++;
X if (*cp == '/')
X *pp++ = *cp++; /* otherwise add "./"? */

X *pp = '\0';
X }
X }
X


X /* pathcomp is ignored unless renamed_fullpath is TRUE: */
X if ((error = checkdir(pathcomp, INIT)) != 0) /* initialize path buffer */

X return error; /* ...unless no mem or vol label on hard disk */
X


X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */
X if (!renamed) { /* cp already set if renamed */
X if (jflag) /* junking directories */

X cp = (char *)strrchr(filename, '/');
X if (cp == (char *)NULL) /* no '/' or not junking dirs */
X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X }

X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X


X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';

X/* GRR: can add 8.3 truncation here */
X if (last_dot) { /* one dot in directory name is legal */
X *last_dot = '.';
X last_dot = (char *)NULL;
X }


X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = (char *)NULL; /* leave directory semi-colons alone */
X break;
X
X case ':': /* drive names not stored in zipfile, */
X case '[': /* so no colons allowed; no brackets, */
X case ']': /* either */
X *pp++ = '_';
X break;
X


X case '.':
X if (pp == pathcomp) { /* nothing appended yet... */
X if (*cp == '/') { /* don't bother appending a "./" */
X ++cp; /* component to the path: skip */
X break; /* to next char after the '/' */

X } else if (*cp == '.' && cp[1] == '/') { /* "../" */
X *pp++ = '.'; /* add first dot, unchanged... */
X ++cp; /* skip second dot, since it will */


X } else { /* be "added" at end of if-block */

X *pp++ = '_'; /* FAT doesn't allow null filename */


X dotname = TRUE; /* bodies, so map .exrc -> _.exrc */
X } /* (extra '_' now, "dot" below) */
X } else if (dotname) { /* found a second dot, but still */
X dotname = FALSE; /* have extra leading underscore: */

X *pp = '\0'; /* remove it by shifting chars */
X pp = pathcomp + 1; /* left one space (e.g., .p1.p2: */
X while (pp[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */
X *pp = pp[1]; /* finished) [opt.: since first */
X ++pp; /* two chars are same, can start */


X } /* shifting at second position] */
X }

X last_dot = pp; /* point at last dot so far... */
X *pp++ = '_'; /* convert dot to underscore for now */
X break;
X


X case ';': /* start of VMS version? */

X lastsemi = pp; /* omit for now; remove VMS vers. later */
X break;
X


X case '\026': /* control-V quote for special chars */

X quote = TRUE; /* set flag for next character */
X break;
X
X case ' ': /* change spaces to underscore only */
X if (sflag) /* if specifically requested */


X *pp++ = '_';
X else

X *pp++ = (char)workch;


X break;
X
X default:

X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;

X } /* end switch */
X


X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X
X /* if not saving them, remove VMS version numbers (appended "###") */
X if (!V_flag && lastsemi) {

X pp = lastsemi; /* semi-colon was omitted: expect all #'s */


X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp == '\0') /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X }
X

X/* GRR: can add 8.3 truncation here */
X if (last_dot != (char *)NULL) /* one dot is OK: put it back in */


X *last_dot = '.'; /* (already done for directories) */

X
X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.

X ---------------------------------------------------------------------------*/
X
X if (filename[strlen(filename) - 1] == '/') {


X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {

X FPRINTF(stdout, " creating: %s\n", filename);
X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X


X if (*pathcomp == '\0') {

X FPRINTF(stderr, LoadFarString(ConversionFailed), filename);


X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);
X

X if (pInfo->vollabel) { /* set the volume label now */

X if (QCOND2)
X FPRINTF(stdout, "labelling %c: %-22s\n", (nLabelDrive + 'a' - 1),
X filename);
X if (volumelabel(filename)) {
X FPRINTF(stderr, LoadFarString(ErrSetVolLabel));
X return 3;
X }
X return 2; /* success: skip the "extraction" quietly */
X }


X
X return error;
X

X} /* end function mapname() */


X
X
X
X
X

X/***********************/
X/* Function checkdir() */
X/***********************/
X
Xint checkdir(pathcomp, flag)
X char *pathcomp;
X int flag;
X/*
X * returns: 1 - (on APPEND_NAME) truncated filename
X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be
X * 4 - path is too long
X * 10 - can't allocate memory for filename buffers
X */
X{
X static int rootlen = 0; /* length of rootpath */
X static char *rootpath; /* user's "extract-to" directory */

X static char *buildpath; /* full path (so far) to extracted file */
X static char *end; /* pointer to end of buildpath ('\0') */
X#ifdef MSC
X int attrs; /* work around MSC stat() bug */
X#endif


X
X# define FN_MASK 7
X# define FUNCTION (flag & FN_MASK)

X
X
X
X/*---------------------------------------------------------------------------


X APPEND_DIR: append the path component to the path being built and check
X for its existence. If doesn't exist and we are creating directories, do
X so for this one; else signal success or error as appropriate.

X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_DIR) {
X int too_long = FALSE;


X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));

X while ((*end = *pathcomp++) != '\0')
X ++end;


X
X /* GRR: could do better check, see if overrunning buffer as we go:

X * check end-buildpath after each append, set warning variable if
X * within 20 of FILNAMSIZ; then if var set, do careful check when


X * appending. Clear variable when begin new path. */
X

X if ((end-buildpath) > FILNAMSIZ-3) /* need '/', one-char name, '\0' */
X too_long = TRUE; /* check if extracting directory? */


X#ifdef MSC /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */

X if (_dos_getfileattr(buildpath, &attrs) || stat(buildpath, &statbuf))
X#else
X if (stat(buildpath, &statbuf)) /* path doesn't exist */


X#endif
X {
X if (!create_dirs) { /* told not to create (freshening) */

X free(buildpath);


X return 2; /* path doesn't exist: nothing to do */
X }
X if (too_long) {

X FPRINTF(stderr, LoadFarString(PathTooLong), buildpath);
X fflush(stderr);
X free(buildpath);


X return 4; /* no room for filenames: fatal */
X }

X if (MKDIR(buildpath, 0777) == -1) { /* create the directory */
X FPRINTF(stderr, LoadFarString(CantCreateDir), buildpath,
X filename);
X fflush(stderr);
X free(buildpath);


X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;

X } else if (!S_ISDIR(statbuf.st_mode)) {
X FPRINTF(stderr, LoadFarString(DirIsntDirectory), buildpath,
X filename);
X fflush(stderr);
X free(buildpath);


X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {

X FPRINTF(stderr, LoadFarString(PathTooLong), buildpath);
X fflush(stderr);
X free(buildpath);


X return 4; /* no room for filenames: fatal */
X }

X *end++ = '/';
X *end = '\0';
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0;
X


X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------

X GETPATH: copy full path to the string pointed at by pathcomp, and free
X buildpath.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {
X strcpy(pathcomp, buildpath);
X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
X free(buildpath);
X buildpath = end = (char *)NULL;


X return 0;
X }
X

X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.

X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {


X Trace((stderr, "appending filename [%s]\n", pathcomp));

X while ((*end = *pathcomp++) != '\0') {
X ++end;
X if ((end-buildpath) >= FILNAMSIZ) {
X *--end = '\0';
X FPRINTF(stderr, LoadFarString(PathTooLongTrunc),
X filename, buildpath);
X fflush(stderr);
X return 1; /* filename truncated */
X }
X }
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0; /* could check for existence here, prompt for new name... */
X }
X


X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.

X ---------------------------------------------------------------------------*/
X


X if (FUNCTION == INIT) {

X Trace((stderr, "initializing buildpath to "));
X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+1)) ==
X (char *)NULL)
X return 10;
X if (pInfo->vollabel) {


X/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
X if (renamed_fullpath && pathcomp[1] == ':')

X *buildpath = ToLower(*pathcomp);


X else if (!renamed_fullpath && rootpath && rootpath[1] == ':')

X *buildpath = ToLower(*rootpath);
X else {
X GETDRIVE(nLabelDrive); /* assumed that a == 1, b == 2, etc. */
X *buildpath = (char)(nLabelDrive - 1 + 'a');
X }
X nLabelDrive = *buildpath - 'a' + 1; /* save for mapname() */
X if (volflag == 0 || *buildpath < 'a' || /* no labels/bogus disk */


X (volflag == 1 && !isfloppy(nLabelDrive))) { /* -$: no fixed */

X free(buildpath);


X return IZ_VOL_LABEL; /* skipping with message */
X }

X *buildpath = '\0';
X end = buildpath;


X } else if (renamed_fullpath) { /* pathcomp = valid data */

X end = buildpath;
X while ((*end = *pathcomp++) != '\0')
X ++end;


X } else if (rootlen > 0) {

X strcpy(buildpath, rootpath);
X end = buildpath + rootlen;
X } else {
X *buildpath = '\0';
X end = buildpath;
X }
X Trace((stderr, "[%s]\n", buildpath));


X return 0;
X }
X

X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line. Note that under OS/2 and MS-DOS, if a candidate extract-to
X directory specification includes a drive letter (leading "x:"), it is
X treated just as if it had a trailing '/'--that is, one directory level
X will be created if the path doesn't exist, unless this is otherwise pro-
X hibited (e.g., freshening).
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));
X if (pathcomp == (char *)NULL) {
X rootlen = 0;

X return 0;
X }


X if ((rootlen = strlen(pathcomp)) > 0) {
X int had_trailing_pathsep=FALSE, has_drive=FALSE, xtra=2;
X
X if (isalpha(pathcomp[0]) && pathcomp[1] == ':')
X has_drive = TRUE; /* drive designator */
X if (pathcomp[rootlen-1] == '/') {
X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (has_drive && (rootlen == 2)) {
X if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */
X xtra = 3; /* room for '.' + '/' + 0 at end of "x:" */
X } else if (rootlen > 0) { /* need not check "x:." and "x:/" */
X#ifdef MSC

X /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */
X if (_dos_getfileattr(pathcomp, &attrs) ||


X SSTAT(pathcomp, &statbuf) || !S_ISDIR(statbuf.st_mode))
X#else
X if (SSTAT(pathcomp, &statbuf) || !S_ISDIR(statbuf.st_mode))
X#endif
X {
X /* path does not exist */
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || (!has_drive && !had_trailing_pathsep)
X#endif
X ) {
X rootlen = 0;
X return 2; /* treat as stored file */
X }

X/* GRR: scan for wildcard characters? OS-dependent... if find any, return 2:
X * treat as stored file(s) */


X /* create directory (could add loop here to scan pathcomp
X * and create more than one level, but really necessary?) */
X if (MKDIR(pathcomp, 0777) == -1) {

X FPRINTF(stderr, LoadFarString(CantCreateExtractDir),


X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, */

X return 3; /* failed: file exists, or need 2+ levels */
X }
X }
X }


X if ((rootpath = (char *)malloc(rootlen+xtra)) == (char *)NULL) {
X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);
X if (xtra == 3) /* had just "x:", make "x:." */
X rootpath[rootlen++] = '.';
X rootpath[rootlen++] = '/';
X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));

X return 0;
X }


X#endif /* !SFX || SFX_EXDIR */
X
X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.

X ---------------------------------------------------------------------------*/
X


X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);

X return 0;
X }
X

X return 99; /* should never reach */
X
X} /* end function checkdir() */


X
X
X
X
X

X
X/***********************/
X/* Function isfloppy() */

X/***********************/
X
Xstatic int isfloppy(nDrive) /* more precisely, is it removable? */
X int nDrive;
X{
X union REGS regs;
X
X regs.h.ah = 0x44;
X regs.h.al = 0x08;
X regs.h.bl = (uch)nDrive;
X#ifdef __EMX__
X _int86(0x21, &regs, &regs);
X if (regs.x.flags & 1)
X#else
X intdos(&regs, &regs);
X if (regs.x.cflag) /* error: do default a/b check instead */
X#endif
X {
X Trace((stderr,
X "error in DOS function 0x44 (AX = 0x%04x): guessing instead...\n",
X regs.x.ax));


X return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;
X } else

X return regs.x.ax? FALSE : TRUE;


X}
X
X
X
X

X#if (!defined(__GO32__) && !defined(__EMX__))
X
Xtypedef struct dosfcb {
X uch flag; /* ff to indicate extended FCB */
X char res[5]; /* reserved */
X uch vattr; /* attribute */
X uch drive; /* drive (1=A, 2=B, ...) */
X uch vn[11]; /* file or volume name */
X char dmmy[5];
X uch nn[11]; /* holds new name if renaming (else reserved) */
X char dmmy2[9];
X} dos_fcb;
X
X/**************************/
X/* Function volumelabel() */
X/**************************/
X
Xstatic int volumelabel(newlabel)
X char *newlabel;
X{
X#ifdef DEBUG
X char *p;
X#endif
X int len = strlen(newlabel);
X dos_fcb fcb, dta, far *pfcb=&fcb, far *pdta=&dta;
X struct SREGS sregs;
X union REGS regs;
X
X
X/*---------------------------------------------------------------------------
X Label the diskette specified by nLabelDrive using FCB calls. (Old ver-
X sions of MS-DOS and OS/2 DOS boxes can't use DOS function 3Ch to create
X labels.) Must use far pointers for MSC FP_* macros to work; must pad
X FCB filenames with spaces; and cannot include dot in 8th position. May
X or may not need to zero out FCBs before using; do so just in case.
X ---------------------------------------------------------------------------*/
X
X memset((char *)&dta, 0, sizeof(dos_fcb));
X memset((char *)&fcb, 0, sizeof(dos_fcb));
X
X#ifdef DEBUG
X for (p = (char *)&dta; (p - (char *)&dta) < sizeof(dos_fcb); ++p)
X if (*p)
X fprintf(stderr, "error: dta[%d] = %x\n", (p - (char *)&dta), *p);
X for (p = (char *)&fcb; (p - (char *)&fcb) < sizeof(dos_fcb); ++p)
X if (*p)
X fprintf(stderr, "error: fcb[%d] = %x\n", (p - (char *)&fcb), *p);
X printf("testing pointer macros:\n");
X segread(&sregs);
X printf("cs = %x, ds = %x, es = %x, ss = %x\n", sregs.cs, sregs.ds, sregs.es,
X sregs.ss);


X#endif /* DEBUG */
X

X#if 0
X#ifdef __TURBOC__
X bdosptr(0x1a, dta, DO_NOT_CARE);
X#else
X (intdosx method below)


X#endif
X#endif /* 0 */
X

X /* set the disk transfer address for subsequent FCB calls */
X sregs.ds = FP_SEG(pdta);
X regs.x.dx = FP_OFF(pdta);
X Trace((stderr, "segment:offset of pdta = %x:%x\n", sregs.ds, regs.x.dx));
X Trace((stderr, "&dta = %lx, pdta = %lx\n", (ulg)&dta, (ulg)pdta));
X regs.h.ah = 0x1a;
X intdosx(&regs, &regs, &sregs);
X
X /* fill in the FCB */
X sregs.ds = FP_SEG(pfcb);
X regs.x.dx = FP_OFF(pfcb);
X pfcb->flag = 0xff; /* extended FCB */
X pfcb->vattr = 0x08; /* attribute: disk volume label */
X pfcb->drive = (uch)nLabelDrive;
X
X#ifdef DEBUG
X Trace((stderr, "segment:offset of pfcb = %x:%x\n", sregs.ds, regs.x.dx));
X Trace((stderr, "&fcb = %lx, pfcb = %lx\n", (ulg)&fcb, (ulg)pfcb));
X Trace((stderr, "(2nd check: labelling drive %c:)\n", pfcb->drive-1+'A'));
X if (pfcb->flag != fcb.flag)
X fprintf(stderr, "error: pfcb->flag = %d, fcb.flag = %d\n",
X pfcb->flag, fcb.flag);
X if (pfcb->drive != fcb.drive)
X fprintf(stderr, "error: pfcb->drive = %d, fcb.drive = %d\n",
X pfcb->drive, fcb.drive);
X if (pfcb->vattr != fcb.vattr)
X fprintf(stderr, "error: pfcb->vattr = %d, fcb.vattr = %d\n",
X pfcb->vattr, fcb.vattr);


X#endif /* DEBUG */
X

X /* check for existing label */
X Trace((stderr, "searching for existing label via FCBs\n"));
X regs.h.ah = 0x11; /* FCB find first */
X#if 0 /* THIS STRNCPY FAILS (MSC bug?): */
X strncpy(pfcb->vn, "???????????", 11); /* i.e., "*.*" */
X Trace((stderr, "pfcb->vn = %lx\n", (ulg)pfcb->vn));
X Trace((stderr, "flag = %x, drive = %d, vattr = %x, vn = %s = %s.\n",
X fcb.flag, fcb.drive, fcb.vattr, fcb.vn, pfcb->vn));
X#endif
X strncpy((char *)fcb.vn, "???????????", 11); /* i.e., "*.*" */
X Trace((stderr, "fcb.vn = %lx\n", (ulg)fcb.vn));
X Trace((stderr, "regs.h.ah = %x, regs.x.dx = %04x, sregs.ds = %04x\n",
X regs.h.ah, regs.x.dx, sregs.ds));
X Trace((stderr, "flag = %x, drive = %d, vattr = %x, vn = %s = %s.\n",
X fcb.flag, fcb.drive, fcb.vattr, fcb.vn, pfcb->vn));
X intdosx(&regs, &regs, &sregs);
X
X/*---------------------------------------------------------------------------
X If not previously labelled, write a new label. Otherwise just rename,
X since MS-DOS 2.x has a bug which damages the FAT when the old label is
X deleted.
X ---------------------------------------------------------------------------*/
X
X if (regs.h.al) {
X Trace((stderr, "no label found\n\n"));
X regs.h.ah = 0x16; /* FCB create file */
X strncpy((char *)fcb.vn, newlabel, len);
X if (len < 11) /* fill with spaces */
X strncpy((char *)(fcb.vn+len), " ", 11-len);
X Trace((stderr, "fcb.vn = %lx pfcb->vn = %lx\n", (ulg)fcb.vn,
X (ulg)pfcb->vn));
X Trace((stderr, "flag = %x, drive = %d, vattr = %x\n", fcb.flag,
X fcb.drive, fcb.vattr));
X Trace((stderr, "vn = %s = %s.\n", fcb.vn, pfcb->vn));
X intdosx(&regs, &regs, &sregs);
X regs.h.ah = 0x10; /* FCB close file */
X if (regs.h.al) {
X Trace((stderr, "unable to write volume name (AL = %x)\n",
X regs.h.al));
X intdosx(&regs, &regs, &sregs);
X return 1;
X } else {
X intdosx(&regs, &regs, &sregs);
X Trace((stderr, "new volume label [%s] written\n", newlabel));
X return 0;
X }
X } else {
X Trace((stderr, "found old label [%s]\n\n", dta.vn)); /* not term. */
X regs.h.ah = 0x17; /* FCB rename */
X strncpy((char *)fcb.vn, (char *)dta.vn, 11);
X strncpy((char *)fcb.nn, newlabel, len);
X if (len < 11) /* fill with spaces */
X strncpy((char *)(fcb.nn+len), " ", 11-len);
X Trace((stderr, "fcb.vn = %lx pfcb->vn = %lx\n", (ulg)fcb.vn,
X (ulg)pfcb->vn));
X Trace((stderr, "fcb.nn = %lx pfcb->nn = %lx\n", (ulg)fcb.nn,
X (ulg)pfcb->nn));
X Trace((stderr, "flag = %x, drive = %d, vattr = %x\n", fcb.flag,
X fcb.drive, fcb.vattr));
X Trace((stderr, "vn = %s = %s.\n", fcb.vn, pfcb->vn));
X Trace((stderr, "nn = %s = %s.\n", fcb.nn, pfcb->nn));
X intdosx(&regs, &regs, &sregs);
X if (regs.h.al) {
X Trace((stderr, "Unable to change volume name (AL = %x)\n",
X regs.h.al));
X return 1;
X } else {
X Trace((stderr, "volume label changed to [%s]\n", newlabel));


X return 0;
X }
X }

X} /* end function volumelabel() */
X
X#endif /* !__GO32__ && !__EMX__ */


X
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()

X /*
X * MS-DOS VERSION
X *
X * Set the output file date/time stamp according to information from the
X * zipfile directory record for this member, then close the file and set
X * its permissions (archive, hidden, read-only, system). Aside from closing
X * the file, this routine is optional (but most compilers support it).
X */
X{
X#ifdef __TURBOC__
X union {
X struct ftime ft; /* system file time record */
X struct {
X ush ztime; /* date and time words */
X ush zdate; /* .. same format as in .ZIP file */
X } zt;
X } td;
X#endif
X
X
X/*---------------------------------------------------------------------------
X Copy and/or convert time and date variables, if necessary; then set the
X file time/date. WEIRD BORLAND "BUG": if output is buffered, and if run
X under at least some versions of DOS (e.g., 6.0), and if files are smaller
X than DOS physical block size (i.e., 512 bytes) (?), then files MAY NOT
X get timestamped correctly--apparently setftime() occurs before any data
X are written to the file, and when file is closed and buffers are flushed,
X timestamp is overwritten with current time. Even with a 32K buffer, this
X does not seem to occur with larger files. UnZip output is now unbuffered,
X but if it were not, could still avoid problem by adding "fflush(outfile)"
X just before setftime() call. Weird, huh?
X ---------------------------------------------------------------------------*/
X
X#ifdef __TURBOC__
X td.zt.ztime = lrec.last_mod_file_time;
X td.zt.zdate = lrec.last_mod_file_date;
X setftime(fileno(outfile), &td.ft);
X#else
X _dos_setftime(fileno(outfile), lrec.last_mod_file_date,
X lrec.last_mod_file_time);
X#endif
X
X/*---------------------------------------------------------------------------
X And finally we can close the file...at least everybody agrees on how to
X do *this*. I think... Also change the mode according to the stored file
X attributes, since we didn't do that when we opened the dude.
X ---------------------------------------------------------------------------*/
X
X fclose(outfile);
X
X#ifdef __TURBOC__
X# if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0452))
X# define Chmod _rtl_chmod
X# else
X# define Chmod _chmod
X# endif
X if (Chmod(filename, 1, pInfo->file_attr) != pInfo->file_attr)
X FPRINTF(stderr, "\nwarning: file attributes may not be correct\n");
X#else /* !__TURBOC__ */
X _dos_setfileattr(filename, pInfo->file_attr);
X#endif /* ?__TURBOC__ */
X
X} /* end function close_outfile() */


X
X
X
X
X

X#ifndef SFX
X
X/*************************/
X/* Function dateformat() */
X/*************************/
X
Xint dateformat()
X{
X

X/*---------------------------------------------------------------------------


X For those operating systems which support it, this function returns a

X value which tells how national convention says that numeric dates are
X displayed. Return values are DF_YMD, DF_DMY and DF_MDY (the meanings
X should be fairly obvious).
X ---------------------------------------------------------------------------*/
X
X#ifndef MSWIN
X#if (!defined(__GO32__) && !defined(__EMX__))
X unsigned short _CountryInfo[18];
X unsigned short far *CountryInfo = _CountryInfo;
X struct SREGS sregs;
X union REGS regs;
X
X sregs.ds = FP_SEG(CountryInfo);
X regs.x.dx = FP_OFF(CountryInfo);
X regs.x.ax = 0x3800;
X int86x(0x21, &regs, &regs, &sregs);
X
X#else /* __GO32__ || __EMX__ */
X unsigned short CountryInfo[18];
X
X _dos_getcountryinfo(CountryInfo);
X#endif
X
X switch(CountryInfo[0]) {


X case 0:
X return DF_MDY;
X case 1:
X return DF_DMY;
X case 2:
X return DF_YMD;
X }

X#endif /* !MSWIN */
X
X return DF_MDY; /* default for systems without locale info */
X
X} /* end function dateformat() */


X
X
X
X
X

X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if defined(__WATCOMC__) || defined(__TURBOC__) || defined(_MSC_VER)


X char buf[80];
X#endif
X
X PRINTF(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */
X "emx+gcc ",

X# else
X# ifdef __GO32__ /* ...so is __GO32__ (double sigh) */
X "djgpp gcc ",
X# else
X "gcc ",
X# endif
X# endif
X __VERSION__,


X#else
X#ifdef __WATCOMC__
X "Watcom C", (sprintf(buf, " (__WATCOMC__ = %d)", __WATCOMC__), buf),
X#else
X#ifdef __TURBOC__
X# ifdef __BORLANDC__
X "Borland C++",
X# if (__BORLANDC__ < 0x0200)
X " 1.0",
X# else

X# if (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */


X " 2.0",
X# else
X# if (__BORLANDC__ == 0x0400)
X " 3.0",
X# else

X# if (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */


X " 3.1",
X# else

X# if (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */
X " 4.0 or 4.02",
X# else
X " later than 4.1",


X# endif
X# endif
X# endif
X# endif
X# endif

X# else
X "Turbo C",

X# if (__TURBOC__ >= 0x0400) /* Kevin: 3.0 -> 0x0401 */
X "++ 3.0 or later",
X# else
X# if (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */
X "++ 1.0",
X# else
X# if ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */


X " 2.0",
X# else

X# if (__TURBOC__ > 0x0100)
X " 1.5", /* James: 0x0105? */
X# else
X " 1.0", /* James: 0x0100 */
X# endif
X# endif


X# endif
X# endif
X# endif

X#else
X#ifdef MSC
X "Microsoft C ",
X# ifdef _MSC_VER

X# if (_MSC_VER == 800)
X "8.0/8.0c (Visual C++ 1.0/1.5)",
X# else


X (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf),

X# endif


X# else
X "5.1 or earlier",
X# endif
X#else
X "unknown compiler", "",
X#endif /* MSC */
X#endif /* __TURBOC__ */
X#endif /* __WATCOMC__ */

X#endif /* __GNUC__ */
X
X "MS-DOS",
X
X#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__)))
X " (32-bit)",
X#else


X# if defined(M_I86HM) || defined(__HUGE__)
X " (16-bit, huge)",
X# else
X# if defined(M_I86LM) || defined(__LARGE__)
X " (16-bit, large)",
X# else
X# if defined(M_I86MM) || defined(__MEDIUM__)
X " (16-bit, medium)",
X# else
X# if defined(M_I86CM) || defined(__COMPACT__)
X " (16-bit, compact)",
X# else
X# if defined(M_I86SM) || defined(__SMALL__)
X " (16-bit, small)",
X# else
X# if defined(M_I86TM) || defined(__TINY__)
X " (16-bit, tiny)",
X# else
X " (16-bit)",

X# endif
X# endif
X# endif
X# endif
X# endif
X# endif

X#endif
X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""

X#endif
X );
X


X /* temporary debugging code for Borland compilers only */
X#ifdef __TURBOC__

X PRINTF("\tdebug(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__, __TURBOC__);
X#ifdef __BORLANDC__
X PRINTF("\tdebug(__BORLANDC__ = 0x%04x)\n", __BORLANDC__);


X#else
X PRINTF("\tdebug(__BORLANDC__ not defined)\n");
X#endif
X#ifdef __TCPLUSPLUS__

X PRINTF("\tdebug(__TCPLUSPLUS__ = 0x%04x)\n", __TCPLUSPLUS__);


X#else
X PRINTF("\tdebug(__TCPLUSPLUS__ not defined)\n");
X#endif
X#ifdef __BCPLUSPLUS__

X PRINTF("\tdebug(__BCPLUSPLUS__ = 0x%04x)\n\n", __BCPLUSPLUS__);


X#else
X PRINTF("\tdebug(__BCPLUSPLUS__ not defined)\n\n");

X#endif
X#endif
X
X} /* end function version() */
X
X#endif /* !SFX */


X
X
X
X
X

X#if (defined(__GO32__) || defined(__EMX__))
X
Xint volatile _doserrno;
X
Xunsigned _dos_getcountryinfo(void *countrybuffer)
X{
X asm("movl %0, %%edx": : "g" (countrybuffer));
X asm("movl $0x3800, %eax");
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X _doserrno = 0;
X asm("jnc 1f");
X asm("movl %%eax, %0": "=m" (_doserrno));
X asm("1:");
X return _doserrno;
X}
X
Xvoid _dos_setftime(int fd, ush dosdate, ush dostime)
X{
X asm("movl %0, %%ebx": : "g" (fd));
X asm("movl %0, %%ecx": : "g" (dostime));
X asm("movl %0, %%edx": : "g" (dosdate));
X asm("movl $0x5701, %eax");
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X}
X
Xvoid _dos_setfileattr(char *name, int attr)
X{
X asm("movl %0, %%edx": : "g" (name));
X asm("movl %0, %%ecx": : "g" (attr));
X asm("movl $0x4301, %eax");
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X}
X
Xvoid _dos_getdrive(unsigned *d)
X{
X asm("movl $0x1900, %eax");
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X asm("xorb %ah, %ah");
X asm("incb %al");
X asm("movl %%eax, %0": "=a" (*d));
X}
X
Xunsigned _dos_creat(char *path, unsigned attr, int *fd)
X{
X asm("movl $0x3c00, %eax");
X asm("movl %0, %%edx": :"g" (path));
X asm("movl %0, %%ecx": :"g" (attr));
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X asm("movl %%eax, %0": "=a" (*fd));
X _doserrno = 0;
X asm("jnc 1f");
X _doserrno = *fd;
X switch (_doserrno) {
X case 3:
X errno = ENOENT;
X break;
X case 4:
X errno = EMFILE;
X break;
X case 5:
X errno = EACCES;
X break;
X }
X asm("1:");
X return _doserrno;
X}
X
Xunsigned _dos_close(int fd)
X{
X asm("movl %0, %%ebx": : "g" (fd));
X asm("movl $0x3e00, %eax");
X asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
X _doserrno = 0;
X asm("jnc 1f");
X asm ("movl %%eax, %0": "=m" (_doserrno));
X if (_doserrno == 6) {
X errno = EBADF;
X }
X asm("1:");
X return _doserrno;
X}
X
Xstatic int volumelabel(char *name)
X{
X int fd;
X
X return _dos_creat(name, FA_LABEL, &fd) ? fd : _dos_close(fd);
X}
X
X#endif /* __GO32__ || __EMX__ */
END_OF_FILE
if test 46263 -ne `wc -c <'unzip-5.12/msdos/msdos.c'`; then
echo shar: \"'unzip-5.12/msdos/msdos.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/msdos.c'
fi
if test -f 'unzip-5.12/zipinfo.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/zipinfo.doc'\"
else
echo shar: Extracting \"'unzip-5.12/zipinfo.doc'\" \(21079 characters\)
sed "s/^X//" >'unzip-5.12/zipinfo.doc' <<'END_OF_FILE'
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
XNAME
X zipinfo - list detailed information about a ZIP archive
X
XSYNOPSIS
X zipinfo [-12smlvhtTz] file[.zip] [file(s) ...]
X [-x xfile(s) ...]
X
X unzip -Z [-12smlvhtTz] file[.zip] [file(s) ...]
X [-x xfile(s) ...]
X
XDESCRIPTION
X zipinfo lists technical information about files in a ZIP
X archive, most commonly found on MS-DOS systems. Such infor-
X mation includes file access permissions, encryption status,
X type of compression, version and operating system or file
X system of compressing program, and the like. The default
X behavior (with no options) is to list single-line entries
X for each file in the archive, with header and trailer lines
X providing summary information for the entire archive. The
X format is a cross between Unix ``ls -l'' and ``unzip -v''
X output. See DETAILED DESCRIPTION below. Note that zipinfo
X is the same program as unzip (under Unix, a link to it); on
X some systems, however, zipinfo support may have been omitted
X when unzip was compiled.
X
XARGUMENTS
X file[.zip]
X Path of the ZIP archive(s). If the file specification
X is a wildcard, each matching file is processed in an
X order determined by the operating system (or file sys-
X tem). Only the filename can be a wildcard; the path
X itself cannot. Wildcard expressions are similar to
X Unix egrep(1) (regular) expressions and may contain:
X
X * matches a sequence of 0 or more characters
X
X ? matches exactly 1 character
X
X [...]
X matches any single character found inside the
X brackets; ranges are specified by a beginning
X character, a hyphen, and an ending character. If
X an exclamation point or a caret (`!' or `^') fol-
X lows the left bracket, then the range of charac-
X ters within the brackets is complemented (that is,
X anything except the characters inside the brackets
X is considered a match).
X
X (Be sure to quote any character which might otherwise
X be interpreted or modified by the operating system,
X particularly under Unix and VMS.) If no matches are
X found, the specification is assumed to be a literal
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 1
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X filename; and if that also fails, the suffix .zip is
X appended. Note that self-extracting ZIP files are sup-
X ported; just specify the .exe suffix (if any) expli-
X citly.
X
X [file(s)]
X An optional list of archive members to be processed.
X Regular expressions (wildcards) may be used to match
X multiple members; see above. Again, be sure to quote
X expressions that would otherwise be expanded or modi-
X fied by the operating system.
X
X [-x xfile(s)]
X An optional list of archive members to be excluded from
X processing.
X
XOPTIONS
X -1 list filenames only, one per line. This option
X excludes all others; headers, trailers and zipfile com-
X ments are never printed. It is intended for use in
X Unix shell scripts.
X
X -2 list filenames only, one per line, but allow headers
X (-h), trailers (-t) and zipfile comments (-z), as well.
X This option may be useful in cases where the stored
X filenames are particularly long.
X
X -s list zipfile info in short Unix ``ls -l'' format. This
X is the default behavior; see below.
X
X -m list zipfile info in medium Unix ``ls -l'' format.
X Identical to the -s output, except that the compression
X factor, expressed as a percentage, is also listed.
X
X -l list zipfile info in long Unix ``ls -l'' format. As
X with -m except that the compressed size (in bytes) is
X printed instead of the compression ratio.
X
X -v list zipfile information in verbose, multi-page format.
X
X -h list header line. The archive name, actual size (in
X bytes) and total number of files is printed.
X
X -t list totals for files listed or for all files. The
X number of files listed, their uncompressed and
X compressed total sizes, and their overall compression
X factor is printed; or, if only the totals line is being
X printed, the values for the entire archive are given.
X Note that the total compressed (data) size will never
X match the actual zipfile size, since the latter
X includes all of the internal zipfile headers in addi-
X tion to the compressed data.
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 2
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X -T print the file dates and times in a sortable decimal
X format (yymmdd.hhmmss). The default date format is a
X more standard, human-readable version with abbreviated
X month names (see examples below).
X
X -z include the archive comment (if any) in the listing.
X
XDETAILED DESCRIPTION
X zipinfo has a number of modes, and its behavior can be
X rather difficult to fathom if one isn't familiar with Unix
X ls(1) (or even if one is). The default behavior is to list
X files in the following format:
X
X-rw-rws--- 1.9 unx 2802 t- defX 11-Aug-91 13:48 perms.2660
X
X The last three fields are the modification date and time of
X the file, and its name. The case of the filename is
X respected; thus files which come from MS-DOS PKZIP are
X always capitalized. If the file was zipped with a stored
X directory name, that is also displayed as part of the
X filename.
X
X The second and third fields indicate that the file was
X zipped under Unix with version 1.9 of zip. Since it comes
X from Unix, the file permissions at the beginning of the line
X are printed in Unix format. The uncompressed file-size
X (2802 in this example) is the fourth field.
X
X The fifth field consists of two characters, either of which
X may take on several values. The first character may be
X either `t' or `b', indicating that zip believes the file to
X be text or binary, respectively; but if the file is
X encrypted, zipinfo notes this fact by capitalizing the char-
X acter (`T' or `B'). The second character may also take on
X four values, depending on whether there is an extended local
X header and/or an ``extra field'' associated with the file
X (fully explained in PKWare's APPNOTE.TXT, but basically
X analogous to pragmas in ANSI C--i.e., they provide a stan-
X dard way to include non-standard information in the
X archive). If neither exists, the character will be a hyphen
X (`-'); if there is an extended local header but no extra
X field, `l'; if the reverse, `x'; and if both exist, `X'.
X Thus the file in this example is (probably) a text file, is
X not encrypted, and has neither an extra field nor an
X extended local header associated with it. The example
X below, on the other hand, is an encrypted binary file with
X an extra field:
X
XRWD,R,R 0.9 vms 168 Bx shrk 9-Aug-91 19:15 perms.0644
X
X Extra fields are used for various purposes (see discussion
X of the -v option below) including the storage of VMS file
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 3
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X attributes, which is presumably the case here. Note that
X the file attributes are listed in VMS format. Some other
X possibilities for the host operating system (which is actu-
X ally a misnomer--host file system is more correct) include
X OS/2 or NT with High Performance File System (HPFS), MS-DOS,
X OS/2 or NT with File Allocation Table (FAT) file system, and
X Macintosh. These are denoted as follows:
X
X-rw-a-- 1.0 hpf 5358 Tl i4:3 4-Dec-91 11:33 longfilename.hpfs
X-r--ahs 1.1 fat 4096 b- i4:2 14-Jul-91 12:58 EA DATA. SF
X--w------- 1.0 mac 17357 bx i8:2 4-May-92 04:02 unzip.macr
X
X File attributes in the first two cases are indicated in a
X Unix-like format, where the seven subfields indicate whether
X the file: (1) is a directory, (2) is readable (always
X true), (3) is writable, (4) is executable (guessed on the
X basis of the extension--.exe, .com, .bat, .cmd and .btm
X files are assumed to be so), (5) has its archive bit set,
X (6) is hidden, and (7) is a system file. Interpretation of
X Macintosh file attributes is unreliable because some Macin-
X tosh archivers don't store any attributes in the archive.
X
X Finally, the sixth field indicates the compression method
X and possible sub-method used. There are six methods known
X at present: storing (no compression), reducing, shrinking,
X imploding, tokenizing (never publicly released), and deflat-
X ing. In addition, there are four levels of reducing (1
X through 4); four types of imploding (4K or 8K sliding dic-
X tionary, and 2 or 3 Shannon-Fano trees); and four levels of
X deflating (superfast, fast, normal, maximum compression).
X zipinfo represents these methods and their sub-methods as
X follows: stor; re:1, re:2, etc.; shrk; i4:2, i8:3, etc.;
X tokn; and defS, defF, defN, and defX.
X
X The medium and long listings are almost identical to the
X short format except that they add information on the file's
X compression. The medium format lists the file's compression
X factor as a percentage indicating the amount of space which
X has been ``removed'':
X
X-rw-rws--- 1.5 unx 2802 t- 81% defX 11-Aug-91 13:48 perms.2660
X
X In this example, the file has been compressed by more than a
X factor of five; the compressed data are only 19% of the ori-
X ginal size. The long format gives the compressed file's
X size in bytes, instead:
X
X-rw-rws--- 1.5 unx 2802 t- 538 defX 11-Aug-91 13:48 perms.2660
X
X Adding the -T option changes the file date and time to
X decimal format:
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 4
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X-rw-rws--- 1.5 unx 2802 t- 538 defX 910811.134804 perms.2660
X
X Note that because of limitations in the MS-DOS format used
X to store file times, the seconds field is always rounded to
X the nearest even second. For Unix files this is expected to
X change in the next major releases of zip(1L) and unzip.
X
X In addition to individual file information, a default zip-
X file listing also includes header and trailer lines:
X
XArchive: OS2.zip 5453 bytes 5 files
X,,rw, 1.0 hpf 730 b- i4:3 26-Jun-92 23:40 Contents
X,,rw, 1.0 hpf 3710 b- i4:3 26-Jun-92 23:33 makefile.os2
X,,rw, 1.0 hpf 8753 b- i8:3 26-Jun-92 15:29 os2unzip.c
X,,rw, 1.0 hpf 98 b- stor 21-Aug-91 15:34 unzip.def
X,,rw, 1.0 hpf 95 b- stor 21-Aug-91 17:51 zipinfo.def
X5 files, 13386 bytes uncompressed, 4951 bytes compressed: 63.0%
X
X The header line gives the name of the archive, its total
X size, and the total number of files; the trailer gives the
X number of files listed, their total uncompressed size, and
X their total compressed size (not including any of zip's
X internal overhead). If, however, one or more file(s) are
X provided, the header and trailer lines are not listed. This
X behavior is also similar to that of Unix's ``ls -l''; it may
X be overridden by specifying the -h and -t options expli-
X citly. In such a case the listing format must also be
X specified explicitly, since -h or -t (or both) in the
X absence of other options implies that ONLY the header or
X trailer line (or both) is listed. See the EXAMPLES section
X below for a semi-intelligible translation of this nonsense.
X
X The verbose listing is mostly self-explanatory. It also
X lists file comments and the zipfile comment, if any, and the
X type and number of bytes in any stored extra fields.
X Currently known types of extra fields include PKWARE's
X authentication (``AV'') info; OS/2 extended attributes; VMS
X filesystem info, both PKWARE and Info-ZIP versions; Macin-
X tosh resource forks; Acorn/Archimedes SparkFS info; and so
X on. (Note that in the case of OS/2 extended attributes--
X perhaps the most common use of zipfile extra fields--the
X size of the stored EAs as reported by zipinfo may not match
X the number given by OS/2's dir command: OS/2 always reports
X the number of bytes required in 16-bit format, whereas
X zipinfo always reports the 32-bit storage.)
X
XENVIRONMENT OPTIONS
X Modifying zipinfo's default behavior via options placed in
X an environment variable can be a bit complicated to explain,
X due to zipinfo's attempts to handle various defaults in an
X intuitive, yet Unix-like, manner. (Try not to laugh.)
X Nevertheless, there is some underlying logic. In brief,
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 5
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X there are three ``priority levels'' of options: the default
X options; environment options, which can override or add to
X the defaults; and explicit options given by the user, which
X can override or add to either of the above.
X
X The default listing format, as noted above, corresponds
X roughly to the "zipinfo -hst" command (except when indivi-
X dual zipfile members are specified). A user who prefers the
X long-listing format (-l) can make use of the zipinfo's
X environment variable to change this default:
X
X ZIPINFO=-l; export ZIPINFO Unix Bourne shell
X setenv ZIPINFO -l Unix C shell
X set ZIPINFO=-l OS/2 or MS-DOS
X define ZIPINFO_OPTS "-l" VMS (quotes for lowercase)
X
X If, in addition, the user dislikes the trailer line,
X zipinfo's concept of ``negative options'' may be used to
X override the default inclusion of the line. This is accom-
X plished by preceding the undesired option with one or more
X minuses: e.g., ``-l-t'' or ``--tl'', in this example. The
X first hyphen is the regular switch character, but the one
X before the `t' is a minus sign. The dual use of hyphens may
X seem a little awkward, but it's reasonably intuitive
X nonetheless: simply ignore the first hyphen and go from
X there. It is also consistent with the behavior of the Unix
X command nice(1).
X
X As suggested above, the default variable names are
X ZIPINFO_OPTS for VMS (where the symbol used to install
X zipinfo as a foreign command would otherwise be confused
X with the environment variable), and ZIPINFO for all other
X operating systems. For compatibility with zip(1L), ZIPIN-
X FOOPT is also accepted (don't ask). If both ZIPINFO and
X ZIPINFOOPT are defined, however, ZIPINFO takes precedence.
X unzip's diagnostic option (-v with no zipfile name) can be
X used to check the values of all four possible unzip and
X zipinfo environment variables.
X
XEXAMPLES
X To get a basic, short-format listing of the complete con-
X tents of a ZIP archive storage.zip, with both header and
X totals lines, use only the archive name as an argument to
X zipinfo:
X
X zipinfo storage
X
X To produce a basic, long-format listing (not verbose),
X including header and totals lines, use -l:
X
X zipinfo -l storage
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 6
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X To list the complete contents of the archive without header
X and totals lines, either negate the -h and -t options or
X else specify the contents explicitly:
X
X zipinfo --h-t storage
X zipinfo storage \*
X
X (where the backslash is required only if the shell would
X otherwise expand the `*' wildcard, as in Unix when globbing
X is turned on--double quotes around the asterisk would have
X worked as well). To turn off the totals line by default,
X use the environment variable (C shell is assumed here):
X
X setenv ZIPINFO --t
X zipinfo storage
X
X To get the full, short-format listing of the first example
X again, given that the environment variable is set as in the
X previous example, it is necessary to specify the -s option
X explicitly, since the -t option by itself implies that ONLY
X the footer line is to be printed:
X
X setenv ZIPINFO --t
X zipinfo -t storage [only totals line]
X zipinfo -st storage [full listing]
X
X The -s option, like -m and -l, includes headers and footers
X by default, unless otherwise specified. Since the environ-
X ment variable specified no footers and that has a higher
X precedence than the default behavior of -s, an explicit -t
X option was necessary to produce the full listing. Nothing
X was indicated about the header, however, so the -s option
X was sufficient. Note that both the -h and -t options, when
X used by themselves or with each other, override any default
X listing of member files; only the header and/or footer are
X printed. This behavior is useful when zipinfo is used with
X a wildcard zipfile specification; the contents of all zip-
X files are then summarized with a single command.
X
X To list information on a single file within the archive, in
X medium format, specify the filename explicitly:
X
X zipinfo -m storage unshrink.c
X
X The specification of any member file, as in this example,
X will override the default header and totals lines; only the
X single line of information about the requested file will be
X printed. This is intuitively what one would expect when
X requesting information about a single file. For multiple
X files, it is often useful to know the total compressed and
X uncompressed size; in such cases -t may be specified expli-
X citly:
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 7
X
XZIPINFO(1L) MISC. REFERENCE MANUAL PAGES ZIPINFO(1L)
X
X zipinfo -mt storage "*.[ch]" Mak\*
X
X To get maximal information about the ZIP archive, use the
X verbose option. It is usually wise to pipe the output into
X a filter such as Unix more(1) if the operating system allows
X it:
X
X zipinfo -v storage | more
X
X Finally, to see the most recently modified files in the
X archive, use the -T option in conjunction with an external
X sorting utility such as Unix sort(1) (and tail(1) as well,
X in this example):
X
X zipinfo -T storage | sort -n +6 | tail -15
X
X The -n option to sort(1) tells it to sort numerically rather
X than in ASCII order, and the +6 option tells it to sort on
X the sixth field after the first one (i.e., the seventh
X field). This assumes the default short-listing format; if
X -m or -l is used, the proper sort(1) option would be +7.
X The tail(1) command filters out all but the last 15 lines of
X the listing. Future releases of zipinfo may incorporate
X date/time and filename sorting as built-in options.
X
XTIPS
X The author finds it convenient to define an alias ii for
X zipinfo on systems which allow aliases (or, on other sys-
X tems, copy/rename the executable, create a link or create a
X command file with the name ii). The ii usage parallels the
X common ll alias for long listings in Unix, and the similar-
X ity between the outputs of the two commands was intentional.
X
XBUGS
X None known at this time, but we're always delighted to find
X a good one.
X
XSEE ALSO
X ls(1), funzip(1L), unzip(1L), unzipsfx(1L), zip(1L),
X zipcloak(1L), zipnote(1L), zipsplit(1L)
X
XAUTHOR
X Greg Roelofs (a.k.a. Cave Newt). ZipInfo contains pattern-
X matching code by Mark Adler and fixes/improvements by many
X others. Please refer to the CONTRIBS file in the UnZip
X source distribution for a more complete list.
X
XInfo-ZIP Last change: 28 Aug 94 (v2.02) 8
X
END_OF_FILE
if test 21079 -ne `wc -c <'unzip-5.12/zipinfo.doc'`; then
echo shar: \"'unzip-5.12/zipinfo.doc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/zipinfo.doc'
fi
echo shar: End of archive 7 \(of 20\).
cp /dev/null ark7isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:15:22 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 73
Archive-name: unzip/part08

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/amiga/amiga.c unzip-5.12/nt/nt.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:40 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 8 (of 20)."'
if test -f 'unzip-5.12/amiga/amiga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/amiga.c'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/amiga.c'\" \(25728 characters\)
sed "s/^X//" >'unzip-5.12/amiga/amiga.c' <<'END_OF_FILE'
X/*------------------------------------------------------------------------
X
X amiga.c
X
X Amiga-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X See History.5xx for revision history.
X
X Contents: mapattr()
X mapname()
X do_wild()
X checkdir()
X cmptime()
X invlocal()
X close_outfile()
X _abort() (Aztec C only)
X version()
X
X ------------------------------------------------------------------------*/


X
X
X#include "unzip.h"
X

X/* Globular varibundus */
X
Xstatic int created_dir; /* used in mapname(), checkdir() */


Xstatic int renamed_fullpath; /* ditto */

X#define PERMS 0777
X#define MKDIR(path,mode) mkdir(path)
X
X
X#ifndef S_ISCRIPT /* not having one implies you have none */
X# define S_IARCHIVE 0020 /* not modified since this bit was last set */
X# define S_IREAD 0010 /* can be opened for reading */
X# define S_IWRITE 0004 /* can be opened for writing */
X# define S_IDELETE 0001 /* can be deleted */
X#endif /* S_ISCRIPT */
X
X#ifndef S_IRWD
X# define S_IRWD 0015 /* useful combo of Amiga privileges */
X#endif /* !S_IRWD */
X
X#ifndef S_IHIDDEN
X# define S_IHIDDEN 0200 /* hidden supported in future AmigaDOS (someday) */
X#endif /* !S_HIDDEN */


X
X
X
X/**********************/
X/* Function mapattr() */
X/**********************/
X

Xint mapattr(void) /* Amiga version */
X{
X ulg tmp = crec.external_file_attributes;
X
X
X /* Amiga attributes = hsparwed = hidden, script, pure, archive,
X * read, write, execute, delete */


X
X switch (pInfo->hostnum) {

X case AMIGA_:
X if ((tmp & 1) == (tmp>>18 & 1))
X tmp ^= 0x000F0000; /* PKAZip compatibility kluge */
X /* turn off archive bit for restored Amiga files */
X pInfo->file_attr = (unsigned)((tmp>>16) & (~S_IARCHIVE));
X break;
X
X case UNIX_: /* preserve read, write, execute: use logical-OR of */
X case VMS_: /* user, group, and other; if writable, set delete bit */
X tmp >>= 16;
X tmp = (( tmp>>6 | tmp>>3 | tmp) & 07) << 1;
X pInfo->file_attr = (unsigned)(tmp&S_IWRITE? tmp|S_IDELETE : tmp);
X break;
X
X /* all other platforms: assume read-only bit in DOS half of attribute
X * word is set correctly ==> will become READ or READ+WRITE+DELETE */
X case FS_FAT_:
X case FS_HPFS_: /* can add S_IHIDDEN check to MSDOS/OS2/NT eventually */
X case FS_NTFS_:
X case MAC_:
X case ATARI_:
X case TOPS20_:
X default:
X pInfo->file_attr = (unsigned)(tmp&1? S_IREAD : S_IRWD);
X break;
X


X } /* end switch (host-OS-created-by) */
X

X pInfo->file_attr &= 0xff; /* mask off all but lower eight bits */
X return 0;
X
X} /* end function mapattr() */
X
X
X
X


X/************************/
X/* Function mapname() */
X/************************/
X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
X{ /* 3 if error (skip file), 10 if no memory (skip file) */
X char pathcomp[FILNAMSIZ]; /* path-component buffer */

X char *pp, *cp=NULL; /* character pointers */
X char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */
X int quote = FALSE; /* flags */


X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X
X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X
X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X

X /* user gave full pathname: don't prepend rootpath */
X renamed_fullpath = (renamed && strchr(filename, ':'));
X
X if (checkdir((char *)NULL, INIT) == 10)
X return 10; /* initialize path buffer, unless no memory */


X
X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */

X if (jflag) /* junking directories */
X cp = (char *)strrchr(filename, '/');

X if (cp == NULL) /* no '/' or not junking dirs */


X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X

X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X
X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';

X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = NULL; /* leave directory semi-colons alone */
X break;
X
X case ';': /* VMS version (or DEC-20 attrib?) */
X lastsemi = pp; /* keep for now; remove VMS ";##" */
X *pp++ = (char)workch; /* later, if requested */


X break;
X
X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X

X default:
X /* allow European characters in filenames: */

X if (isprint(workch) || (128 <= workch && workch <= 255))


X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X

X /* if not saving them, remove with VMS version numbers (appended ";###") */


X if (!V_flag && lastsemi) {

X pp = lastsemi + 1;


X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp == '\0') /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X }
X

X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.
X ---------------------------------------------------------------------------*/
X
X if (filename[strlen(filename) - 1] == '/') {

X if (checkdir(filename, GETPATH) == 1) {
X fprintf(stderr, "pathname too long: truncat{ed/ing}\n");
X return 1; /* GRR: NEEDS WORK! (do checking only when appending) */
X }


X if (created_dir && QCOND2) {

X fprintf(stdout, " creating: %s\n", filename);


X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X
X if (*pathcomp == '\0') {

X fprintf(stderr, "mapname: conversion of %s failed\n", filename);


X return 3;
X }
X

X if ((error = checkdir(pathcomp, APPEND_NAME)) == 1) {
X /* GRR: OK if truncated here: warn and continue */
X /* (warn in checkdir?) */
X }
X checkdir(filename, GETPATH);
X


X return error;
X
X} /* end function mapname() */
X
X

Xstatic int ispattern(char *p)
X{
X register char c;
X while (c = *p++)
X if (c == '\\') {
X if (!*++p)
X return FALSE;
X } else if (c == '?' || c == '*')
X return TRUE;
X else if (c == '[') {
X for (;;) {
X if (!(c = *p++))
X return FALSE;
X else if (c == '\\') {
X if (!*++p)
X return FALSE;
X } else if (c == ']')
X return TRUE;
X }
X }
X return FALSE;
X}
X
X/**********************/
X/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
X/**********************/


X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{

X static DIR *dir = NULL;


X static char *dirname, *wildname, matchname[FILNAMSIZ];

X static int firstcall=TRUE, have_dirname, dirnamelen;

X struct dirent *file;
X BPTR lok = 0;


X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;

X /* avoid needless readdir() scans: */
X if (!ispattern(wildspec) || (lok = Lock(wildspec, ACCESS_READ))) {
X if (lok) UnLock(lok);
X have_dirname = FALSE;


X strcpy(matchname, wildspec);
X return matchname;
X }
X

X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, '/')) == NULL
X && (wildname = strrchr(wildspec, ':')) == NULL) {
X dirname = ""; /* current dir */


X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {
X ++wildname; /* point at character after '/' or ':' */
X dirnamelen = wildname - wildspec;

X if ((dirname = (char *)malloc(dirnamelen+1)) == NULL) {
X fprintf(stderr, "warning: can't allocate wildcard buffers\n");


X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }

X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = 0;


X have_dirname = TRUE;
X }
X

X if ((dir = opendir(dirname)) != NULL) {
X while ((file = readdir(dir)) != NULL) {

X if (match(file->d_name, wildname, 1)) { /* case insensitive */
X if (have_dirname) {


X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);

X dir = NULL;
X }


X
X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */

X if (dir == NULL) {


X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X }
X
X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */

X while ((file = readdir(dir)) != NULL)
X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */


X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */

X dir = NULL;


X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X
X} /* end function do_wild() */
X

X
X
X/***********************/
X/* Function checkdir() */
X/***********************/
X
Xint checkdir(pathcomp, flag)
X char *pathcomp;
X int flag;
X/*

X * returns: 1 - (on APPEND_xxx) truncated path component


X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be

X * 10 - can't allocate memory for filename buffers
X */
X{
X static int rootlen = 0; /* length of rootpath */
X static char *rootpath; /* user's "extract-to" directory */
X static char *buildpath; /* full path (so far) to extracted file */
X static char *end; /* pointer to end of buildpath ('\0') */

X
X# define FN_MASK 7
X# define FUNCTION (flag & FN_MASK)
X
X
X
X/*---------------------------------------------------------------------------
X APPEND_DIR: append the path component to the path being built and check
X for its existence. If doesn't exist and we are creating directories, do
X so for this one; else signal success or error as appropriate.
X ---------------------------------------------------------------------------*/
X

X/* GRR: check path length after each segment: warn about truncation */


X
X if (FUNCTION == APPEND_DIR) {

X Trace((stderr, "appending dir segment [%s]\n", pathcomp));

X while ((*end = *pathcomp++))
X ++end;


X if (stat(buildpath, &statbuf)) { /* path doesn't exist */

X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpath);
X return 2; /* path doesn't exist: nothing to do */
X }

X if (MKDIR(buildpath, 0777) == -1) { /* create the directory */

X fprintf(stderr,
X "checkdir: can't create %s\n unable to process %s.\n"
X , buildpath, filename);


X fflush(stderr);
X free(buildpath);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {

X fprintf(stderr, "checkdir: %s exists but is not a directory\n\
X unable to process %s.\n", buildpath, filename);


X fflush(stderr);
X free(buildpath);
X return 3; /* path existed but wasn't dir */
X }

X *end++ = '/';
X *end = '\0';
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0;
X
X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------
X GETPATH: copy full path to the string pointed at by pathcomp, and free
X buildpath.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {

X strcpy(pathcomp, buildpath); /* DO ERROR CHECKING: TOO LONG? */


X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
X free(buildpath);

X buildpath = end = NULL;


X return 0;
X }
X
X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X

X if (FUNCTION == APPEND_NAME) { /* DO ERROR CHECKING */


X Trace((stderr, "appending filename [%s]\n", pathcomp));

X while ((*end = *pathcomp++))
X ++end;


X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0; /* could check for existence here, prompt for new name... */
X }
X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == INIT) {
X Trace((stderr, "initializing buildpath to "));

X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+1)) == NULL)
X return 10;
X if ((rootlen > 0) && !renamed_fullpath) {


X strcpy(buildpath, rootpath);
X end = buildpath + rootlen;
X } else {
X *buildpath = '\0';
X end = buildpath;
X }
X Trace((stderr, "[%s]\n", buildpath));
X return 0;
X }
X
X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line.

X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));

X if (pathcomp == NULL) {


X rootlen = 0;
X return 0;
X }
X if ((rootlen = strlen(pathcomp)) > 0) {

X int had_trailing_pathsep=FALSE;
X


X if (pathcomp[rootlen-1] == '/') {
X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }

X if (rootlen > 0 && (stat(pathcomp, &statbuf) ||
X !S_ISDIR(statbuf.st_mode))) /* path does not exist */
X {


X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR

X || !had_trailing_pathsep


X#endif
X ) {
X rootlen = 0;
X return 2; /* treat as stored file */
X }

X /* create the directory (could add loop here to scan pathcomp
X * and create more than one level, but why really necessary?) */


X if (MKDIR(pathcomp, 0777) == -1) {

X fprintf(stderr,
X "checkdir: can't create extraction directory: %s\n",
X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, and */
X return 3; /* failed: file exists, or 2+ levels required */
X }
X }
X if ((rootpath = (char *)malloc(rootlen+2)) == NULL) {


X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);

X if (rootpath[rootlen - 1] != ':')


X rootpath[rootlen++] = '/';
X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));
X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X
X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);
X return 0;
X }
X
X return 99; /* should never reach */
X
X} /* end function checkdir() */
X
X

X/**********************/
X/* Function cmptime() */
X/**********************/
X
X/* cmptime() clone pinched from from Zip1.9h,
X * by Mark Adler, Jean-loup Gailly, et al., circa 1991.
X * Incorporated into UnZip 5.1d by John Bush
X */
X
Xint cmptime(p, q)
Xstruct tm *p, *q; /* times to compare */
X/* Return negative if time p is before time q, positive if after, and
X zero if the same */
X{
X int r; /* temporary variable */
X
X if (p == NULL)
X return -1;
X else if ((r = p->tm_year - q->tm_year) != 0)
X return r;
X else if ((r = p->tm_mon - q->tm_mon) != 0)
X return r;
X else if ((r = p->tm_mday - q->tm_mday) != 0)
X return r;
X else if ((r = p->tm_hour - q->tm_hour) != 0)
X return r;
X else if ((r = p->tm_min - q->tm_min) != 0)
X return r;
X else
X return p->tm_sec - q->tm_sec;
X}
X
X
X/***********************/
X/* Function invlocal() */
X/***********************/
X
X/* mktime() clone pinched from from Zip1.9h,
X * by Mark Adler and Jean-loup Gailly, et.al, circa 1991.
X * Incorporated into UnZip 5.1d by John Bush
X */
Xtime_t invlocal(t)
Xstruct tm *t; /* time to convert */
X/* Find inverse of localtime() using bisection. This routine assumes that
X time_t is an integer type, either signed or unsigned. The expectation
X is that sometime before the year 2038, time_t will be made a 64-bit
X integer, and this routine will still work. */
X{
X time_t i; /* midpoint of current root range */
X time_t l; /* lower end of root range */
X time_t u; /* upper end of root range */
X
X /* Bracket the root [0,largest time_t]. Note: if time_t is a 32-bit signed
X integer, then the upper bound is GMT 1/19/2038 03:14:07, after which all
X the Unix systems in the world come to a grinding halt. Either that, or
X all those systems will suddenly find themselves transported to December
X of 1901 ... */
X l = 0;
X u = 1;
X while (u < (u << 1))
X u = (u << 1) + 1;
X
X /* Find the root */
X while (u - l > 1)
X {
X i = l + ((u - l) >> 1);
X if (cmptime(localtime(&i), t) <= 0)
X l = i;
X else
X u = i;
X }
X return l;


X}
X
X
X
X/**************************************/

X/* Function close_outfile() */
X/**************************************/
X/* this part differs slightly with Zip */
X/*-------------------------------------*/
X
Xvoid close_outfile(void)
X{
X struct tm t; /* good ole time structure */
X time_t u[2]; /* mean ole time stamp */
X ulg dd,dt; /* DOS format time stamps */
X LONG FileDate();
X time_t invlocal();
X
X if (cflag) /* can't set time on stdout */
X return;
X
X /* close the file *before* setting its time under AmigaDos */
X
X fclose(outfile);
X
X /* assign date and time to local variables */
X
X dd = lrec.last_mod_file_date;
X dt = lrec.last_mod_file_time;
X
X /* Convert DOS time to time_t format in (time_t)u */
X
X t.tm_sec = (int) (dt << 1) & 0x3e;
X t.tm_min = (int) (dt >> 5) & 0x3f;
X t.tm_hour = (int) (dt >> 11) & 0x1f;
X
X t.tm_mday = (int) (dd & 0x1f);
X t.tm_mon = ((int) (dd >> 5) & 0xf ) - 1;
X t.tm_year = ((int) (dd >> 9) & 0x7f) + 80;
X
X /* invlocal() is equivalent to mktime() */
X
X u[0] = u[1] = invlocal(&t);
X
X#ifdef DEBUG
X fprintf (stderr,"\nclose_outfile(): u=%s\n",ctime(&u[0]));
X#endif
X
X if (!FileDate(filename, u))
X fprintf(stderr, "warning: can't set the time for %s\n", filename);
X
X /* set file perms after closing (not done at creation)--see mapattr() */
X
X chmod(filename, pInfo->file_attr);


X
X} /* end function close_outfile() */
X
X

X/********************************************************************/
X/* Load filedate as a separate external file; it's used by Zip, too.*/
X/* */
X#include "amiga/filedate.c" /* */
X/* */
X/********************************************************************/
X
X/**************** for Aztec, do linewise with stat.c ****************/
X
X#ifdef AZTEC_C
X# include "amiga/stat.c"
X/* this is the exact same stat.c used for Aztec by Zip */
X
X# include <stdio.h>
X# include "crypt.h"
X
Xvoid _abort(void) /* called when ^C is pressed */
X{
X echon();
X close_leftover_open_dirs();
X fflush(stdout);
X fputs("\n^C\n", stderr);
X exit(1);
X}
X#endif /* AZTEC_C */


X
X
X#ifndef SFX
X
X/************************/

X/* Function version() */
X/************************/
X
X
X/* NOTE: the following include depends upon the environment
X * variable $Workbench to be set correctly. (Set by
X * default, by kickstart during startup)
X */
Xint WBversion = (int)
X#include "ENV:Workbench"
X;
X
Xvoid version()
X{
X extern char Far CompiledWith[];
X
X/* Define buffers. */
X
X char buf1[16]; /* compiler name */
X char buf2[16]; /* revstamp */
X char buf3[16]; /* OS */
X char buf4[16]; /* Date */
X/* char buf5[16]; /* Time */
X
X/* format "with" name strings */
X
X#ifdef AMIGA
X# ifdef __SASC
X strcpy(buf1,"SAS/C ");
X# else
X# ifdef LATTICE
X strcpy(buf1,"Lattice C ");
X# else
X# ifdef AZTEC_C
X strcpy(buf1,"Manx Aztec C ");
X# else
X strcpy(buf1,"UNKNOWN ");


X# endif
X# endif
X# endif

X/* "under" */
X sprintf(buf3,"AmigaDOS v%d",WBversion);
X#else
X strcpy(buf1,"Unknown compiler ");
X strcpy(buf3,"Unknown OS");
X#endif
X
X/* Define revision, date, and time strings.
X * NOTE: Do not calculate run time, be sure to use time compiled.
X * Pass these strings via your makefile if undefined.
X */
X
X#if defined(__VERSION__) && defined(__REVISION__)
X sprintf(buf2,"version %d.%d",__VERSION__,__REVISION__);
X#else
X# ifdef __VERSION__
X sprintf(buf2,"version %d",__VERSION__);
X# else
X sprintf(buf2,"unknown version");


X# endif
X#endif
X
X#ifdef __DATE__

X sprintf(buf4," on %s",__DATE__);
X#else
X strcpy(buf4," unknown date");
X#endif
X
X/******
X#ifdef __TIME__
X sprintf(buf5," at %s",__TIME__);
X#else
X strcpy(buf5," unknown time");
X#endif
X******/
X
X/* Print strings using "CompiledWith" mask defined in unzip.c (used by all).
X * ("Compiled with %s%s under %s%s%s%s.")
X */
X
X printf(LoadFarString(CompiledWith),
X buf1,
X buf2,
X buf3,
X buf4,
X /* buf5, */ "",
X "" ); /* buf6 not used */
X


X} /* end function version() */
X
X#endif /* !SFX */

END_OF_FILE
if test 25728 -ne `wc -c <'unzip-5.12/amiga/amiga.c'`; then
echo shar: \"'unzip-5.12/amiga/amiga.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/amiga.c'
fi
if test -f 'unzip-5.12/nt/nt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/nt/nt.c'\"
else
echo shar: Extracting \"'unzip-5.12/nt/nt.c'\" \(40790 characters\)
sed "s/^X//" >'unzip-5.12/nt/nt.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X nt.c Last updated: 15 Aug 94
X
X WinNT-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X (Borrowed, pilfered and plundered code from OS/2 and MS-DOS versions and
X from ZIP; modified as necessary.)
X
X Contains: GetLoadPath()
X opendir()
X readdir()
X closedir()
X mapattr()
X getNTfiletime()
X close_outfile()
X isfloppy()
X IsVolumeOldFAT()
X IsFileNameValid()
X map2fat()
X checkdir()
X do_wild()
X mapname()
X version()
X
X ---------------------------------------------------------------------------*/
X
X#include <windows.h>
X#include "unzip.h"
X
X
X#define MKDIR(path,mode) mkdir(path)
X
Xstruct direct
X{
X char reserved [21];
X char ff_attrib;
X short ff_ftime;
X short ff_fdate;
X long size;
X char d_name[MAX_PATH];
X int d_first;
X HANDLE d_hFindFile;
X};
X


X
Xstatic int created_dir; /* used by mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */

Xstatic int fnlen; /* ditto */
Xstatic unsigned nLabelDrive; /* ditto */


X
X
X
X#ifdef SFX
X

X/**************************/
X/* Function GetLoadPath() */
X/**************************/
X
Xchar *GetLoadPath(void)
X{
X#ifdef MSC
X extern char *_pgmptr;
X return _pgmptr;
X
X#else /* use generic API call */
X GetModuleFileName(NULL, filename, FILNAMSIZ);
X return filename;
X#endif
X
X} /* end function GetLoadPath() */


X
X
X
X
X

X#else /* !SFX */
X

X/**********************/ /* Borrowed from ZIP 2.0 sources */
X/* Function opendir() */ /* Difference: no special handling for */
X/**********************/ /* hidden or system files. */
X
Xstatic struct direct *opendir(n)
X const char *n; /* directory to open */
X{
X struct direct *d; /* malloc'd return value */
X char *p; /* malloc'd temporary string */
X WIN32_FIND_DATA fd;
X int len = strlen(n);
X
X /* Start searching for files in the MSDOS directory n */
X
X if ((d = (struct direct *)malloc(sizeof(struct direct))) == NULL ||
X (p = malloc(strlen(n) + 5)) == NULL)
X {
X if (d != (struct direct *)NULL)
X free((void *)d);


X return (struct direct *)NULL;
X }

X strcpy(p, n);
X if (p[len-1] == ':')
X p[len++] = '.'; /* x: => x:. */
X else if (p[len-1] == '/' || p[len-1] == '\\')
X --len; /* foo/ => foo */
X strcpy(p+len, "/*");
X
X if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd))) {
X free((voidp *)d);
X free((voidp *)p);
X return NULL;
X }
X strcpy(d->d_name, fd.cFileName);
X
X free((voidp *)p);
X d->d_first = 1;
X return d;
X
X} /* end of function opendir() */
X
X
X
X
X/**********************/ /* Borrowed from ZIP 2.0 sources */
X/* Function readdir() */ /* Difference: no special handling for */
X/**********************/ /* hidden or system files. */
X
Xstatic struct direct *readdir(d)
X struct direct *d; /* directory stream from which to read */


X{
X /* Return pointer to first or next directory entry, or NULL if end. */
X
X if ( d->d_first )
X d->d_first = 0;
X else

X {
X WIN32_FIND_DATA fd;
X
X if ( !FindNextFile(d->d_hFindFile, &fd) )
X return NULL;
X
X strcpy(d->d_name, fd.cFileName);
X }


X return (struct direct *)d;
X

X} /* end of function readdir() */
X
X
X
X
X/***********************/
X/* Function closedir() */ /* Borrowed from ZIP 2.0 sources */
X/***********************/
X
Xstatic void closedir(d)
X struct direct *d; /* directory stream to close */
X{
X FindClose(d->d_hFindFile);
X free(d);
X}
X
X#endif /* ?SFX */
X
X
X
X


X/**********************/
X/* Function mapattr() */
X/**********************/
X

X/* Identical to MS-DOS, OS/2 versions. */
X/* However, NT has a lot of extra permission stuff, so this function should */
X/* probably be extended in the future. */


X
Xint mapattr()
X{
X /* set archive bit (file is not backed up): */
X pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;
X return 0;
X

X} /* end function mapattr() */
X
X
X
X
X/****************************/ /* Get the file time in a format that */
X/* Function getNTfiletime() */ /* can be used by SetFileTime() in NT */
X/****************************/
X
Xint getNTfiletime(FILETIME *ft)
X{
X FILETIME lft; /* 64-bit value made up of two 32 bit [low & high] */
X WORD wDOSDate; /* for converting from DOS date to Windows NT */
X WORD wDOSTime;
X
X /* Copy and/or convert time and date variables, if necessary; */
X /* then set the file time/date. */
X wDOSTime = (WORD)lrec.last_mod_file_time;
X wDOSDate = (WORD)lrec.last_mod_file_date;
X
X /* The DosDateTimeToFileTime() function converts a DOS date/time */
X /* into a 64 bit Windows NT file time */
X if (!DosDateTimeToFileTime(wDOSDate, wDOSTime, &lft))
X {
X PRINTF("DosDateTime failed: %d\n", GetLastError());
X return FALSE;
X }
X if (!LocalFileTimeToFileTime( &lft, ft))
X {
X PRINTF("LocalFileTime failed: %d\n", GetLastError());
X *ft = lft;
X }
X return TRUE;


X}
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()

X{
X FILETIME ft; /* File time type defined in NT */
X HANDLE hFile; /* File handle defined in NT */
X int gotTime;
X
X /* don't set the time stamp on standard output */
X if (cflag) {
X fclose(outfile);
X return;
X }
X
X gotTime = getNTfiletime(&ft);
X
X /* Close the file and then re-open it using the Win32
X * CreateFile call, so that the file can be created
X * with GENERIC_WRITE access, otherwise the SetFileTime
X * call will fail. */
X fclose(outfile);
X
X hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
X FILE_ATTRIBUTE_NORMAL, NULL);
X if ( hFile == INVALID_HANDLE_VALUE ) {
X FPRINTF(stderr, "\nCreateFile error %d when trying set file time\n",
X GetLastError());
X }
X else {
X if (gotTime)
X if (!SetFileTime(hFile, NULL, NULL, &ft))
X PRINTF("\nSetFileTime failed: %d\n", GetLastError());
X CloseHandle(hFile);
X }
X
X /* HG: I think this could be done in the CreateFile call above - just */
X /* replace 'FILE_ATTRIBUTE_NORMAL' with 'pInfo->file_attr & 0x7F' */
X if (!SetFileAttributes(filename, pInfo->file_attr & 0x7F))
X FPRINTF(stderr, "\nwarning (%d): could not set file attributes\n",
X GetLastError());
X
X return;


X
X} /* end function close_outfile() */
X
X
X

X/* ============================================================================
X*/
X
X
X
X/***********************/
X/* Function isfloppy() */ /* more precisely, is it removable? */
X/***********************/
X
Xstatic int isfloppy(int nDrive) /* 1 == A:, 2 == B:, etc. */
X{
X char rootPathName[4];
X
X rootPathName[0] = 'A' + nDrive - 1; /* Build the root path name, */
X rootPathName[1] = ':'; /* e.g. "A:/" */
X rootPathName[2] = '/';
X rootPathName[3] = '\0';
X
X return (GetDriveType(rootPathName) == DRIVE_REMOVABLE);
X
X} /* end function isfloppy() */
X
X
X
X
X/*****************************/
X/* Function IsVolumeOldFAT() */
X/*****************************/
X
X/*
X * Note: 8.3 limits on filenames apply only to old-style FAT filesystems.
X * More recent versions of Windows (Windows NT 3.5 / Windows 4.0)
X * can support long filenames (LFN) on FAT filesystems. Check the
X * filesystem maximum component length field to detect LFN support.
X * [GRR: this routine is only used to determine whether spaces in
X * filenames are supported...]
X */
X
Xstatic int IsVolumeOldFAT(char *name)
X{
X char *tmp0;
X char rootPathName[4];
X char tmp1[MAX_PATH], tmp2[MAX_PATH];
X unsigned volSerNo, maxCompLen, fileSysFlags;
X
X if (isalpha(name[0]) && (name[1] == ':'))
X tmp0 = name;
X else
X {
X GetFullPathName(name, MAX_PATH, tmp1, &tmp0);
X tmp0 = &tmp1[0];
X }
X strncpy(rootPathName, tmp0, 3); /* Build the root path name, */
X rootPathName[3] = '\0'; /* e.g. "A:/" */
X
X GetVolumeInformation(rootPathName, tmp1, MAX_PATH, &volSerNo,
X &maxCompLen, &fileSysFlags, tmp2, MAX_PATH);
X
X /* Long Filenames (LFNs) are available if the component length is > 12 */
X return maxCompLen <= 12;
X/* return !strncmp(strupr(tmp2), "FAT", 3); old version */


X
X}
X
X
X
X

X/******************************/
X/* Function IsFileNameValid() */
X/******************************/
X
Xstatic int IsFileNameValid(char *name)
X{
X HFILE hf;
X OFSTRUCT of;
X
X hf = OpenFile(name, &of, OF_READ | OF_SHARE_DENY_NONE);
X if (hf == HFILE_ERROR)
X switch (GetLastError())


X {
X case ERROR_INVALID_NAME:
X case ERROR_FILENAME_EXCED_RANGE:
X return FALSE;

X default:
X return TRUE;
X }

X else
X _lclose(hf);
X return TRUE;


X}
X
X
X
X

X/**********************/
X/* Function map2fat() */ /* Identical to OS/2 version */


X/**********************/
X
Xvoid map2fat(pathcomp, pEndFAT)
X char *pathcomp, **pEndFAT;
X{
X char *ppc = pathcomp; /* variable pointer to pathcomp */
X char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */
X char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */

X char *last_dot = NULL; /* last dot not converted to underscore */


X int dotname = FALSE; /* flag: path component begins with dot */

X /* ("." and ".." don't count) */

X register unsigned workch; /* hold the character being tested */
X
X

X /* Only need check those characters which are legal in HPFS but not
X * in FAT: to get here, must already have passed through mapname.
X * (GRR: oops, small bug--if char was quoted, no longer have any
X * knowledge of that.) Also must truncate path component to ensure
X * 8.3 compliance...
X */
X while ((workch = (uch)*ppc++) != 0) {

X switch (workch) {
X case '[':
X case ']':
X *pEnd++ = '_'; /* convert brackets to underscores */
X break;
X


X case '.':
X if (pEnd == *pEndFAT) { /* nothing appended yet... */
X if (*ppc == '\0') /* don't bother appending a */
X break; /* "./" component to the path */

X else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */
X *pEnd++ = '.'; /* add first dot, unchanged... */
X ++ppc; /* skip second dot, since it will */


X } else { /* be "added" at end of if-block */

X *pEnd++ = '_'; /* FAT doesn't allow null filename */


X dotname = TRUE; /* bodies, so map .exrc -> _.exrc */
X } /* (extra '_' now, "dot" below) */
X } else if (dotname) { /* found a second dot, but still */
X dotname = FALSE; /* have extra leading underscore: */

X *pEnd = '\0'; /* remove it by shifting chars */
X pEnd = *pEndFAT + 1; /* left one space (e.g., .p1.p2: */
X while (pEnd[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */
X *pEnd = pEnd[1]; /* finished) [opt.: since first */
X ++pEnd; /* two chars are same, can start */


X } /* shifting at second position] */
X }

X last_dot = pEnd; /* point at last dot so far... */
X *pEnd++ = '_'; /* convert dot to underscore for now */
X break;
X


X default:
X *pEnd++ = (char)workch;
X

X } /* end switch */
X } /* end while loop */
X

X *pEnd = '\0'; /* terminate buildpathFAT */
X
X /* NOTE: keep in mind that pEnd points to the end of the path
X * component, and *pEndFAT still points to the *beginning* of it...
X * Also note that the algorithm does not try to get too fancy:
X * if there are no dots already, the name either gets truncated
X * at 8 characters or the last underscore is converted to a dot
X * (only if more characters are saved that way). In no case is
X * a dot inserted between existing characters.
X */

X if (last_dot == NULL) { /* no dots: check for underscores... */


X char *plu = strrchr(pBegin, '_'); /* pointer to last underscore */
X

X if (plu == NULL) { /* no dots, no underscores: truncate at 8 chars */
X *pEndFAT += 8; /* (or could insert '.' and keep 11...?) */


X if (*pEndFAT > pEnd)
X *pEndFAT = pEnd; /* oops...didn't have 8 chars to truncate */
X else
X **pEndFAT = '\0';
X } else if (MIN(plu - pBegin, 8) + MIN(pEnd - plu - 1, 3) > 8) {
X last_dot = plu; /* be lazy: drop through to next if-blk */
X } else if ((pEnd - *pEndFAT) > 8) {
X *pEndFAT += 8; /* more fits into just basename than if */
X **pEndFAT = '\0'; /* convert last underscore to dot */
X } else

X *pEndFAT = pEnd; /* whole thing fits into 8 chars or less */
X }
X
X if (last_dot != NULL) { /* one dot (or two, in the case of */
X *last_dot = '.'; /* "..") is OK: put it back in */
X


X if ((last_dot - pBegin) > 8) {
X char *p=last_dot, *q=pBegin+8;
X int i;

X


X for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */
X *q++ = *p++; /* shift .ext left and trun- */
X *q = '\0'; /* cate/terminate it */
X *pEndFAT = q;
X } else if ((pEnd - last_dot) > 4) { /* too many chars in extension */
X *pEndFAT = last_dot + 4;

X **pEndFAT = '\0';
X } else
X *pEndFAT = pEnd; /* filename is fine; point at terminating zero */
X }
X} /* end function map2fat() */
X
X
X
X
X/***********************/ /* Borrowed from os2.c for UnZip 5.1. */
X/* Function checkdir() */ /* Difference: no EA stuff */
X/***********************/ /* HPFS stuff works on NTFS too */


X
Xint checkdir(pathcomp, flag)
X char *pathcomp;
X int flag;
X/*
X * returns: 1 - (on APPEND_NAME) truncated filename
X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be
X * 4 - path is too long
X * 10 - can't allocate memory for filename buffers
X */
X{
X static int rootlen = 0; /* length of rootpath */
X static char *rootpath; /* user's "extract-to" directory */

X static char *buildpathHPFS; /* full path (so far) to extracted file, */
X static char *buildpathFAT; /* both HPFS/EA (main) and FAT versions */
X static char *endHPFS; /* corresponding pointers to end of */

X static char *endFAT; /* buildpath ('\0') */


X
X# define FN_MASK 7
X# define FUNCTION (flag & FN_MASK)
X
X
X
X/*---------------------------------------------------------------------------
X APPEND_DIR: append the path component to the path being built and check
X for its existence. If doesn't exist and we are creating directories, do
X so for this one; else signal success or error as appropriate.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_DIR) {

X char *p = pathcomp;

X int too_long=FALSE;


X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));

X while ((*endHPFS = *p++) != '\0') /* copy to HPFS filename */
X ++endHPFS;
X if (IsFileNameValid(buildpathHPFS)) {

X p = pathcomp;
X while ((*endFAT = *p++) != '\0') /* copy to FAT filename, too */
X ++endFAT;
X } else {

X/* GRR: check error return? */
X map2fat(pathcomp, &endFAT); /* map, put in FAT fn, update endFAT */
X }

X
X /* GRR: could do better check, see if overrunning buffer as we go:

X * check endHPFS-buildpathHPFS after each append, set warning variable
X * if within 20 of FILNAMSIZ; then if var set, do careful check when


X * appending. Clear variable when begin new path. */
X

X /* next check: need to append '/', at least one-char name, '\0' */
X if ((endHPFS-buildpathHPFS) > FILNAMSIZ-3)
X too_long = TRUE; /* check if extracting dir? */
X if (stat(buildpathFAT, &statbuf)) /* path doesn't exist */


X {
X if (!create_dirs) { /* told not to create (freshening) */

X free(buildpathHPFS);
X free(buildpathFAT);


X return 2; /* path doesn't exist: nothing to do */
X }

X if (too_long) { /* GRR: should allow FAT extraction w/o EAs */
X FPRINTF(stderr, "checkdir error: path too long: %s\n",
X buildpathHPFS);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);

X return 4; /* no room for filenames: fatal */
X }

X if (MKDIR(buildpathFAT, 0777) == -1) { /* create the directory */
X FPRINTF(stderr, "checkdir error: can't create %s\n\
X unable to process %s.\n", buildpathFAT, filename);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);

X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {

X FPRINTF(stderr, "checkdir error: %s exists but is not directory\n\


X unable to process %s.\n", buildpathFAT, filename);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);

X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {

X FPRINTF(stderr, "checkdir error: path too long: %s\n",
X buildpathHPFS);
X fflush(stderr);
X free(buildpathHPFS);
X free(buildpathFAT);

X return 4; /* no room for filenames: fatal */
X }

X *endHPFS++ = '/';
X *endFAT++ = '/';
X *endHPFS = *endFAT = '\0';

X Trace((stderr, "buildpathHPFS now = [%s]\n", buildpathHPFS));
X Trace((stderr, "buildpathFAT now = [%s]\n", buildpathFAT));


X return 0;
X
X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------

X GETPATH: copy full FAT path to the string pointed at by pathcomp (want
X filename to reflect name used on disk, not EAs; if full path is HPFS,
X buildpathFAT and buildpathHPFS will be identical). Also free both paths.

X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {

X Trace((stderr, "getting and freeing FAT path [%s]\n", buildpathFAT));
X Trace((stderr, "freeing HPFS path [%s]\n", buildpathHPFS));
X strcpy(pathcomp, buildpathFAT);
X free(buildpathFAT);
X free(buildpathHPFS);

X buildpathHPFS = buildpathFAT = endHPFS = endFAT = NULL;


X return 0;
X }
X
X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {

X char *p = pathcomp;


X int error = 0;
X

X Trace((stderr, "appending filename [%s]\n", pathcomp));

X while ((*endHPFS = *p++) != '\0') { /* copy to HPFS filename */
X ++endHPFS;
X if ((endHPFS-buildpathHPFS) >= FILNAMSIZ) {
X *--endHPFS = '\0';
X FPRINTF(stderr, "checkdir warning: path too long; truncating\n\
X %s\n -> %s\n", filename, buildpathHPFS);
X fflush(stderr);

X error = 1; /* filename truncated */
X }
X }
X
X if ( pInfo->vollabel || IsFileNameValid(buildpathHPFS)) {


X p = pathcomp;
X while ((*endFAT = *p++) != '\0') /* copy to FAT filename, too */

X ++endFAT;
X } else {


X map2fat(pathcomp, &endFAT); /* map, put in FAT fn, update endFAT */
X }
X Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n",
X buildpathHPFS, buildpathFAT));
X

X return error; /* could check for existence, prompt for new name... */
X
X } /* end if (FUNCTION == APPEND_NAME) */


X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == INIT) {
X

X/* HG: variable not used here */
X/* char *p; */
X


X Trace((stderr, "initializing buildpathHPFS and buildpathFAT to "));

X if ((buildpathHPFS = (char *)malloc(fnlen+rootlen+1)) == NULL)
X return 10;
X if ((buildpathFAT = (char *)malloc(fnlen+rootlen+1)) == NULL) {
X free(buildpathHPFS);
X return 10;
X }


X if (pInfo->vollabel) { /* use root or renamed path, but don't store */

X/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
X if (renamed_fullpath && pathcomp[1] == ':')

X *buildpathHPFS = ToLower(*pathcomp);


X else if (!renamed_fullpath && rootpath && rootpath[1] == ':')

X *buildpathHPFS = ToLower(*rootpath);
X else {
X char tmpN[MAX_PATH], *tmpP;
X if (GetFullPathName(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH)
X { /* by definition of MAX_PATH we should never get here */
X FPRINTF(stderr,
X "checkdir warning: current dir path too long\n");
X return 1; /* can't get drive letter */
X }
X nLabelDrive = *tmpN - 'a' + 1;
X *buildpathHPFS = (char)(nLabelDrive - 1 + 'a');
X }


X nLabelDrive = *buildpathHPFS - 'a' + 1; /* save for mapname() */

X if (volflag == 0 || *buildpathHPFS < 'a' || /* no labels/bogus? */


X (volflag == 1 && !isfloppy(nLabelDrive))) { /* -$: no fixed */

X free(buildpathHPFS);
X free(buildpathFAT);


X return IZ_VOL_LABEL; /* skipping with message */
X }

X *buildpathHPFS = '\0';


X } else if (renamed_fullpath) /* pathcomp = valid data */

X strcpy(buildpathHPFS, pathcomp);


X else if (rootlen > 0)

X strcpy(buildpathHPFS, rootpath);
X else
X *buildpathHPFS = '\0';
X endHPFS = buildpathHPFS;
X endFAT = buildpathFAT;
X while ((*endFAT = *endHPFS) != '\0') {
X ++endFAT;
X ++endHPFS;

X }
X Trace((stderr, "[%s]\n", buildpathHPFS));


X return 0;
X }
X
X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line. Note that under OS/2 and MS-DOS, if a candidate extract-to
X directory specification includes a drive letter (leading "x:"), it is
X treated just as if it had a trailing '/'--that is, one directory level
X will be created if the path doesn't exist, unless this is otherwise pro-
X hibited (e.g., freshening).
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));

X if (pathcomp == NULL) {


X rootlen = 0;
X return 0;
X }
X if ((rootlen = strlen(pathcomp)) > 0) {
X int had_trailing_pathsep=FALSE, has_drive=FALSE, xtra=2;
X
X if (isalpha(pathcomp[0]) && pathcomp[1] == ':')
X has_drive = TRUE; /* drive designator */
X if (pathcomp[rootlen-1] == '/') {
X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (has_drive && (rootlen == 2)) {
X if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */
X xtra = 3; /* room for '.' + '/' + 0 at end of "x:" */
X } else if (rootlen > 0) { /* need not check "x:." and "x:/" */

X if (SSTAT(pathcomp, &statbuf) || !S_ISDIR(statbuf.st_mode)) {


X /* path does not exist */
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || (!has_drive && !had_trailing_pathsep)
X#endif
X ) {
X rootlen = 0;
X return 2; /* treat as stored file */
X }

X /* create directory (could add loop here to scan pathcomp
X * and create more than one level, but really necessary?) */
X if (MKDIR(pathcomp, 0777) == -1) {
X FPRINTF(stderr,

X "checkdir: can't create extraction directory: %s\n",


X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, */

X return 3; /* failed: file exists, or need 2+ levels */
X }
X }
X }
X if ((rootpath = (char *)malloc(rootlen+xtra)) == NULL) {

X} /* end function checkdir() */
X
X
X
X


X#ifndef SFX
X
X/************************/
X/* Function do_wild() */ /* identical to OS/2 version */
X/************************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{

X static struct direct *dir = NULL;


X static char *dirname, *wildname, matchname[FILNAMSIZ];

X static int firstcall=TRUE, have_dirname, dirnamelen;
X struct direct *file;
X
X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, '/')) == NULL &&
X (wildname = strrchr(wildspec, ':')) == NULL) {


X dirname = ".";
X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {
X ++wildname; /* point at character after '/' or ':' */
X dirnamelen = wildname - wildspec;

X if ((dirname = (char *)malloc(dirnamelen+1)) == NULL) {
X FPRINTF(stderr, "warning: can't allocate wildcard buffers\n");


X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }

X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
X have_dirname = TRUE;
X }
X Trace((stderr, "do_wild: dirname = [%s]\n", dirname));
X

X if ((dir = opendir(dirname)) != NULL) {
X while ((file = readdir(dir)) != NULL) {

X Trace((stderr, "do_wild: readdir returns %s\n", file->d_name));
X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X Trace((stderr, "do_wild: match() succeeds\n"));
X if (have_dirname) {
X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);

X dir = NULL;


X }
X Trace((stderr, "do_wild: opendir(%s) returns NULL\n", dirname));
X
X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */

X if (dir == NULL) {


X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X }
X
X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */

X while ((file = readdir(dir)) != NULL)


X if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */

X dir = NULL;


X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X
X} /* end function do_wild() */
X

X#endif /* !SFX */
X
X
X
X


X/************************/
X/* Function mapname() */
X/************************/
X

X/*
X * There are presently two possibilities in OS/2: the output filesystem is
X * FAT, or it is HPFS. If the former, we need to map to FAT, obviously, but
X * we *also* must map to HPFS and store that version of the name in extended
X * attributes. Either way, we need to map to HPFS, so the main mapname
X * routine does that. In the case that the output file system is FAT, an
X * extra filename-mapping routine is called in checkdir(). While it should
X * be possible to determine the filesystem immediately upon entry to mapname(),
X * it is conceivable that the DOS APPEND utility could be added to OS/2 some-
X * day, allowing a FAT directory to be APPENDed to an HPFS drive/path. There-
X * fore we simply check the filesystem at each path component.
X *
X * Note that when alternative IFS's become available/popular, everything will
X * become immensely more complicated. For example, a Minix filesystem would
X * have limited filename lengths like FAT but no extended attributes in which
X * to store the longer versions of the names. A BSD Unix filesystem would
X * support paths of length 1024 bytes or more, but it is not clear that FAT
X * EAs would allow such long .LONGNAME fields or that OS/2 would properly
X * restore such fields when moving files from FAT to the new filesystem.
X *
X * GRR: some or all of the following chars should be checked in either
X * mapname (HPFS) or map2fat (FAT), depending: ,=^+'"[]<>|\t&
X */

X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */

X{ /* 3 if error (skip file), 10 if no memory (skip file), */

X /* IZ_VOL_LABEL if can't do vol label, IZ_CREATED_DIR */


X char pathcomp[FILNAMSIZ]; /* path-component buffer */

X char *pp, *cp=NULL; /* character pointers */
X char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */


X int quote = FALSE; /* flag: next char is literal */

X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X
X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X
X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X renamed_fullpath = FALSE;

X fnlen = strlen(filename);
X

X return error; /* ...unless no mem or vol label on hard disk */
X


X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */
X if (!renamed) { /* cp already set if renamed */
X if (jflag) /* junking directories */
X cp = (char *)strrchr(filename, '/');

X if (cp == NULL) /* no '/' or not junking dirs */


X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X }
X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X
X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';

X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = NULL; /* leave directory semi-colons alone */


X break;
X
X case ':':

X *pp++ = '_'; /* drive names not stored in zipfile, */
X break; /* so no colons allowed */


X
X case ';': /* start of VMS version? */

X lastsemi = pp; /* remove VMS version later... */

X *pp++ = ';'; /* but keep semicolon for now */
X break;
X


X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X

X case ' ': /* keep spaces unless specifically */

X /* NT cannot create filenames with spaces on FAT volumes */
X if (sflag || IsVolumeOldFAT(filename))


X *pp++ = '_';
X else

X *pp++ = ' ';


X break;
X
X default:
X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X
X /* if not saving them, remove VMS version numbers (appended "###") */
X if (!V_flag && lastsemi) {

X pp = lastsemi + 1; /* semi-colon was kept: expect #'s after */


X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp == '\0') /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X }
X

X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.
X ---------------------------------------------------------------------------*/
X

X if (filename[fnlen-1] == '/') {


X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {

X/* GRR: trailing '/'? need to strip or not? */
X FPRINTF(stdout, " creating: %-22s\n", filename);

X /* HG: are we setting the date&time on a newly created dir? */
X /* Not quite sure how to do this. It does not seem to */
X /* be done in the MS-DOS version of mapname(). */
X return IZ_CREATED_DIR; /* dir time already set */


X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X
X if (*pathcomp == '\0') {

X FPRINTF(stderr, "mapname: conversion of %s failed\n", filename);


X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);

X Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",
X filename, error));

X
X if (pInfo->vollabel) { /* set the volume label now */

X char drive[3];
X
X /* Build a drive string, e.g. "b:" */
X drive[0] = 'a' + nLabelDrive - 1;
X drive[1] = ':';
X drive[2] = '\0';
X if (QCOND2)
X FPRINTF(stdout, "labelling %s %-22s\n", drive, filename);
X if (!SetVolumeLabel(drive, filename)) {
X FPRINTF(stderr, "mapname: error setting volume label\n");
X return 3;
X }
X return 2; /* success: skip the "extraction" quietly */
X }


X
X return error;
X

X} /* end function mapname() */


X
X
X
X
X

X#ifndef SFX
X
X/************************/


X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if defined(_MSC_VER)


X char buf[80];
X#endif
X
X PRINTF(LoadFarString(CompiledWith),
X

X#ifdef _MSC_VER /* MSC == VC++, but what about SDK compiler? */
X (sprintf(buf, "Microsoft C %d.%02d ", _MSC_VER/100, _MSC_VER%100), buf),
X# if (_MSC_VER >= 800)
X "(Visual C++)",
X# else
X "(bad version)",
X# endif
X#else
X "unknown compiler (SDK?)", "",
X#endif
X
X "Windows NT", " (32-bit)",


X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X

X return;


X
X} /* end function version() */
X
X#endif /* !SFX */

END_OF_FILE
if test 40790 -ne `wc -c <'unzip-5.12/nt/nt.c'`; then
echo shar: \"'unzip-5.12/nt/nt.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/nt/nt.c'
fi
echo shar: End of archive 8 \(of 20\).
cp /dev/null ark8isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:15:32 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 74
Archive-name: unzip/part09

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/explode.c unzip-5.12/inflate.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:40 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 9 (of 20)."'
if test -f 'unzip-5.12/explode.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/explode.c'\"
else
echo shar: Extracting \"'unzip-5.12/explode.c'\" \(28523 characters\)
sed "s/^X//" >'unzip-5.12/explode.c' <<'END_OF_FILE'
X/* explode.c -- put in the public domain by Mark Adler
X version c13, 25 August 1994 */
X
X
X/* You can do whatever you like with this source file, though I would
X prefer that if you modify it and redistribute it that you include
X comments to that effect with your name and the date. Thank you.
X
X History:
X vers date who what
X ---- --------- -------------- ------------------------------------
X c1 30 Mar 92 M. Adler explode that uses huft_build from inflate
X (this gives over a 70% speed improvement
X over the original unimplode.c, which
X decoded a bit at a time)
X c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k.
X c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG
X c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy()
X c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing
X the 32K window size for specialized
X applications.
X c6 31 May 92 M. Adler added typecasts to eliminate some warnings
X c7 27 Jun 92 G. Roelofs added more typecasts.
X c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch.
X c9 19 Jul 93 J. Bush added more typecasts (to return values);
X made l[256] array static for Amiga.
X c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added
X buf and unshrink arguments to flush();
X undef'd various macros at end for Turbo C;
X removed NEXTBYTE macro (now in unzip.h)
X and bytebuf variable (not used); changed
X memset() to memzero().
X c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation.
X c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines
X to avoid bug in Encore compiler.
X c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix)


X */
X
X
X/*

X Explode imploded (PKZIP method 6 compressed) data. This compression
X method searches for as much of the current string of bytes (up to a length
X of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches
X (of at least length 2 or 3), it codes the next byte. Otherwise, it codes
X the length of the matched string and its distance backwards from the
X current position. Single bytes ("literals") are preceded by a one (a
X single bit) and are either uncoded (the eight bits go directly into the
X compressed stream for a total of nine bits) or Huffman coded with a
X supplied literal code tree. If literals are coded, then the minimum match
X length is three, otherwise it is two.
X
X There are therefore four kinds of imploded streams: 8K search with coded
X literals (min match = 3), 4K search with coded literals (min match = 3),
X 8K with uncoded literals (min match = 2), and 4K with uncoded literals
X (min match = 2). The kind of stream is identified in two bits of a
X general purpose bit flag that is outside of the compressed stream.
X
X Distance-length pairs for matched strings are preceded by a zero bit (to
X distinguish them from literals) and are always coded. The distance comes
X first and is either the low six (4K) or low seven (8K) bits of the
X distance (uncoded), followed by the high six bits of the distance coded.
X Then the length is six bits coded (0..63 + min match length), and if the
X maximum such length is coded, then it's followed by another eight bits
X (uncoded) to be added to the coded length. This gives a match length
X range of 2..320 or 3..321 bytes.
X
X The literal, length, and distance codes are all represented in a slightly
X compressed form themselves. What is sent are the lengths of the codes for
X each value, which is sufficient to construct the codes. Each byte of the
X code representation is the code length (the low four bits representing
X 1..16), and the number of values sequentially with that length (the high
X four bits also representing 1..16). There are 256 literal code values (if
X literals are coded), 64 length code values, and 64 distance code values,
X in that order at the beginning of the compressed stream. Each set of code
X values is preceded (redundantly) with a byte indicating how many bytes are
X in the code description that follows, in the range 1..256.
X
X The codes themselves are decoded using tables made by huft_build() from
X the bit lengths. That routine and its comments are in the inflate.c
X module.
X */
X
X#include "unzip.h" /* must supply slide[] (uch) array and NEXTBYTE macro */
X


X#ifndef WSIZE
X# define WSIZE 0x8000 /* window size--must be a power of two, and */

X#endif /* at least 8K for zip's implode method */
X
X
Xstruct huft {
X uch e; /* number of extra bits or operation */
X uch b; /* number of bits in this code or subcode */
X union {
X ush n; /* literal, length base, or distance base */
X struct huft *t; /* pointer to next level of table */
X } v;
X};
X
X/* Function prototypes */
X/* routines from inflate.c */
Xextern unsigned hufts;
Xint huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
X struct huft **, int *));
Xint huft_free OF((struct huft *));
X
X/* routines here */
Xint get_tree OF((unsigned *, unsigned));
Xint explode_lit8 OF((struct huft *, struct huft *, struct huft *,
X int, int, int));
Xint explode_lit4 OF((struct huft *, struct huft *, struct huft *,
X int, int, int));
Xint explode_nolit8 OF((struct huft *, struct huft *, int, int));
Xint explode_nolit4 OF((struct huft *, struct huft *, int, int));
Xint explode OF((void));
X
X
X/* The implode algorithm uses a sliding 4K or 8K byte window on the
X uncompressed stream to find repeated byte strings. This is implemented
X here as a circular buffer. The index is updated simply by incrementing
X and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K
X buffer of inflate is used, and it works just as well to always have
X a 32K circular buffer, so the index is anded with 0x7fff. This is
X done to allow the window to also be used as the output buffer. */
X/* This must be supplied in an external module useable like "uch slide[8192];"
X or "uch *slide;", where the latter would be malloc'ed. In unzip, slide[]
X is actually a 32K area for use by inflate, which uses a 32K sliding window.
X */
X
X
X/* Tables for length and distance */
Xush cplen2[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
X 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
X 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65};
Xush cplen3[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
X 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
X 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
X 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66};
Xush extra[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 8};
Xush cpdist4[] = {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705,
X 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473,
X 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177,
X 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881,
X 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585,
X 3649, 3713, 3777, 3841, 3905, 3969, 4033};
Xush cpdist8[] = {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281,
X 1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689,
X 2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097,
X 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505,
X 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913,
X 7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065};
X
X
X/* Macros for inflate() bit peeking and grabbing.
X The usage is:
X
X NEEDBITS(j)
X x = b & mask_bits[j];
X DUMPBITS(j)
X
X where NEEDBITS makes sure that b has at least j bits in it, and
X DUMPBITS removes the bits from b. The macros use the variable k
X for the number of bits in b. Normally, b and k are register
X variables for speed.
X */
X
X#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}}
X#define DUMPBITS(n) {b>>=(n);k-=(n);}
X
X
X
Xint get_tree(l, n)
Xunsigned *l; /* bit lengths */
Xunsigned n; /* number expected */
X/* Get the bit lengths for a code representation from the compressed
X stream. If get_tree() returns 4, then there is an error in the data.
X Otherwise zero is returned. */
X{
X unsigned i; /* bytes remaining in list */
X unsigned k; /* lengths entered */
X unsigned j; /* number of codes */
X unsigned b; /* bit length for those codes */
X
X
X /* get bit lengths */
X i = NEXTBYTE + 1; /* length/count pairs to read */
X k = 0; /* next code */
X do {
X b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */
X j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */
X if (k + j > n)
X return 4; /* don't overflow l[] */
X do {
X l[k++] = b;
X } while (--j);
X } while (--i);
X return k != n ? 4 : 0; /* should have read n of them */
X}
X
X
X
Xint explode_lit8(tb, tl, td, bb, bl, bd)
Xstruct huft *tb, *tl, *td; /* literal, length, and distance tables */
Xint bb, bl, bd; /* number of bits decoded by those */
X/* Decompress the imploded data using coded literals and an 8K sliding
X window. */
X{
X long s; /* bytes to decompress */
X register unsigned e; /* table entry flag/number of extra bits */
X unsigned n, d; /* length and index for copy */
X unsigned w; /* current window position */
X struct huft *t; /* pointer to table entry */
X unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X unsigned u; /* true if unflushed */
X
X
X /* explode the coded data */
X b = k = w = 0; /* initialize bit buffer, window */
X u = 1; /* buffer unflushed */
X mb = mask_bits[bb]; /* precompute masks for speed */
X ml = mask_bits[bl];
X md = mask_bits[bd];
X s = ucsize;
X while (s > 0) /* do until ucsize bytes uncompressed */
X {
X NEEDBITS(1)
X if (b & 1) /* then literal--decode it */
X {
X DUMPBITS(1)
X s--;
X NEEDBITS((unsigned)bb) /* get coded literal */
X if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X slide[w++] = (uch)t->v.n;
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X }
X else /* else distance/length */
X {
X DUMPBITS(1)
X NEEDBITS(7) /* get distance low bits */
X d = (unsigned)b & 0x7f;
X DUMPBITS(7)
X NEEDBITS((unsigned)bd) /* get coded distance high bits */
X if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X d = w - d - t->v.n; /* construct offset */
X NEEDBITS((unsigned)bl) /* get coded length */
X if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X n = t->v.n;
X if (e) /* get length extra bits */
X {
X NEEDBITS(8)
X n += (unsigned)b & 0xff;
X DUMPBITS(8)
X }
X
X /* do the copy */
X s -= n;
X do {
X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
X if (u && w <= d)
X {
X memzero(slide + w, e);
X w += e;
X d += e;
X }
X else
X#ifndef NOMEMCPY
X if (w - d >= e) /* (this test assumes unsigned comparison) */
X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }
X else /* do it slow to avoid memcpy() overlap */
X#endif /* !NOMEMCPY */
X do {
X slide[w++] = slide[d++];
X } while (--e);
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X } while (n);
X }
X }
X
X /* flush out slide */
X flush(slide, w, 0);
X if (csize + (k >> 3)) /* should have read csize bytes, but sometimes */
X { /* read one too many: k>>3 compensates */
X used_csize = lrec.csize - csize - (k >> 3);
X return 5;
X }


X return 0;
X}
X
X

X
Xint explode_lit4(tb, tl, td, bb, bl, bd)
Xstruct huft *tb, *tl, *td; /* literal, length, and distance tables */
Xint bb, bl, bd; /* number of bits decoded by those */
X/* Decompress the imploded data using coded literals and a 4K sliding
X window. */
X{
X long s; /* bytes to decompress */
X register unsigned e; /* table entry flag/number of extra bits */
X unsigned n, d; /* length and index for copy */
X unsigned w; /* current window position */
X struct huft *t; /* pointer to table entry */
X unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X unsigned u; /* true if unflushed */
X
X
X /* explode the coded data */
X b = k = w = 0; /* initialize bit buffer, window */
X u = 1; /* buffer unflushed */
X mb = mask_bits[bb]; /* precompute masks for speed */
X ml = mask_bits[bl];
X md = mask_bits[bd];
X s = ucsize;
X while (s > 0) /* do until ucsize bytes uncompressed */
X {
X NEEDBITS(1)
X if (b & 1) /* then literal--decode it */
X {
X DUMPBITS(1)
X s--;
X NEEDBITS((unsigned)bb) /* get coded literal */
X if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X slide[w++] = (uch)t->v.n;
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X }
X else /* else distance/length */
X {
X DUMPBITS(1)
X NEEDBITS(6) /* get distance low bits */
X d = (unsigned)b & 0x3f;
X DUMPBITS(6)
X NEEDBITS((unsigned)bd) /* get coded distance high bits */
X if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X d = w - d - t->v.n; /* construct offset */
X NEEDBITS((unsigned)bl) /* get coded length */
X if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X n = t->v.n;
X if (e) /* get length extra bits */
X {
X NEEDBITS(8)
X n += (unsigned)b & 0xff;
X DUMPBITS(8)
X }
X
X /* do the copy */
X s -= n;
X do {
X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
X if (u && w <= d)
X {
X memzero(slide + w, e);
X w += e;
X d += e;
X }
X else
X#ifndef NOMEMCPY
X if (w - d >= e) /* (this test assumes unsigned comparison) */
X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }
X else /* do it slow to avoid memcpy() overlap */
X#endif /* !NOMEMCPY */
X do {
X slide[w++] = slide[d++];
X } while (--e);
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X } while (n);
X }
X }
X
X /* flush out slide */
X flush(slide, w, 0);
X if (csize + (k >> 3)) /* should have read csize bytes, but sometimes */
X { /* read one too many: k>>3 compensates */
X used_csize = lrec.csize - csize - (k >> 3);
X return 5;
X }


X return 0;
X}
X
X

X
Xint explode_nolit8(tl, td, bl, bd)
Xstruct huft *tl, *td; /* length and distance decoder tables */
Xint bl, bd; /* number of bits decoded by tl[] and td[] */
X/* Decompress the imploded data using uncoded literals and an 8K sliding
X window. */
X{
X long s; /* bytes to decompress */
X register unsigned e; /* table entry flag/number of extra bits */
X unsigned n, d; /* length and index for copy */
X unsigned w; /* current window position */
X struct huft *t; /* pointer to table entry */
X unsigned ml, md; /* masks for bl and bd bits */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X unsigned u; /* true if unflushed */
X
X
X /* explode the coded data */
X b = k = w = 0; /* initialize bit buffer, window */
X u = 1; /* buffer unflushed */
X ml = mask_bits[bl]; /* precompute masks for speed */
X md = mask_bits[bd];
X s = ucsize;
X while (s > 0) /* do until ucsize bytes uncompressed */
X {
X NEEDBITS(1)
X if (b & 1) /* then literal--get eight bits */
X {
X DUMPBITS(1)
X s--;
X NEEDBITS(8)
X slide[w++] = (uch)b;
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X DUMPBITS(8)
X }
X else /* else distance/length */
X {
X DUMPBITS(1)
X NEEDBITS(7) /* get distance low bits */
X d = (unsigned)b & 0x7f;
X DUMPBITS(7)
X NEEDBITS((unsigned)bd) /* get coded distance high bits */
X if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X d = w - d - t->v.n; /* construct offset */
X NEEDBITS((unsigned)bl) /* get coded length */
X if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X n = t->v.n;
X if (e) /* get length extra bits */
X {
X NEEDBITS(8)
X n += (unsigned)b & 0xff;
X DUMPBITS(8)
X }
X
X /* do the copy */
X s -= n;
X do {
X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
X if (u && w <= d)
X {
X memzero(slide + w, e);
X w += e;
X d += e;
X }
X else
X#ifndef NOMEMCPY
X if (w - d >= e) /* (this test assumes unsigned comparison) */
X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }
X else /* do it slow to avoid memcpy() overlap */
X#endif /* !NOMEMCPY */
X do {
X slide[w++] = slide[d++];
X } while (--e);
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X } while (n);
X }
X }
X
X /* flush out slide */
X flush(slide, w, 0);
X if (csize + (k >> 3)) /* should have read csize bytes, but sometimes */
X { /* read one too many: k>>3 compensates */
X used_csize = lrec.csize - csize - (k >> 3);
X return 5;
X }


X return 0;
X}
X
X

X
Xint explode_nolit4(tl, td, bl, bd)
Xstruct huft *tl, *td; /* length and distance decoder tables */
Xint bl, bd; /* number of bits decoded by tl[] and td[] */
X/* Decompress the imploded data using uncoded literals and a 4K sliding
X window. */
X{
X long s; /* bytes to decompress */
X register unsigned e; /* table entry flag/number of extra bits */
X unsigned n, d; /* length and index for copy */
X unsigned w; /* current window position */
X struct huft *t; /* pointer to table entry */
X unsigned ml, md; /* masks for bl and bd bits */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X unsigned u; /* true if unflushed */
X
X
X /* explode the coded data */
X b = k = w = 0; /* initialize bit buffer, window */
X u = 1; /* buffer unflushed */
X ml = mask_bits[bl]; /* precompute masks for speed */
X md = mask_bits[bd];
X s = ucsize;
X while (s > 0) /* do until ucsize bytes uncompressed */
X {
X NEEDBITS(1)
X if (b & 1) /* then literal--get eight bits */
X {
X DUMPBITS(1)
X s--;
X NEEDBITS(8)
X slide[w++] = (uch)b;
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X DUMPBITS(8)
X }
X else /* else distance/length */
X {
X DUMPBITS(1)
X NEEDBITS(6) /* get distance low bits */
X d = (unsigned)b & 0x3f;
X DUMPBITS(6)
X NEEDBITS((unsigned)bd) /* get coded distance high bits */
X if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X d = w - d - t->v.n; /* construct offset */
X NEEDBITS((unsigned)bl) /* get coded length */
X if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
X DUMPBITS(t->b)
X n = t->v.n;
X if (e) /* get length extra bits */
X {
X NEEDBITS(8)
X n += (unsigned)b & 0xff;
X DUMPBITS(8)
X }
X
X /* do the copy */
X s -= n;
X do {
X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
X if (u && w <= d)
X {
X memzero(slide + w, e);
X w += e;
X d += e;
X }
X else
X#ifndef NOMEMCPY
X if (w - d >= e) /* (this test assumes unsigned comparison) */
X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }
X else /* do it slow to avoid memcpy() overlap */
X#endif /* !NOMEMCPY */
X do {
X slide[w++] = slide[d++];
X } while (--e);
X if (w == WSIZE)
X {
X flush(slide, w, 0);
X w = u = 0;
X }
X } while (n);
X }
X }
X
X /* flush out slide */
X flush(slide, w, 0);
X if (csize + (k >> 3)) /* should have read csize bytes, but sometimes */
X { /* read one too many: k>>3 compensates */
X used_csize = lrec.csize - csize - (k >> 3);
X return 5;
X }


X return 0;
X}
X
X

X
Xint explode()
X/* Explode an imploded compressed stream. Based on the general purpose
X bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding
X window. Construct the literal (if any), length, and distance codes and
X the tables needed to decode them (using huft_build() from inflate.c),
X and call the appropriate routine for the type of data in the remainder
X of the stream. The four routines are nearly identical, differing only
X in whether the literal is decoded or simply read in, and in how many
X bits are read in, uncoded, for the low distance bits. */
X{
X unsigned r; /* return codes */
X struct huft *tb; /* literal code table */
X struct huft *tl; /* length code table */
X struct huft *td; /* distance code table */
X int bb; /* bits for tb */
X int bl; /* bits for tl */
X int bd; /* bits for td */
X static unsigned l[256]; /* bit lengths for codes */
X
X
X /* Tune base table sizes. Note: I thought that to truly optimize speed,
X I would have to select different bl, bd, and bb values for different
X compressed file sizes. I was suprised to find out the the values of
X 7, 7, and 9 worked best over a very wide range of sizes, except that
X bd = 8 worked marginally better for large compressed sizes. */
X bl = 7;
X bd = csize > 200000L ? 8 : 7;
X
X
X /* With literal tree--minimum match length is 3 */
X hufts = 0; /* initialize huft's malloc'ed */
X if (lrec.general_purpose_bit_flag & 4)
X {
X bb = 9; /* base table size for literals */
X if ((r = get_tree(l, 256)) != 0)
X return (int)r;
X if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb)) != 0)
X {
X if (r == 1)
X huft_free(tb);
X return (int)r;
X }
X if ((r = get_tree(l, 64)) != 0)
X return (int)r;
X if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl)) != 0)
X {
X if (r == 1)
X huft_free(tl);
X huft_free(tb);
X return (int)r;
X }
X if ((r = get_tree(l, 64)) != 0)
X return (int)r;
X if (lrec.general_purpose_bit_flag & 2) /* true if 8K */
X {
X if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
X {
X if (r == 1)
X huft_free(td);
X huft_free(tl);
X huft_free(tb);
X return (int)r;
X }
X r = explode_lit8(tb, tl, td, bb, bl, bd);
X }
X else /* else 4K */
X {
X if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
X {
X if (r == 1)
X huft_free(td);
X huft_free(tl);
X huft_free(tb);
X return (int)r;
X }
X r = explode_lit4(tb, tl, td, bb, bl, bd);
X }
X huft_free(td);
X huft_free(tl);
X huft_free(tb);


X }
X else
X
X

X /* No literal tree--minimum match length is 2 */
X {
X if ((r = get_tree(l, 64)) != 0)
X return (int)r;
X if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl)) != 0)
X {
X if (r == 1)
X huft_free(tl);
X return (int)r;
X }
X if ((r = get_tree(l, 64)) != 0)
X return (int)r;
X if (lrec.general_purpose_bit_flag & 2) /* true if 8K */
X {
X if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
X {
X if (r == 1)
X huft_free(td);
X huft_free(tl);
X return (int)r;
X }
X r = explode_nolit8(tl, td, bl, bd);
X }
X else /* else 4K */
X {
X if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
X {
X if (r == 1)
X huft_free(td);
X huft_free(tl);
X return (int)r;
X }
X r = explode_nolit4(tl, td, bl, bd);
X }
X huft_free(td);
X huft_free(tl);
X }
X#ifdef DEBUG
X fprintf(stderr, "<%u > ", hufts);
X#endif /* DEBUG */
X return (int)r;
X}
X
X/* so explode.c and inflate.c can be compiled together into one object: */
X#undef NEXTBYTE
X#undef NEEDBITS
X#undef DUMPBITS
END_OF_FILE
if test 28523 -ne `wc -c <'unzip-5.12/explode.c'`; then
echo shar: \"'unzip-5.12/explode.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/explode.c'
fi
if test -f 'unzip-5.12/inflate.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/inflate.c'\"
else
echo shar: Extracting \"'unzip-5.12/inflate.c'\" \(38275 characters\)
sed "s/^X//" >'unzip-5.12/inflate.c' <<'END_OF_FILE'
X/* inflate.c -- put in the public domain by Mark Adler
X version c14o, 23 August 1994 */
X
X
X/* You can do whatever you like with this source file, though I would
X prefer that if you modify it and redistribute it that you include
X comments to that effect with your name and the date. Thank you.
X
X History:
X vers date who what
X ---- --------- -------------- ------------------------------------
X a ~~ Feb 92 M. Adler used full (large, one-step) lookup table
X b1 21 Mar 92 M. Adler first version with partial lookup tables
X b2 21 Mar 92 M. Adler fixed bug in fixed-code blocks
X b3 22 Mar 92 M. Adler sped up match copies, cleaned up some
X b4 25 Mar 92 M. Adler added prototypes; removed window[] (now
X is the responsibility of unzip.h--also
X changed name to slide[]), so needs diffs
X for unzip.c and unzip.h (this allows
X compiling in the small model on MSDOS);
X fixed cast of q in huft_build();
X b5 26 Mar 92 M. Adler got rid of unintended macro recursion.
X b6 27 Mar 92 M. Adler got rid of nextbyte() routine. fixed
X bug in inflate_fixed().
X c1 30 Mar 92 M. Adler removed lbits, dbits environment variables.
X changed BMAX to 16 for explode. Removed
X OUTB usage, and replaced it with flush()--
X this was a 20% speed improvement! Added
X an explode.c (to replace unimplod.c) that
X uses the huft routines here. Removed
X register union.
X c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k.
X c3 10 Apr 92 M. Adler reduced memory of code tables made by
X huft_build significantly (factor of two to
X three).
X c4 15 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy().
X worked around a Turbo C optimization bug.
X c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing
X the 32K window size for specialized
X applications.
X c6 31 May 92 M. Adler added some typecasts to eliminate warnings
X c7 27 Jun 92 G. Roelofs added some more typecasts (444: MSC bug).
X c8 5 Oct 92 J-l. Gailly added ifdef'd code to deal with PKZIP bug.
X c9 9 Oct 92 M. Adler removed a memory error message (~line 416).
X c10 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch,
X removed old inflate, renamed inflate_entry
X to inflate, added Mark's fix to a comment.
X c10.5 14 Dec 92 M. Adler fix up error messages for incomplete trees.
X c11 2 Jan 93 M. Adler fixed bug in detection of incomplete
X tables, and removed assumption that EOB is
X the longest code (bad assumption).
X c12 3 Jan 93 M. Adler make tables for fixed blocks only once.
X c13 5 Jan 93 M. Adler allow all zero length codes (pkzip 2.04c
X outputs one zero length code for an empty
X distance tree).
X c14 12 Mar 93 M. Adler made inflate.c standalone with the
X introduction of inflate.h.
X c14b 16 Jul 93 G. Roelofs added (unsigned) typecast to w at 470.
X c14c 19 Jul 93 J. Bush changed v[N_MAX], l[288], ll[28x+3x] arrays
X to static for Amiga.
X c14d 13 Aug 93 J-l. Gailly de-complicatified Mark's c[*p++]++ thing.
X c14e 8 Oct 93 G. Roelofs changed memset() to memzero().
X c14f 22 Oct 93 G. Roelofs renamed quietflg to qflag; made Trace()
X conditional; added inflate_free().
X c14g 28 Oct 93 G. Roelofs changed l/(lx+1) macro to pointer (Cray bug)
X c14h 7 Dec 93 C. Ghisler huft_build() optimizations.
X c14i 9 Jan 94 A. Verheijen set fixed_t{d,l} to NULL after freeing;
X G. Roelofs check NEXTBYTE macro for EOF.
X c14j 23 Jan 94 G. Roelofs removed Ghisler "optimizations"; ifdef'd
X EOF check.
X c14k 27 Feb 94 G. Roelofs added some typecasts to avoid warnings.
X c14l 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines
X to avoid bug in Encore compiler.
X c14m 7 Jul 94 P. Kienitz modified to allow assembler version of
X inflate_codes() (define ASM_INFLATECODES)
X c14n 22 Jul 94 G. Roelofs changed fprintf to FPRINTF for DLL versions
X c14o 23 Aug 94 C. Spieler added a newline to a debug statement;
X G. Roelofs added another typecast to avoid MSC warning


X */
X
X
X/*

X Inflate deflated (PKZIP's method 8 compressed) data. The compression
X method searches for as much of the current string of bytes (up to a
X length of 258) in the previous 32K bytes. If it doesn't find any
X matches (of at least length 3), it codes the next byte. Otherwise, it
X codes the length of the matched string and its distance backwards from
X the current position. There is a single Huffman code that codes both
X single bytes (called "literals") and match lengths. A second Huffman
X code codes the distance information, which follows a length code. Each
X length or distance code actually represents a base value and a number
X of "extra" (sometimes zero) bits to get to add to the base value. At
X the end of each deflated block is a special end-of-block (EOB) literal/
X length code. The decoding process is basically: get a literal/length
X code; if EOB then done; if a literal, emit the decoded byte; if a
X length then get the distance and emit the referred-to bytes from the
X sliding window of previously emitted data.
X
X There are (currently) three kinds of inflate blocks: stored, fixed, and
X dynamic. The compressor outputs a chunk of data at a time and decides
X which method to use on a chunk-by-chunk basis. A chunk might typically
X be 32K to 64K, uncompressed. If the chunk is uncompressible, then the
X "stored" method is used. In this case, the bytes are simply stored as
X is, eight bits per byte, with none of the above coding. The bytes are
X preceded by a count, since there is no longer an EOB code.
X
X If the data is compressible, then either the fixed or dynamic methods
X are used. In the dynamic method, the compressed data is preceded by
X an encoding of the literal/length and distance Huffman codes that are
X to be used to decode this block. The representation is itself Huffman
X coded, and so is preceded by a description of that code. These code
X descriptions take up a little space, and so for small blocks, there is
X a predefined set of codes, called the fixed codes. The fixed method is
X used if the block ends up smaller that way (usually for quite small
X chunks); otherwise the dynamic method is used. In the latter case, the
X codes are customized to the probabilities in the current block and so
X can code it much better than the pre-determined fixed codes can.
X
X The Huffman codes themselves are decoded using a mutli-level table
X lookup, in order to maximize the speed of decoding plus the speed of
X building the decoding tables. See the comments below that precede the
X lbits and dbits tuning parameters.


X */
X
X
X/*

X Notes beyond the 1.93a appnote.txt:
X
X 1. Distance pointers never point before the beginning of the output
X stream.
X 2. Distance pointers can point back across blocks, up to 32k away.
X 3. There is an implied maximum of 7 bits for the bit length table and
X 15 bits for the actual data.
X 4. If only one code exists, then it is encoded using one bit. (Zero
X would be more efficient, but perhaps a little confusing.) If two
X codes exist, they are coded using one bit each (0 and 1).
X 5. There is no way of sending zero distance codes--a dummy must be
X sent if there are none. (History: a pre 2.0 version of PKZIP would
X store blocks with no distance codes, but this was discovered to be
X too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
X zero distance codes, which is sent as one code of zero bits in
X length.
X 6. There are up to 286 literal/length codes. Code 256 represents the
X end-of-block. Note however that the static length tree defines
X 288 codes just to fill out the Huffman codes. Codes 286 and 287
X cannot be used though, since there is no length base or extra bits
X defined for them. Similarily, there are up to 30 distance codes.
X However, static trees define 32 codes (all 5 bits) to fill out the
X Huffman codes, but the last two had better not show up in the data.
X 7. Unzip can check dynamic Huffman blocks for complete code sets.
X The exception is that a single code would not be complete (see #4).
X 8. The five bits following the block type is really the number of
X literal codes sent minus 257.
X 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
X (1+6+6). Therefore, to output three times the length, you output
X three codes (1+1+1), whereas to output four times the same length,
X you only need two codes (1+3). Hmm.
X 10. In the tree reconstruction algorithm, Code = Code + Increment
X only if BitLength(i) is not zero. (Pretty obvious.)
X 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
X 12. Note: length code 284 can represent 227-258, but length code 285
X really is 258. The last length deserves its own, short code
X since it gets used a lot in very redundant files. The length
X 258 is special since 258 - 3 (the min match length) is 255.
X 13. The literal/length and distance code bit lengths are read as a
X single stream of lengths. It is possible (and advantageous) for
X a repeat code (16, 17, or 18) to go across the boundary between
X the two sets of lengths.
X */
X
X
X#define PKZIP_BUG_WORKAROUND /* PKZIP 1.93a problem--live with it */
X
X/*
X inflate.h must supply the uch slide[WSIZE] array and the NEXTBYTE,
X FLUSH() and memzero macros. If the window size is not 32K, it
X should also define WSIZE. If INFMOD is defined, it can include
X compiled functions to support the NEXTBYTE and/or FLUSH() macros.
X There are defaults for NEXTBYTE and FLUSH() below for use as
X examples of what those functions need to do. Normally, you would
X also want FLUSH() to compute a crc on the data. inflate.h also
X needs to provide these typedefs:
X
X typedef unsigned char uch;
X typedef unsigned short ush;
X typedef unsigned long ulg;
X
X This module uses the external functions malloc() and free() (and
X probably memset() or bzero() in the memzero() macro). Their
X prototypes are normally found in <string.h> and <stdlib.h>.
X */
X#define INFMOD /* tell inflate.h to include code to be compiled */
X#include "inflate.h"
X
X#ifndef WSIZE /* default is 32K */
X# define WSIZE 0x8000 /* window size--must be a power of two, and at least */
X#endif /* 32K for zip's deflate method */
X
X#ifndef NEXTBYTE /* default is to simply get a byte from stdin */
X# define NEXTBYTE getchar()
X#endif
X


X#ifndef FPRINTF
X# define FPRINTF fprintf
X#endif
X

X#ifndef FLUSH /* default is to simply write the buffer to stdout */
X# define FLUSH(n) fwrite(slide, 1, n, stdout) /* return value not used */
X#endif
X/* Warning: the fwrite above might not work on 16-bit compilers, since
X 0x8000 might be interpreted as -32,768 by the library function. */
X
X#ifndef Trace
X# ifdef DEBUG
X# define Trace(x) fprintf x
X# else
X# define Trace(x)
X# endif
X#endif
X
X
X/* Huffman code lookup table entry--this entry is four bytes for machines
X that have 16-bit pointers (e.g. PC's in the small or medium model).
X Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16
X means that v is a literal, 16 < e < 32 means that v is a pointer to
X the next table, which codes e - 16 bits, and lastly e == 99 indicates
X an unused code. If a code with e == 99 is looked up, this implies an
X error in the data. */
Xstruct huft {
X uch e; /* number of extra bits or operation */
X uch b; /* number of bits in this code or subcode */
X union {
X ush n; /* literal, length base, or distance base */
X struct huft *t; /* pointer to next level of table */
X } v;
X};
X
X
X/* Function prototypes */
X#ifndef OF
X# ifdef __STDC__
X# define OF(a) a
X# else /* !__STDC__ */
X# define OF(a) ()
X# endif /* ?__STDC__ */
X#endif
Xint huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
X struct huft **, int *));
Xint huft_free OF((struct huft *));
Xint inflate_codes OF((struct huft *, struct huft *, int, int));
Xint inflate_stored OF((void));
Xint inflate_fixed OF((void));
Xint inflate_dynamic OF((void));
Xint inflate_block OF((int *));
Xint inflate OF((void));
Xint inflate_free OF((void));
X
X
X/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
X stream to find repeated byte strings. This is implemented here as a
X circular buffer. The index is updated simply by incrementing and then
X and'ing with 0x7fff (32K-1). */
X/* It is left to other modules to supply the 32K area. It is assumed
X to be usable as if it were declared "uch slide[32768];" or as just
X "uch *slide;" and then malloc'ed in the latter case. The definition
X must be in unzip.h, included above. */
Xunsigned wp; /* current position in slide */
X
X
X/* Tables for deflate from PKZIP's appnote.txt. */
Xstatic unsigned border[] = { /* Order of the bit length code lengths */
X 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
Xstatic ush cplens[] = { /* Copy lengths for literal codes 257..285 */
X 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
X 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
X /* note: see note #13 above about the 258 in this list. */
Xstatic ush cplext[] = { /* Extra bits for literal codes 257..285 */
X 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
X 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
Xstatic ush cpdist[] = { /* Copy offsets for distance codes 0..29 */
X 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
X 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
X 8193, 12289, 16385, 24577};
Xstatic ush cpdext[] = { /* Extra bits for distance codes */
X 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
X 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
X 12, 12, 13, 13};
X
X/* And'ing with mask[n] masks the lower n bits */
Xush mask[] = {


X 0x0000,
X 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
X 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
X};
X
X

X/* Macros for inflate() bit peeking and grabbing.
X The usage is:
X
X NEEDBITS(j)
X x = b & mask[j];
X DUMPBITS(j)
X
X where NEEDBITS makes sure that b has at least j bits in it, and
X DUMPBITS removes the bits from b. The macros use the variable k
X for the number of bits in b. Normally, b and k are register
X variables for speed, and are initialized at the begining of a
X routine that uses these macros from a global bit buffer and count.
X
X In order to not ask for more bits than there are in the compressed
X stream, the Huffman tables are constructed to only ask for just
X enough bits to make up the end-of-block code (value 256). Then no
X bytes need to be "returned" to the buffer at the end of the last
X block. See the huft_build() routine.
X */
X
Xulg bb; /* bit buffer */
Xunsigned bk; /* bits in bit buffer */
X
X#ifndef CHECK_EOF
X# define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}}
X#else
X# define NEEDBITS(n) {while(k<(n)){int c=NEXTBYTE;if(c==EOF)return 1;\
X b|=((ulg)c)<<k;k+=8;}}
X#endif /* Piet Plomp: change "return 1" to "break" */
X
X#define DUMPBITS(n) {b>>=(n);k-=(n);}
X
X
X/*
X Huffman code decoding is performed using a multi-level table lookup.
X The fastest way to decode is to simply build a lookup table whose
X size is determined by the longest code. However, the time it takes
X to build this table can also be a factor if the data being decoded
X is not very long. The most common codes are necessarily the
X shortest codes, so those codes dominate the decoding time, and hence
X the speed. The idea is you can have a shorter table that decodes the
X shorter, more probable codes, and then point to subsidiary tables for
X the longer codes. The time it costs to decode the longer codes is
X then traded against the time it takes to make longer tables.
X
X This results of this trade are in the variables lbits and dbits
X below. lbits is the number of bits the first level table for literal/
X length codes can decode in one step, and dbits is the same thing for
X the distance codes. Subsequent tables are also less than or equal to
X those sizes. These values may be adjusted either when all of the
X codes are shorter than that, in which case the longest code length in
X bits is used, or when the shortest code is *longer* than the requested
X table size, in which case the length of the shortest code in bits is
X used.
X
X There are two different values for the two tables, since they code a
X different number of possibilities each. The literal/length table
X codes 286 possible values, or in a flat code, a little over eight
X bits. The distance table codes 30 possible values, or a little less
X than five bits, flat. The optimum values for speed end up being
X about one bit more than those, so lbits is 8+1 and dbits is 5+1.
X The optimum values may differ though from machine to machine, and
X possibly even between compilers. Your mileage may vary.
X */
X
X
Xint lbits = 9; /* bits in base literal/length lookup table */
Xint dbits = 6; /* bits in base distance lookup table */
X
X
X/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
X#define BMAX 16 /* maximum bit length of any code (16 for explode) */
X#define N_MAX 288 /* maximum number of codes in any set */
X
X
Xunsigned hufts; /* track memory usage */
X
X
Xint huft_build(b, n, s, d, e, t, m)
Xunsigned *b; /* code lengths in bits (all assumed <= BMAX) */
Xunsigned n; /* number of codes (assumed <= N_MAX) */
Xunsigned s; /* number of simple-valued codes (0..s-1) */
Xush *d; /* list of base values for non-simple codes */
Xush *e; /* list of extra bits for non-simple codes */
Xstruct huft **t; /* result: starting table */
Xint *m; /* maximum lookup bits, returns actual */
X/* Given a list of code lengths and a maximum table size, make a set of
X tables to decode that set of codes. Return zero on success, one if
X the given code set is incomplete (the tables are still built in this
X case), two if the input is invalid (all zero length codes or an
X oversubscribed set of lengths), and three if not enough memory.
X The code with value 256 is special, and the tables are constructed
X so that no bits beyond that code are fetched when that code is
X decoded. */
X{
X unsigned a; /* counter for codes of length k */
X unsigned c[BMAX+1]; /* bit length count table */
X unsigned el; /* length of EOB code (value 256) */
X unsigned f; /* i repeats in table every f entries */
X int g; /* maximum code length */
X int h; /* table level */
X register unsigned i; /* counter, current code */
X register unsigned j; /* counter */
X register int k; /* number of bits in current code */
X int lx[BMAX+1]; /* memory for l[-1..BMAX-1] */
X int *l = lx+1; /* stack of bits per table */
X register unsigned *p; /* pointer into c[], b[], or v[] */
X register struct huft *q; /* points to current table */
X struct huft r; /* table entry for structure assignment */
X struct huft *u[BMAX]; /* table stack */
X static unsigned v[N_MAX]; /* values in order of bit length */
X register int w; /* bits before this table == (l * h) */
X unsigned x[BMAX+1]; /* bit offsets, then code stack */
X unsigned *xp; /* pointer into x */
X int y; /* number of dummy codes added */
X unsigned z; /* number of entries in current table */
X
X
X /* Generate counts for each bit length */
X el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */
X memzero((char *)c, sizeof(c));
X p = b; i = n;
X do {
X c[*p]++; p++; /* assume all entries <= BMAX */
X } while (--i);
X if (c[0] == n) /* null input--all zero length codes */
X {
X *t = (struct huft *)NULL;
X *m = 0;


X return 0;
X }
X

X
X /* Find minimum and maximum length, bound *m by those */
X for (j = 1; j <= BMAX; j++)
X if (c[j])
X break;
X k = j; /* minimum code length */
X if ((unsigned)*m < j)
X *m = j;
X for (i = BMAX; i; i--)
X if (c[i])
X break;
X g = i; /* maximum code length */
X if ((unsigned)*m > i)
X *m = i;
X
X
X /* Adjust last length count to fill out codes, if needed */
X for (y = 1 << j; j < i; j++, y <<= 1)
X if ((y -= c[j]) < 0)
X return 2; /* bad input: more codes than bits */
X if ((y -= c[i]) < 0)
X return 2;
X c[i] += y;
X
X
X /* Generate starting offsets into the value table for each length */
X x[1] = j = 0;
X p = c + 1; xp = x + 2;
X while (--i) { /* note that i == g from above */
X *xp++ = (j += *p++);
X }
X
X
X /* Make a table of values in order of bit lengths */
X p = b; i = 0;
X do {
X if ((j = *p++) != 0)
X v[x[j]++] = i;
X } while (++i < n);
X
X
X /* Generate the Huffman codes and for each, make the table entries */
X x[0] = i = 0; /* first Huffman code is zero */
X p = v; /* grab values in bit order */
X h = -1; /* no tables yet--level -1 */
X w = l[-1] = 0; /* no bits decoded yet */
X u[0] = (struct huft *)NULL; /* just to keep compilers happy */
X q = (struct huft *)NULL; /* ditto */
X z = 0; /* ditto */
X
X /* go through the bit lengths (k already is bits in shortest code) */
X for (; k <= g; k++)
X {
X a = c[k];
X while (a--)
X {
X /* here i is the Huffman code of length k bits for value *p */
X /* make tables up to required level */
X while (k > w + l[h])
X {
X w += l[h++]; /* add bits already decoded */
X
X /* compute minimum size table less than or equal to *m bits */
X z = (z = g - w) > (unsigned)*m ? *m : z; /* upper limit */
X if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
X { /* too few codes for k-w bit table */
X f -= a + 1; /* deduct codes from patterns left */
X xp = c + k;
X while (++j < z) /* try smaller tables up to z bits */
X {
X if ((f <<= 1) <= *++xp)
X break; /* enough codes to use up j bits */
X f -= *xp; /* else deduct codes from patterns */
X }
X }
X if ((unsigned)w + j > el && (unsigned)w < el)
X j = el - w; /* make EOB code end at table */
X z = 1 << j; /* table entries for j-bit table */
X l[h] = j; /* set table size in stack */
X
X /* allocate and link in new table */
X if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
X (struct huft *)NULL)
X {
X if (h)
X huft_free(u[0]);
X return 3; /* not enough memory */
X }
X hufts += z + 1; /* track memory usage */
X *t = q + 1; /* link to list for huft_free() */
X *(t = &(q->v.t)) = (struct huft *)NULL;
X u[h] = ++q; /* table starts after link */
X
X /* connect to last table, if there is one */
X if (h)
X {
X x[h] = i; /* save pattern for backing up */
X r.b = (uch)l[h-1]; /* bits to dump before this table */
X r.e = (uch)(16 + j); /* bits in this table */
X r.v.t = q; /* pointer to this table */
X j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
X u[h-1][j] = r; /* connect to last table */
X }
X }
X
X /* set up table entry in r */
X r.b = (uch)(k - w);
X if (p >= v + n)
X r.e = 99; /* out of values--invalid code */
X else if (*p < s)
X {
X r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
X r.v.n = *p++; /* simple code is just the value */
X }
X else
X {
X r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
X r.v.n = d[*p++ - s];
X }
X
X /* fill code-like entries with r */
X f = 1 << (k - w);
X for (j = i >> w; j < z; j += f)
X q[j] = r;
X
X /* backwards increment the k-bit code i */
X for (j = 1 << (k - 1); i & j; j >>= 1)
X i ^= j;
X i ^= j;
X
X /* backup over finished tables */
X while ((i & ((1 << w) - 1)) != x[h])
X w -= l[--h]; /* don't need to update q */
X }
X }
X
X
X /* return actual size of base table */
X *m = l[0];
X
X
X /* Return true (1) if we were given an incomplete table */
X return y != 0 && g != 1;
X}
X
X
X
Xint huft_free(t)
Xstruct huft *t; /* table to free */
X/* Free the malloc'ed tables built by huft_build(), which makes a linked
X list of the tables it made, with the links in a dummy first entry of
X each table. */
X{
X register struct huft *p, *q;
X
X
X /* Go through linked list, freeing from the malloced (t[-1]) address. */
X p = t;
X while (p != (struct huft *)NULL)
X {
X q = (--p)->v.t;
X free(p);
X p = q;
X }

X return 0;
X}
X
X

X
X#ifdef ASM_INFLATECODES
X# define inflate_codes(tl,td,bl,bd) flate_codes(tl,td,bl,bd,(uch *)slide)
X int flate_codes OF((struct huft *, struct huft *, int, int, uch *));
X
X#else
X
Xint inflate_codes(tl, td, bl, bd)
Xstruct huft *tl, *td; /* literal/length and distance decoder tables */
Xint bl, bd; /* number of bits decoded by tl[] and td[] */
X/* inflate (decompress) the codes in a deflated (compressed) block.
X Return an error code or zero if it all goes ok. */
X{
X register unsigned e; /* table entry flag/number of extra bits */
X unsigned n, d; /* length and index for copy */
X unsigned w; /* current window position */
X struct huft *t; /* pointer to table entry */
X unsigned ml, md; /* masks for bl and bd bits */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X
X
X /* make local copies of globals */
X b = bb; /* initialize bit buffer */
X k = bk;
X w = wp; /* initialize window position */
X
X
X /* inflate the coded data */
X ml = mask[bl]; /* precompute masks for speed */
X md = mask[bd];
X while (1) /* do until end of block */
X {
X NEEDBITS((unsigned)bl)
X if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((unsigned)b & mask[e]))->e) > 16);
X DUMPBITS(t->b)
X if (e == 16) /* then it's a literal */
X {
X slide[w++] = (uch)t->v.n;
X if (w == WSIZE)
X {
X FLUSH(w);
X w = 0;
X }
X }
X else /* it's an EOB or a length */
X {
X /* exit if end of block */
X if (e == 15)
X break;
X
X /* get length of block to copy */
X NEEDBITS(e)
X n = t->v.n + ((unsigned)b & mask[e]);
X DUMPBITS(e);
X
X /* decode distance of block to copy */
X NEEDBITS((unsigned)bd)
X if ((e = (t = td + ((unsigned)b & md))->e) > 16)
X do {
X if (e == 99)
X return 1;
X DUMPBITS(t->b)
X e -= 16;
X NEEDBITS(e)
X } while ((e = (t = t->v.t + ((unsigned)b & mask[e]))->e) > 16);
X DUMPBITS(t->b)
X NEEDBITS(e)
X d = w - t->v.n - ((unsigned)b & mask[e]);
X DUMPBITS(e)
X
X /* do the copy */
X do {
X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
X#ifndef NOMEMCPY
X if (w - d >= e) /* (this test assumes unsigned comparison) */
X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }
X else /* do it slow to avoid memcpy() overlap */
X#endif /* !NOMEMCPY */
X do {
X slide[w++] = slide[d++];
X } while (--e);
X if (w == WSIZE)
X {
X FLUSH(w);
X w = 0;
X }
X } while (n);
X }
X }
X
X
X /* restore the globals from the locals */
X wp = w; /* restore global window pointer */
X bb = b; /* restore global bit buffer */
X bk = k;
X
X
X /* done */


X return 0;
X}
X

X#endif /* ASM_INFLATECODES */
X
X
X
Xint inflate_stored()
X/* "decompress" an inflated type 0 (stored) block. */
X{
X unsigned n; /* number of bytes in block */
X unsigned w; /* current window position */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X
X
X /* make local copies of globals */
X Trace((stderr, "\nstored block"));
X b = bb; /* initialize bit buffer */
X k = bk;
X w = wp; /* initialize window position */
X
X
X /* go to byte boundary */
X n = k & 7;
X DUMPBITS(n);
X
X
X /* get the length and its complement */
X NEEDBITS(16)
X n = ((unsigned)b & 0xffff);
X DUMPBITS(16)
X NEEDBITS(16)
X if (n != (unsigned)((~b) & 0xffff))
X return 1; /* error in compressed data */
X DUMPBITS(16)
X
X
X /* read and output the compressed data */
X while (n--)
X {
X NEEDBITS(8)
X slide[w++] = (uch)b;
X if (w == WSIZE)
X {
X FLUSH(w);
X w = 0;
X }
X DUMPBITS(8)
X }
X
X
X /* restore the globals from the locals */
X wp = w; /* restore global window pointer */
X bb = b; /* restore global bit buffer */
X bk = k;


X return 0;
X}
X
X

X/* Globals for literal tables (built once) */
Xstruct huft *fixed_tl = (struct huft *)NULL;
Xstruct huft *fixed_td;
Xint fixed_bl, fixed_bd;
X
Xint inflate_fixed()
X/* decompress an inflated type 1 (fixed Huffman codes) block. We should
X either replace this with a custom decoder, or at least precompute the
X Huffman tables. */
X{
X /* if first time, set up tables for fixed blocks */
X Trace((stderr, "\nliteral block"));
X if (fixed_tl == (struct huft *)NULL)
X {
X int i; /* temporary variable */
X static unsigned l[288]; /* length list for huft_build */
X
X /* literal table */
X for (i = 0; i < 144; i++)
X l[i] = 8;
X for (; i < 256; i++)
X l[i] = 9;
X for (; i < 280; i++)
X l[i] = 7;
X for (; i < 288; i++) /* make a complete, but wrong code set */
X l[i] = 8;
X fixed_bl = 7;
X if ((i = huft_build(l, 288, 257, cplens, cplext,
X &fixed_tl, &fixed_bl)) != 0)
X {
X fixed_tl = (struct huft *)NULL;
X return i;
X }
X
X /* distance table */
X for (i = 0; i < 30; i++) /* make an incomplete code set */
X l[i] = 5;
X fixed_bd = 5;
X if ((i = huft_build(l, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd)) > 1)
X {
X huft_free(fixed_tl);
X fixed_tl = (struct huft *)NULL;
X return i;
X }
X }
X
X
X /* decompress until an end-of-block code */
X return inflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd) != 0;
X}
X
X
X
Xint inflate_dynamic()
X/* decompress an inflated type 2 (dynamic Huffman codes) block. */
X{
X int i; /* temporary variables */
X unsigned j;
X unsigned l; /* last length */
X unsigned m; /* mask for bit lengths table */
X unsigned n; /* number of lengths to get */
X struct huft *tl; /* literal/length code table */
X struct huft *td; /* distance code table */
X int bl; /* lookup bits for tl */
X int bd; /* lookup bits for td */
X unsigned nb; /* number of bit length codes */
X unsigned nl; /* number of literal/length codes */
X unsigned nd; /* number of distance codes */
X#ifdef PKZIP_BUG_WORKAROUND
X static unsigned ll[288+32]; /* literal/length and distance code lengths */
X#else
X static unsigned ll[286+30]; /* literal/length and distance code lengths */
X#endif
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X
X
X /* make local bit buffer */
X Trace((stderr, "\ndynamic block"));
X b = bb;
X k = bk;
X
X
X /* read in table lengths */
X NEEDBITS(5)
X nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */
X DUMPBITS(5)
X NEEDBITS(5)
X nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */
X DUMPBITS(5)
X NEEDBITS(4)
X nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */
X DUMPBITS(4)
X#ifdef PKZIP_BUG_WORKAROUND
X if (nl > 288 || nd > 32)
X#else
X if (nl > 286 || nd > 30)
X#endif
X return 1; /* bad lengths */
X
X
X /* read in bit-length-code lengths */
X for (j = 0; j < nb; j++)
X {
X NEEDBITS(3)
X ll[border[j]] = (unsigned)b & 7;
X DUMPBITS(3)
X }
X for (; j < 19; j++)
X ll[border[j]] = 0;
X
X
X /* build decoding table for trees--single level, 7 bit lookup */
X bl = 7;
X if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
X {
X if (i == 1)
X huft_free(tl);
X return i; /* incomplete code set */
X }
X
X
X /* read in literal and distance code lengths */
X n = nl + nd;
X m = mask[bl];
X i = l = 0;
X while ((unsigned)i < n)
X {
X NEEDBITS((unsigned)bl)
X j = (td = tl + ((unsigned)b & m))->b;
X DUMPBITS(j)
X j = td->v.n;
X if (j < 16) /* length of code in bits (0..15) */
X ll[i++] = l = j; /* save last length in l */
X else if (j == 16) /* repeat last length 3 to 6 times */
X {
X NEEDBITS(2)
X j = 3 + ((unsigned)b & 3);
X DUMPBITS(2)
X if ((unsigned)i + j > n)
X return 1;
X while (j--)
X ll[i++] = l;
X }
X else if (j == 17) /* 3 to 10 zero length codes */
X {
X NEEDBITS(3)
X j = 3 + ((unsigned)b & 7);
X DUMPBITS(3)
X if ((unsigned)i + j > n)
X return 1;
X while (j--)
X ll[i++] = 0;


X l = 0;
X }

X else /* j == 18: 11 to 138 zero length codes */
X {
X NEEDBITS(7)
X j = 11 + ((unsigned)b & 0x7f);
X DUMPBITS(7)
X if ((unsigned)i + j > n)
X return 1;
X while (j--)
X ll[i++] = 0;
X l = 0;
X }
X }
X
X
X /* free decoding table for trees */
X huft_free(tl);
X
X
X /* restore the global bit buffer */
X bb = b;
X bk = k;
X
X
X /* build the decoding tables for literal/length and distance codes */
X bl = lbits;
X if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
X {
X if (i == 1 && !qflag) {
X FPRINTF(stderr, "(incomplete l-tree) ");
X huft_free(tl);
X }
X return i; /* incomplete code set */
X }
X bd = dbits;
X if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
X {
X if (i == 1 && !qflag) {
X FPRINTF(stderr, "(incomplete d-tree) ");
X#ifdef PKZIP_BUG_WORKAROUND
X i = 0;
X }
X#else
X huft_free(td);
X }
X huft_free(tl);
X return i; /* incomplete code set */
X#endif
X }
X
X
X /* decompress until an end-of-block code */
X if (inflate_codes(tl, td, bl, bd))


X return 1;
X
X

X /* free the decoding tables, return */
X huft_free(tl);
X huft_free(td);


X return 0;
X}
X
X

X
Xint inflate_block(e)
Xint *e; /* last block flag */
X/* decompress an inflated block */
X{
X unsigned t; /* block type */
X register ulg b; /* bit buffer */
X register unsigned k; /* number of bits in bit buffer */
X
X
X /* make local bit buffer */
X b = bb;
X k = bk;
X
X
X /* read in last block bit */
X NEEDBITS(1)
X *e = (int)b & 1;
X DUMPBITS(1)
X
X
X /* read in block type */
X NEEDBITS(2)
X t = (unsigned)b & 3;
X DUMPBITS(2)
X
X
X /* restore the global bit buffer */
X bb = b;
X bk = k;
X
X
X /* inflate that block type */
X if (t == 2)
X return inflate_dynamic();
X if (t == 0)
X return inflate_stored();
X if (t == 1)
X return inflate_fixed();
X
X
X /* bad block type */
X return 2;
X}
X
X
X
Xint inflate()
X/* decompress an inflated entry */
X{
X int e; /* last block flag */
X int r; /* result code */
X unsigned h; /* maximum struct huft's malloc'ed */
X
X
X /* initialize window, bit buffer */
X wp = 0;
X bk = 0;
X bb = 0;
X
X
X /* decompress until the last block */
X h = 0;
X do {
X hufts = 0;
X if ((r = inflate_block(&e)) != 0)
X return r;
X if (hufts > h)
X h = hufts;
X } while (!e);
X
X
X /* flush out slide */
X FLUSH(wp);
X
X
X /* return success */
X Trace((stderr, "\n%u bytes in Huffman tables (%d/entry)\n",
X h * sizeof(struct huft), sizeof(struct huft)));


X return 0;
X}
X
X

X
Xint inflate_free()
X{
X if (fixed_tl != (struct huft *)NULL)
X {
X huft_free(fixed_td);
X huft_free(fixed_tl);
X fixed_td = fixed_tl = (struct huft *)NULL;


X }
X return 0;
X}

END_OF_FILE
if test 38275 -ne `wc -c <'unzip-5.12/inflate.c'`; then
echo shar: \"'unzip-5.12/inflate.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/inflate.c'
fi
echo shar: End of archive 9 \(of 20\).
cp /dev/null ark9isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:15:39 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 75
Archive-name: unzip/part10

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/file_io.c unzip-5.12/tops20/make.mic
# unzip-5.12/unix/unix.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:41 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 10 (of 20)."'
if test -f 'unzip-5.12/file_io.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/file_io.c'\"
else
echo shar: Extracting \"'unzip-5.12/file_io.c'\" \(35360 characters\)
sed "s/^X//" >'unzip-5.12/file_io.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X file_io.c
X
X This file contains routines for doing direct but relatively generic input/
X output, file-related sorts of things, plus some miscellaneous stuff. Most
X of the stuff has to do with opening, closing, reading and/or writing files.
X
X Contains: open_input_file()
X open_outfile() (non-VMS)
X readbuf()
X readbyte()
X flush() (non-VMS)
X disk_error() (non-VMS)
X handler()
X dos_to_unix_time() (non-VMS, non-OS/2)
X check_for_newer() (non-VMS, non-OS/2)
X find_ecrec()
X get_cdir_ent()
X do_string()
X makeword()
X makelong()
X memset() (ZMEM only)
X memcpy() (ZMEM only)
X zstrnicmp()
X zstat() (REGULUS only)
X LoadFarString() (SMALL_MEM only)
X LoadFarStringSmall() (SMALL_MEM only)
X LoadFarStringSmall2() (SMALL_MEM only)


X
X ---------------------------------------------------------------------------*/
X
X

X#define FILE_IO_C
X#include "unzip.h"
X#include "crypt.h"
X#include "tables.h" /* definition/initialization of ebcdic[] */
X
X#ifdef USE_FWRITE
X# define WriteError(buf,len,strm) \
X ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
X#else
X# define WriteError(buf,len,strm) \
X ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
X#endif
X
Xstatic int disk_error OF((void));
X
X
X
X/*****************************/
X/* Strings used in file_io.c */
X/*****************************/
X
X#ifdef UNIX
X static char Far CannotDeleteOldFile[] = "\nerror: cannot delete old %s\n";
X#endif
X
Xstatic char Far CantOpenZipfile[] = "error: can't open zipfile [ %s ]\n";
Xstatic char Far CannotCreateFile[] = "\nerror: cannot create %s\n";
Xstatic char Far ReadError[] = "error: zipfile read error\n";
Xstatic char Far DiskFull[] =
X "\n%s: write error (disk full?). Continue? (y/n/^C) ";
Xstatic char Far ZipfileCorrupt[] = "error: zipfile probably corrupt (%s)\n";
Xstatic char Far CentDirEndSigNotFound[] = "\
X End-of-central-directory signature not found. Either this file is not\n\
X a zipfile, or it constitutes one disk of a multi-part archive. In the\n\
X latter case the central directory and zipfile comment will be found on\n\
X the last disk(s) of this archive.\n";
Xstatic char Far FilenameTooLongTrunc[] =
X "warning: filename too long--truncating.\n";
Xstatic char Far ExtraFieldTooLong[] =
X "warning: extra field too long (%d). Ignoring...\n";


X
X
X
X
X

X/******************************/
X/* Function open_input_file() */
X/******************************/
X
Xint open_input_file() /* return 1 if open failed */
X{
X /*
X * open the zipfile for reading and in BINARY mode to prevent cr/lf
X * translation, which would corrupt the bitstreams
X */
X
X#if defined(UNIX) || defined(TOPS20) || defined(ATARI_ST)
X zipfd = open(zipfn, O_RDONLY);
X#else /* !(UNIX || TOPS20) */
X#ifdef VMS
X zipfd = open(zipfn, O_RDONLY, 0, "ctx=stm");
X#else /* !VMS */
X#ifdef MACOS
X zipfd = open(zipfn, 0);
X#else /* !MACOS */
X zipfd = open(zipfn, O_RDONLY | O_BINARY);
X#endif /* ?MACOS */
X#endif /* ?VMS */
X#endif /* ?(UNIX || TOPS20) */
X if (zipfd < 0) {
X FPRINTF(stderr, LoadFarString(CantOpenZipfile), zipfn);
X return 1;
X }
X return 0;
X
X} /* end function open_input_file() */
X
X
X
X
X#ifndef VMS /* for VMS use code in vms.c */
X
X/***************************/
X/* Function open_outfile() */
X/***************************/
X
Xint open_outfile() /* return 1 if fail */
X{
X#ifdef DOS_NT_OS2
X if (stat(filename, &statbuf) == 0 && !(statbuf.st_mode & S_IWRITE))
X chmod(filename, S_IREAD | S_IWRITE);
X#endif
X#ifdef UNIX
X if (stat(filename, &statbuf) == 0 && unlink(filename) < 0) {
X FPRINTF(stderr, LoadFarString(CannotDeleteOldFile), filename);
X return 1;
X }
X#endif
X#ifdef TOPS20
X char *tfilnam;
X
X if ((tfilnam = (char *)malloc(2*strlen(filename)+1)) == (char *)NULL)
X return 1;
X strcpy(tfilnam, filename);
X upper(tfilnam);
X enquote(tfilnam);
X if ((outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
X FPRINTF(stderr, LoadFarString(CannotCreateFile), tfilnam);
X free(tfilnam);
X return 1;
X }
X free(tfilnam);
X#else
X#ifdef MTS
X if (aflag)
X outfile = fopen(filename, FOPWT);
X else
X outfile = fopen(filename, FOPW);
X if (outfile == (FILE *)NULL) {
X FPRINTF(stderr, LoadFarString(CannotCreateFile), filename);
X return 1;
X }
X#else
X if ((outfile = fopen(filename, FOPW)) == (FILE *)NULL) {
X FPRINTF(stderr, LoadFarString(CannotCreateFile), filename);
X return 1;
X }
X#endif
X#endif
X
X#if 0 /* this SUCKS! on Ultrix, it must be writing a byte at a time... */
X setbuf(outfile, (char *)NULL); /* make output unbuffered */
X#endif
X
X#ifdef USE_FWRITE
X#ifdef DOS_NT_OS2
X /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE): bogus */
X setbuf(outfile, (char *)NULL); /* make output unbuffered */
X#else /* !DOS_NT_OS2 */
X#ifdef _IOFBF /* make output fully buffered (works just about like write()) */
X setvbuf(outfile, (char *)slide, _IOFBF, WSIZE);
X#else
X setbuf(outfile, (char *)slide);
X#endif
X#endif /* ?DOS_NT_OS2 */
X#endif /* USE_FWRITE */
X return 0;
X
X} /* end function open_outfile() */
X
X#endif /* !VMS */


X
X
X
X
X

X/**********************/
X/* Function readbuf() */
X/**********************/
X
Xunsigned readbuf(buf, size) /* return number of bytes read into buf */
X char *buf;
X register unsigned size;
X{
X register unsigned count;
X unsigned n;
X
X n = size;
X while (size) {
X if (incnt == 0) {
X#ifdef OLD_READBUF
X if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
X return (n-size);
X#else
X if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) == 0)
X return (n-size);
X else if (incnt < 0) {
X FPRINTF(stderr, LoadFarString(ReadError));
X return 0; /* discarding some data; better than lock-up */
X }
X#endif
X /* buffer ALWAYS starts on a block boundary: */
X cur_zipfile_bufstart += INBUFSIZ;


X inptr = inbuf;
X }

X count = MIN(size, (unsigned)incnt);
X memcpy(buf, inptr, count);
X buf += count;
X inptr += count;
X incnt -= count;
X size -= count;
X }
X return n;
X
X} /* end function readbuf() */


X
X
X
X
X

X/***********************/
X/* Function readbyte() */
X/***********************/
X
Xint readbyte() /* refill inbuf and return a byte if available, else EOF */
X{
X if (mem_mode || (incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) <= 0)
X return EOF;
X cur_zipfile_bufstart += INBUFSIZ; /* always starts on a block boundary */
X inptr = inbuf;
X
X#ifdef CRYPT
X if (pInfo->encrypted) {
X uch *p;
X int n;
X
X for (n = (long)incnt > csize + 1 ? (int)csize + 1 : incnt,
X p = inptr; n--; p++)
X zdecode(*p);


X }
X#endif /* CRYPT */
X

X --incnt;
X return *inptr++;
X
X} /* end function readbyte() */


X
X
X
X
X

X#ifndef VMS /* for VMS use code in vms.c */
X
X/********************/
X/* Function flush() */
X/********************/
X
Xint flush(rawbuf, size, unshrink) /* cflag => always 0; 50 if write error */


X uch *rawbuf;
X ulg size;
X int unshrink;
X{

X#ifdef ASM_CRC
X ulg CalcCRC(ulg *crc_table, ulg crcval, uch *rawbuf, ulg rawbufsize);
X#else
X register ulg crcval = crc32val;
X register ulg n = size;
X#endif
X register uch *p, *q;
X uch *transbuf;
X ulg transbufsiz;
X static int didCRlast = FALSE;
X
X
X/*---------------------------------------------------------------------------
X Compute the CRC first; if testing or if disk is full, that's it.
X ---------------------------------------------------------------------------*/
X
X#ifdef ASM_CRC
X crc32val = CalcCRC(crc_32_tab, crc32val, rawbuf, size);
X#else
X p = rawbuf;


X while (n--)
X crcval = crc_32_tab[((uch)crcval ^ (*p++)) & 0xff] ^ (crcval >> 8);

X crc32val = crcval;
X#endif /* ?ASM_CRC */
X
X if (tflag || size == 0L) /* testing or nothing to write: all done */
X return 0;
X
X if (disk_full)
X return 50; /* disk already full: ignore rest of file */
X
X/*---------------------------------------------------------------------------
X Write the bytes rawbuf[0..size-1] to the output device, first converting
X end-of-lines and ASCII/EBCDIC as needed. If SMALL_MEM or MED_MEM are NOT
X defined, outbuf is assumed to be at least as large as rawbuf and is not
X necessarily checked for overflow.
X ---------------------------------------------------------------------------*/
X
X if (!pInfo->textmode) {
X /* GRR: note that for standard MS-DOS compilers, size argument to
X * fwrite() can never be more than 65534, so WriteError macro will
X * have to be rewritten if size can ever be that large. For now,
X * never more than 32K. Also note that write() returns an int, which
X * doesn't necessarily limit size to 32767 bytes if write() is used
X * on 16-bit systems but does make it more of a pain; however, because
X * at least MSC 5.1 has a lousy implementation of fwrite() (as does
X * DEC Ultrix cc), write() is used anyway.
X */
X if (WriteError(rawbuf, size, outfile)) /* write raw binary data */
X return cflag? 0 : disk_error();
X } else {
X if (unshrink) {
X /* rawbuf = outbuf */
X transbuf = outbuf2;
X transbufsiz = TRANSBUFSIZ;
X } else {
X /* rawbuf = slide */
X transbuf = outbuf;
X transbufsiz = OUTBUFSIZ;
X Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n", OUTBUFSIZ));
X }
X if (newfile) {
X didCRlast = FALSE; /* no previous buffers written */
X newfile = FALSE;
X }
X p = rawbuf;
X if (*p == LF && didCRlast)
X ++p;
X
X /*-----------------------------------------------------------------------
X Algorithm: CR/LF => native; lone CR => native; lone LF => native.
X This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
X stream-oriented files, not record-oriented).
X -----------------------------------------------------------------------*/
X
X for (didCRlast = FALSE, q = transbuf; p < rawbuf+size; ++p) {
X if (*p == CR) { /* lone CR or CR/LF: EOL either way */
X PutNativeEOL
X if (p == rawbuf+size-1) /* last char in buffer */
X didCRlast = TRUE;
X else if (p[1] == LF) /* get rid of accompanying LF */
X ++p;
X } else if (*p == LF) /* lone LF */
X PutNativeEOL
X else
X#ifndef DOS_NT_OS2
X if (*p != CTRLZ) /* lose all ^Z's */
X#endif
X *q++ = native(*p);
X
X#if (defined(SMALL_MEM) || defined(MED_MEM))
X# if (lenEOL == 1) /* don't check unshrink: both buffers small but equal */
X if (!unshrink)
X# endif
X /* check for danger of buffer overflow and flush */
X if (q > transbuf+transbufsiz-lenEOL) {
X Trace((stderr,
X "p - rawbuf = %u q-transbuf = %u size = %lu\n",
X (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
X if (WriteError(transbuf, (unsigned)(q-transbuf), outfile))
X return cflag? 0 : disk_error();
X q = transbuf;
X continue;
X }
X#endif /* SMALL_MEM || MED_MEM */
X }
X
X /*-----------------------------------------------------------------------
X Done translating: write whatever we've got to file.
X -----------------------------------------------------------------------*/
X
X Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n",
X (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
X if (q > transbuf &&
X WriteError(transbuf, (unsigned)(q-transbuf), outfile))
X return cflag? 0 : disk_error();
X }


X
X return 0;
X

X} /* end function flush() */


X
X
X
X
X

X/*************************/
X/* Function disk_error() */
X/*************************/
X
Xstatic int disk_error()
X{
X FPRINTF(stderr, LoadFarString(DiskFull), filename);
X FFLUSH(stderr);
X
X#ifndef MSWIN
X fgets(answerbuf, 9, stdin);
X if (*answerbuf == 'y') /* stop writing to this file */
X disk_full = 1; /* (outfile bad?), but new OK */
X else
X#endif
X disk_full = 2; /* no: exit program */
X
X return 50; /* 50: disk full */
X
X} /* end function disk_error() */
X
X#endif /* !VMS */


X
X
X
X
X

X/**********************/
X/* Function handler() */
X/**********************/
X
Xvoid handler(signal) /* upon interrupt, turn on echo and exit cleanly */
X int signal;
X{
X#if defined(SIGBUS) || defined(SIGSEGV)
X# ifdef SMALL_MEM
X static char *corrupt;
X corrupt = LoadFarString(ZipfileCorrupt);
X# else
X static char *corrupt = LoadFarString(ZipfileCorrupt);
X# endif
X#endif
X
X#if !defined(DOS_NT_OS2) && !defined(MACOS)
X echon();
X PUTC('\n', stderr);
X#endif /* !DOS_NT_OS2 && !MACOS */
X#ifdef SIGBUS
X if (signal == SIGBUS) {
X FPRINTF(stderr, corrupt, "bus error");
X exit(3);
X }
X#endif /* SIGBUS */
X#ifdef SIGSEGV
X if (signal == SIGSEGV) {
X FPRINTF(stderr, corrupt, "segmentation violation");
X exit(3);
X }
X#endif /* SIGSEGV */
X exit(0);


X}
X
X
X
X
X

X#ifdef DEBUG_TIME
X# define TTrace(x) FPRINTF x
X#else
X# define TTrace(x)
X#endif
X
X#if !defined(VMS) && !defined(OS2)
X
X/*******************************/
X/* Function dos_to_unix_time() */ /* only used for freshening/updating */
X/*******************************/
X
Xtime_t dos_to_unix_time(ddate, dtime)
X unsigned ddate, dtime;
X{
X int yr, mo, dy, hh, mm, ss;
X#ifdef TOPS20
X# define YRBASE 1900
X struct tmx *tmx;
X char temp[20];
X time_t retval;
X#else /* !TOPS20 */
X# define YRBASE 1970
X static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
X int leap;
X long m_time, days=0;
X#if (!defined(MACOS) && !defined(MSC))
X#if (defined(BSD) || defined(MTS) || defined(__GO32__))
X#ifndef BSD4_4
X static struct timeb tbp;
X#endif /* !BSD4_4 */
X#else /* !(BSD || MTS || __GO32__) */
X#ifdef ATARI_ST
X extern long _timezone;
X# define timezone _timezone; /* a whoops in our library... */
X#else /* !ATARI_ST */
X extern long timezone; /* declared in <time.h> for MSC (& Borland?) */
X#endif /* ?ATARI_ST */
X#endif /* ?(BSD || MTS || __GO32__) */
X#endif /* !MACOS && !MSC */
X#endif /* ?TOPS20 */
X
X
X /* dissect date */
X yr = ((ddate >> 9) & 0x7f) + (1980 - YRBASE);
X mo = ((ddate >> 5) & 0x0f) - 1;
X dy = (ddate & 0x1f) - 1;
X
X /* dissect time */
X hh = (dtime >> 11) & 0x1f;
X mm = (dtime >> 5) & 0x3f;
X ss = (dtime & 0x1f) * 2;
X
X#ifdef TOPS20
X tmx = (struct tmx *)malloc(sizeof(struct tmx));
X sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
X time_parse(temp, tmx, (char *)0);
X retval = time_make(tmx);
X free(tmx);
X return retval;
X
X#else /* !TOPS20 */
X /* leap = # of leap years from BASE up to but not including current year */
X leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
X
X /* calculate days from BASE to this year and add expired days this year */
X days = (yr * 365) + (leap - 492) + yday[mo];
X
X /* if year is a leap year and month is after February, add another day */
X if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
X ++days; /* OK through 2199 */
X
X /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
X m_time = ((long)(days + dy) * 86400L) + ((long)hh * 3600) + (mm * 60) + ss;
X /* - 1; MS-DOS times always rounded up to nearest even second */
X TTrace((stderr, "dos_to_unix_time:\n"));
X TTrace((stderr, " m_time before timezone = %ld\n", m_time));
X
X#ifndef MACOS
X#if (defined(BSD) || defined(MTS) || defined(__GO32__))
X#ifndef BSD4_4
X ftime(&tbp);
X m_time += tbp.timezone * 60L;
X#endif
X#else /* !(BSD || MTS || __GO32__) */
X#ifdef WIN32
X {
X TIME_ZONE_INFORMATION tzinfo;
X DWORD res;
X
X /* account for timezone differences */
X res = GetTimeZoneInformation(&tzinfo);
X if (res == TIME_ZONE_ID_STANDARD)
X m_time += 60*(tzinfo.Bias + tzinfo.StandardBias);
X else if (res == TIME_ZONE_ID_DAYLIGHT)
X m_time += 60*(tzinfo.Bias + tzinfo.DaylightBias);
X /* GRR: are other return-values possible? */
X }
X#else /* !WIN32 */
X tzset(); /* set `timezone' variable */
X m_time += timezone;
X#endif /* ?WIN32 */
X#endif /* ?(BSD || MTS || __GO32__) */
X#endif /* !MACOS */
X TTrace((stderr, " m_time after timezone = %ld\n", m_time));
X
X#ifdef BSD4_4 /* see comments in unix.c */
X m_time -= localtime((time_t *) &m_time)->tm_gmtoff;
X#else /* !BSD4_4 */
X#ifndef WIN32
X if (localtime((time_t *)&m_time)->tm_isdst)
X m_time -= 60L * 60L; /* adjust for daylight savings time */
X#endif /* !WIN32 */
X#endif /* ?BSD4_4 */
X TTrace((stderr, " m_time after DST = %ld\n", m_time));
X
X return m_time;
X#endif /* ?TOPS20 */
X
X} /* end function dos_to_unix_time() */


X
X
X
X
X

X/******************************/
X/* Function check_for_newer() */ /* only used for freshening/updating */


X/******************************/
X
Xint check_for_newer(filename) /* return 1 if existing file newer or equal; */
X char *filename; /* 0 if older; -1 if doesn't exist yet */
X{

X time_t existing, archive;
X


X if (stat(filename, &statbuf))
X return DOES_NOT_EXIST;
X

X /* round up existing filetime to nearest 2 seconds for comparison */
X existing = (statbuf.st_mtime & 1) ? statbuf.st_mtime+1 : statbuf.st_mtime;
X archive = dos_to_unix_time(lrec.last_mod_file_date,
X lrec.last_mod_file_time);
X
X TTrace((stderr, "check_for_newer: existing %ld, archive %ld, e-a %ld\n",
X existing, archive, existing-archive));


X
X return (existing >= archive);

X
X} /* end function check_for_newer() */
X
X#endif /* !VMS && !OS2 */


X
X
X
X
X

X/*************************/
X/* Function find_ecrec() */
X/*************************/
X
Xint find_ecrec(searchlen) /* return PK-class error */
X long searchlen;
X{
X int i, numblks, found=FALSE;
X LONGINT tail_len;
X ec_byte_rec byterec;
X
X
X/*---------------------------------------------------------------------------
X Treat case of short zipfile separately.
X ---------------------------------------------------------------------------*/
X
X if (ziplen <= INBUFSIZ) {
X lseek(zipfd, 0L, SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)ziplen)) ==
X (int)ziplen)
X
X /* 'P' must be at least 22 bytes from end of zipfile */
X for (inptr = inbuf+(int)ziplen-22; inptr >= inbuf; --inptr)
X if ((native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) {
X incnt -= inptr - inbuf;
X found = TRUE;
X break;
X }
X
X/*---------------------------------------------------------------------------
X Zipfile is longer than INBUFSIZ: may need to loop. Start with short
X block at end of zipfile (if not TOO short).
X ---------------------------------------------------------------------------*/
X
X } else {
X if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) {
X cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) !=
X (int)tail_len)
X goto fail; /* shut up; it's expedient */
X
X /* 'P' must be at least 22 bytes from end of zipfile */
X for (inptr = inbuf+(int)tail_len-22; inptr >= inbuf; --inptr)
X if ((native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) {
X incnt -= inptr - inbuf;
X found = TRUE;
X break;
X }
X /* sig may span block boundary: */
X strncpy((char *)hold, (char *)inbuf, 3);
X } else
X cur_zipfile_bufstart = ziplen - tail_len;
X
X /*-----------------------------------------------------------------------
X Loop through blocks of zipfile data, starting at the end and going
X toward the beginning. In general, need not check whole zipfile for
X signature, but may want to do so if testing.
X -----------------------------------------------------------------------*/
X
X numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
X /* ==amount= ==done== ==rounding== =blksiz= */
X
X for (i = 1; !found && (i <= numblks); ++i) {
X cur_zipfile_bufstart -= INBUFSIZ;
X lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
X break; /* fall through and fail */
X
X for (inptr = inbuf+INBUFSIZ-1; inptr >= inbuf; --inptr)
X if ((native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) {
X incnt -= inptr - inbuf;
X found = TRUE;
X break;
X }
X /* sig may span block boundary: */
X strncpy((char *)hold, (char *)inbuf, 3);
X }
X } /* end if (ziplen > INBUFSIZ) */
X
X/*---------------------------------------------------------------------------
X Searched through whole region where signature should be without finding
X it. Print informational message and die a horrible death.
X ---------------------------------------------------------------------------*/
X
Xfail:
X if (!found) {
X#ifdef MSWIN
X MessageBeep(1);
X#endif
X if (qflag || (zipinfo_mode && !hflag))
X FPRINTF(stderr, "[%s]\n", zipfn);
X FPRINTF(stderr, LoadFarString(CentDirEndSigNotFound));
X return PK_ERR; /* failed */
X }
X
X/*---------------------------------------------------------------------------
X Found the signature, so get the end-central data before returning. Do
X any necessary machine-type conversions (byte ordering, structure padding
X compensation) by reading data into character array and copying to struct.
X ---------------------------------------------------------------------------*/
X
X real_ecrec_offset = cur_zipfile_bufstart + (inptr-inbuf);
X#ifdef TEST
X printf("\n found end-of-central-dir signature at offset %ld (%.8lXh)\n",
X real_ecrec_offset, real_ecrec_offset);
X printf(" from beginning of file; offset %d (%.4Xh) within block\n",
X inptr-inbuf, inptr-inbuf);
X#endif
X
X if (readbuf((char *)byterec, ECREC_SIZE+4) == 0)
X return PK_EOF;
X
X ecrec.number_this_disk =
X makeword(&byterec[NUMBER_THIS_DISK]);
X ecrec.num_disk_with_start_central_dir =
X makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
X ecrec.num_entries_centrl_dir_ths_disk =
X makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);
X ecrec.total_entries_central_dir =
X makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
X ecrec.size_central_directory =
X makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
X ecrec.offset_start_central_directory =
X makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
X ecrec.zipfile_comment_length =
X makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
X
X expect_ecrec_offset = ecrec.offset_start_central_directory +
X ecrec.size_central_directory;
X return PK_COOL;
X
X} /* end function find_ecrec() */


X
X
X
X
X

X/***************************/
X/* Function get_cdir_ent() */
X/***************************/
X
Xint get_cdir_ent() /* return PK-type error code */
X{
X cdir_byte_hdr byterec;
X
X
X/*---------------------------------------------------------------------------
X Read the next central directory entry and do any necessary machine-type
X conversions (byte ordering, structure padding compensation--do so by
X copying the data from the array into which it was read (byterec) to the
X usable struct (crec)).
X ---------------------------------------------------------------------------*/
X
X if (readbuf((char *)byterec, CREC_SIZE) == 0)
X return PK_EOF;
X
X crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
X crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
X crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
X crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
X
X crec.general_purpose_bit_flag =
X makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
X crec.compression_method =
X makeword(&byterec[C_COMPRESSION_METHOD]);
X crec.last_mod_file_time =
X makeword(&byterec[C_LAST_MOD_FILE_TIME]);
X crec.last_mod_file_date =
X makeword(&byterec[C_LAST_MOD_FILE_DATE]);
X crec.crc32 =
X makelong(&byterec[C_CRC32]);
X crec.csize =
X makelong(&byterec[C_COMPRESSED_SIZE]);
X crec.ucsize =
X makelong(&byterec[C_UNCOMPRESSED_SIZE]);
X crec.filename_length =
X makeword(&byterec[C_FILENAME_LENGTH]);
X crec.extra_field_length =
X makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
X crec.file_comment_length =
X makeword(&byterec[C_FILE_COMMENT_LENGTH]);
X crec.disk_number_start =
X makeword(&byterec[C_DISK_NUMBER_START]);
X crec.internal_file_attributes =
X makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
X crec.external_file_attributes =
X makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
X crec.relative_offset_local_header =
X makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
X
X return PK_COOL;
X
X} /* end function get_cdir_ent() */


X
X
X
X
X

X/************************/
X/* Function do_string() */
X/************************/
X
Xint do_string(len, option) /* return PK-type error code */
X unsigned int len; /* without prototype, ush converted to this */
X int option;
X{
X long comment_bytes_left, block_length;
X int error=PK_OK;
X ush extra_len;
X
X
X/*---------------------------------------------------------------------------
X This function processes arbitrary-length (well, usually) strings. Three
X options are allowed: SKIP, wherein the string is skipped (pretty logical,
X eh?); DISPLAY, wherein the string is printed to standard output after un-
X dergoing any necessary or unnecessary character conversions; and FILENAME,
X wherein the string is put into the filename[] array after undergoing ap-
X propriate conversions (including case-conversion, if that is indicated:
X see the global variable pInfo->lcflag). The latter option should be OK,
X since filename is now dimensioned at 1025, but we check anyway.
X
X The string, by the way, is assumed to start at the current file-pointer
X position; its length is given by len. So start off by checking length
X of string: if zero, we're already done.
X ---------------------------------------------------------------------------*/
X
X if (!len)
X return PK_COOL;
X
X switch (option) {
X
X /*
X * First case: print string on standard output. First set loop vari-
X * ables, then loop through the comment in chunks of OUTBUFSIZ bytes,
X * converting formats and printing as we go. The second half of the
X * loop conditional was added because the file might be truncated, in
X * which case comment_bytes_left will remain at some non-zero value for
X * all time. outbuf and slide are used as scratch buffers because they
X * are available (we should be either before or in between any file pro-
X * cessing).
X */
X
X case DISPLAY:
X comment_bytes_left = len;
X block_length = OUTBUFSIZ; /* for the while statement, first time */
X while (comment_bytes_left > 0 && block_length > 0) {
X#ifndef MSWIN
X register uch *p = outbuf;
X register uch *q = outbuf;
X#endif
X if ((block_length = readbuf((char *)outbuf,
X (unsigned) MIN((long)OUTBUFSIZ, comment_bytes_left))) == 0)
X return PK_EOF;
X comment_bytes_left -= block_length;
X
X /* this is why we allocated an extra byte for outbuf: */
X outbuf[block_length] = '\0'; /* terminate w/zero: ASCIIZ */
X
X /* remove all ASCII carriage returns comment before printing
X * (since used before A_TO_N(), check for CR instead of '\r')
X */
X while (*p) {
X while (*p == CR)
X ++p;


X *q++ = *p++;
X }

X /* could check whether (p - outbuf) == block_length here */


X *q = '\0';
X

X A_TO_N(outbuf); /* translate string to native */
X
X#ifdef MSWIN
X /* ran out of local mem -- had to cheat */
X WriteStringToMsgWin(outbuf, bRealTimeMsgUpdate);
X#else /* !MSWIN */
X#ifdef NATIVE
X PRINTF("%s", outbuf); /* GRR: can ANSI be used with EBCDIC? */
X#else /* ASCII */
X p = outbuf - 1;
X q = slide;
X while (*++p) {
X if (*p == 0x1B) { /* ASCII escape char */
X *q++ = '^';
X *q++ = '[';
X } else
X *q++ = *p;
X if ((unsigned)(q-slide) > WSIZE-3) { /* time to flush */
X *q = '\0';
X PRINTF("%s", slide);
X q = slide;
X }


X }
X *q = '\0';

X PRINTF("%s", slide);
X#endif /* ?NATIVE */


X#endif /* ?MSWIN */
X }

X PRINTF("\n"); /* assume no newline at end */


X break;
X
X /*

X * Second case: read string into filename[] array. The filename should
X * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
X * just to be sure.
X */
X
X case FILENAME:
X extra_len = 0;
X if (len >= FILNAMSIZ) {
X FPRINTF(stderr, LoadFarString(FilenameTooLongTrunc));
X error = PK_WARN;
X extra_len = len - FILNAMSIZ + 1;
X len = FILNAMSIZ - 1;
X }
X if (readbuf(filename, len) == 0)
X return PK_EOF;
X filename[len] = '\0'; /* terminate w/zero: ASCIIZ */
X
X A_TO_N(filename); /* translate string to native */
X
X if (pInfo->lcflag) /* replace with lowercase filename */
X TOLOWER(filename, filename);
X
X if (pInfo->vollabel && len > 8 && filename[8] == '.') {
X char *p = filename+8;
X while (*p++)
X p[-1] = *p; /* disk label, and 8th char is dot: remove dot */
X }
X
X if (!extra_len) /* we're done here */


X break;
X
X /*

X * We truncated the filename, so print what's left and then fall
X * through to the SKIP routine.
X */
X FPRINTF(stderr, "[ %s ]\n", filename);
X len = extra_len;
X /* FALL THROUGH... */
X
X /*
X * Third case: skip string, adjusting readbuf's internal variables
X * as necessary (and possibly skipping to and reading a new block of
X * data).
X */
X
X case SKIP:
X LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)


X break;
X
X /*

X * Fourth case: assume we're at the start of an "extra field"; malloc
X * storage for it and read data into the allocated space.
X */
X
X case EXTRA_FIELD:


X if (extra_field != (uch *)NULL)
X free(extra_field);

X if ((extra_field = (uch *)malloc(len)) == (uch *)NULL) {
X FPRINTF(stderr, LoadFarString(ExtraFieldTooLong), len);
X LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
X } else
X if (readbuf((char *)extra_field, len) == 0)
X return PK_EOF;
X break;
X
X } /* end switch (option) */
X return error;
X
X} /* end function do_string() */


X
X
X
X
X

X/***********************/
X/* Function makeword() */
X/***********************/
X
Xush makeword(b)
X uch *b;
X{
X /*
X * Convert Intel style 'short' integer to non-Intel non-16-bit
X * host format. This routine also takes care of byte-ordering.
X */
X return (ush)((b[1] << 8) | b[0]);


X}
X
X
X
X
X

X/***********************/
X/* Function makelong() */
X/***********************/
X
Xulg makelong(sig)
X uch *sig;
X{
X /*
X * Convert intel style 'long' variable to non-Intel non-16-bit
X * host format. This routine also takes care of byte-ordering.
X */
X return (((ulg)sig[3]) << 24)
X + (((ulg)sig[2]) << 16)
X + (((ulg)sig[1]) << 8)
X + ((ulg)sig[0]);


X}
X
X
X
X
X

X#ifdef ZMEM /* memset, memcpy for systems without them */
X
X/*********************/
X/* Function memset() */
X/*********************/
X
Xchar *memset(buf, init, len)
X register char *buf, init; /* buffer loc and initializer */
X register unsigned int len; /* length of the buffer */
X{
X char *start;
X
X start = buf;
X while (len--)
X *(buf++) = init;
X return start;


X}
X
X
X
X
X

X/*********************/
X/* Function memcpy() */
X/*********************/
X
Xchar *memcpy(dst, src, len)
X register char *dst, *src;
X register unsigned int len;
X{
X char *start;
X
X start = dst;
X while (len-- > 0)
X *dst++ = *src++;
X return start;
X}
X
X#endif /* ZMEM */


X
X
X
X
X

X/************************/
X/* Function zstrnicmp() */
X/************************/
X
Xint zstrnicmp(s1, s2, n)
X register char *s1, *s2;
X register int n;
X{
X for (; n > 0; --n, ++s1, ++s2) {
X
X if (ToLower(*s1) != ToLower(*s2))
X /* test includes early termination of one string */
X return (ToLower(*s1) < ToLower(*s2))? -1 : 1;
X
X if (*s1 == '\0') /* both strings terminate early */
X return 0;
X }
X return 0;


X}
X
X
X
X
X

X#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */

X# undef stat
X
X/********************/
X/* Function zstat() */
X/********************/
X
Xint zstat(p, s)
X char *p;
X struct stat *s;
X{
X return (stat(p,s) >= 0? 0 : (-1));
X}
X
X#endif /* REGULUS */


X
X
X
X
X

X#ifdef SMALL_MEM
X
Xchar rgchBigBuffer[512];
Xchar rgchSmallBuffer[96];
Xchar rgchSmallBuffer2[96];
X
X/******************************/
X/* Function LoadFarString() */ /* (and friends...) */
X/******************************/
X
Xchar *LoadFarString(char Far *sz)
X{
X (void)zfstrcpy(rgchBigBuffer, sz);
X return rgchBigBuffer;
X}
X
Xchar *LoadFarStringSmall(char Far *sz)
X{
X (void)zfstrcpy(rgchSmallBuffer, sz);
X return rgchSmallBuffer;
X}
X
Xchar *LoadFarStringSmall2(char Far *sz)
X{
X (void)zfstrcpy(rgchSmallBuffer2, sz);
X return rgchSmallBuffer2;
X}
X
X
X/*************************/
X/* Function zfstrcpy() */ /* portable clone of _fstrcpy() */
X/*************************/
X
Xchar Far * Far zfstrcpy(char Far *s1, const char Far *s2)
X{
X char Far *p = s1;
X
X while ((*s1++ = *s2++) != '\0');
X return p;
X}
X
X#endif /* SMALL_MEM */
END_OF_FILE
if test 35360 -ne `wc -c <'unzip-5.12/file_io.c'`; then
echo shar: \"'unzip-5.12/file_io.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/file_io.c'
fi
if test -f 'unzip-5.12/tops20/make.mic' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/tops20/make.mic'\"
else
echo shar: Extracting \"'unzip-5.12/tops20/make.mic'\" \(369 characters\)
sed "s/^X//" >'unzip-5.12/tops20/make.mic' <<'END_OF_FILE'
X@te no pau e
X@cc -c -q unzip
X@cc -c -q crypt
X@cc -c -q envarg
X@cc -c -q explod
X@cc -c -q extrac
X@cc -c -q fileio
X@cc -c -q inflat
X@cc -c -q match
X@cc -c -q unredu
X@cc -c -q unshri
X@cc -c -q zipinf
X@cc -c -q tops20
X@cc -o unzip unzip.rel crypt.rel envarg.rel explod.rel extrac.rel fileio.rel inflat.rel match.rel unredu.rel unshri.rel zipinf.rel tops20.rel -ltmx
X@kmic
END_OF_FILE
if test 369 -ne `wc -c <'unzip-5.12/tops20/make.mic'`; then
echo shar: \"'unzip-5.12/tops20/make.mic'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/tops20/make.mic'
fi
if test -f 'unzip-5.12/unix/unix.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/unix.c'\"
else
echo shar: Extracting \"'unzip-5.12/unix/unix.c'\" \(30753 characters\)
sed "s/^X//" >'unzip-5.12/unix/unix.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X unix.c
X
X Unix-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X Contains: readdir()
X do_wild() <-- generic enough to put in file_io.c?


X mapattr()
X mapname()
X checkdir()

X mkdir()
X close_outfile()
X version()


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
X
X/* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
X#if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
X# define DIRENT
X#endif
X#if defined(_AIX)
X# define DIRENT
X#endif
X#ifdef COHERENT
X# if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
X# define DIRENT
X# endif
X#endif
X
X/* GRR: may need to uncomment one or both of these for the relevant systems */
X
X#if 0
X#if defined(_POSIX_VERSION)
X# define DIRENT
X#endif
X#endif
X
X#if 0
X#if defined(M_XENIX)
X# define SYSNDIR
X#endif
X#endif
X
X#ifdef DIRENT
X# include <dirent.h>
X#else
X# ifdef SYSV
X# ifdef SYSNDIR
X# include <sys/ndir.h>
X# else
X# include <ndir.h>
X# endif
X# else /* !SYSV */
X# ifndef NO_SYSDIR
X# include <sys/dir.h>
X# endif
X# endif /* ?SYSV */
X# ifndef dirent
X# define dirent direct
X# endif
X#endif /* ?DIRENT */


X
Xstatic int created_dir; /* used in mapname(), checkdir() */

Xstatic int renamed_fullpath; /* ditto */
X
X
X#ifndef SFX
X#ifdef NO_DIR /* for AT&T 3B1 */
X
X#define opendir(path) fopen(path,"r")
X#define closedir(dir) fclose(dir)
Xtypedef FILE DIR;
X
X/*
X * Apparently originally by Rich Salz.
X * Cleaned up and modified by James W. Birdsall.
X */
Xstruct dirent *readdir(dirp)
X DIR *dirp;
X{
X static struct dirent entry;
X
X if (dirp == NULL)
X return NULL;
X
X for (;;)
X if (fread(&entry, sizeof (struct dirent), 1, dirp) == 0)
X return (struct dirent *)NULL;
X else if (entry.d_ino)
X return &entry;
X
X} /* end function readdir() */
X
X#endif /* NO_DIR */
X
X
X/**********************/


X/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
X/**********************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{

X static DIR *dir = (DIR *)NULL;


X static char *dirname, *wildname, matchname[FILNAMSIZ];
X static int firstcall=TRUE, have_dirname, dirnamelen;
X struct dirent *file;
X

X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, '/')) == (char *)NULL) {


X dirname = ".";
X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {

X ++wildname; /* point at character after '/' */


X dirnamelen = wildname - wildspec;

X if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {


X FPRINTF(stderr, "warning: can't allocate wildcard buffers\n");
X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }
X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
X have_dirname = TRUE;
X }
X

X if ((dir = opendir(dirname)) != (DIR *)NULL) {
X while ((file = readdir(dir)) != (struct dirent *)NULL) {
X if (file->d_name[0] == '.' && wildname[0] != '.')
X continue; /* Unix: '*' and '?' do not match leading dot */
X if (match(file->d_name, wildname, 0)) { /* 0 == case sens. */


X if (have_dirname) {
X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);

X dir = (DIR *)NULL;
X }
X


X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */

X if (dir == (DIR *)NULL) {


X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X }
X
X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */

X while ((file = readdir(dir)) != (struct dirent *)NULL)


X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */

X dir = (DIR *)NULL;


X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X
X} /* end function do_wild() */
X

X#endif /* !SFX */


X
X
X
X
X

X/**********************/
X/* Function mapattr() */
X/**********************/
X

Xint mapattr()


X{
X ulg tmp = crec.external_file_attributes;
X

X switch (pInfo->hostnum) {
X case UNIX_:
X case VMS_:
X pInfo->file_attr = (unsigned)(tmp >> 16);
X return 0;
X case AMIGA_:
X tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
X pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
X break;
X /* all remaining cases: expand MSDOS read-only bit into write perms */


X case FS_FAT_:
X case FS_HPFS_:

X case FS_NTFS_:
X case MAC_:

X case ATARI_: /* (used to set = 0666) */

X case TOPS20_:
X default:

X tmp = !(tmp & 1) << 1; /* read-only bit --> write perms bits */
X pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
X break;


X } /* end switch (host-OS-created-by) */
X

X /* for originating systems with no concept of "group," "other," "system": */
X umask( (int)(tmp=umask(0)) ); /* apply mask to expanded r/w(/x) perms */
X pInfo->file_attr &= ~tmp;


X
X return 0;
X

X} /* end function mapattr() */


X
X
X
X
X

X/************************/
X/* Function mapname() */
X/************************/
X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
X{ /* 3 if error (skip file), 10 if no memory (skip file) */
X char pathcomp[FILNAMSIZ]; /* path-component buffer */

X char *pp, *cp=(char *)NULL; /* character pointers */
X char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */


X int quote = FALSE; /* flags */
X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X
X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X

X if (pInfo->vollabel)
X return IZ_VOL_LABEL; /* can't set disk volume labels in Unix */


X
X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X
X /* user gave full pathname: don't prepend rootpath */

X renamed_fullpath = (renamed && (*filename == '/'));


X
X if (checkdir((char *)NULL, INIT) == 10)
X return 10; /* initialize path buffer, unless no memory */
X
X *pathcomp = '\0'; /* initialize translation buffer */
X pp = pathcomp; /* point to translation buffer */
X if (jflag) /* junking directories */
X cp = (char *)strrchr(filename, '/');

X if (cp == (char *)NULL) /* no '/' or not junking dirs */


X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X

X while ((workch = (uch)*cp++) != 0) {
X


X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';
X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = (char *)NULL; /* leave directory semi-colons alone */


X break;
X
X case ';': /* VMS version (or DEC-20 attrib?) */
X lastsemi = pp;

X *pp++ = ';'; /* keep for now; remove VMS ";##" */
X break; /* later, if requested */
X


X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X

X#ifdef MTS
X case ' ': /* change spaces to underscore under */
X *pp++ = '_'; /* MTS; leave as spaces under Unix */
X break;
X#endif


X
X default:
X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X

X *pp = '\0'; /* done with pathcomp: terminate it */
X


X /* if not saving them, remove VMS version numbers (appended ";###") */
X if (!V_flag && lastsemi) {
X pp = lastsemi + 1;

X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp == '\0') /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X }
X
X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.
X ---------------------------------------------------------------------------*/
X
X if (filename[strlen(filename) - 1] == '/') {

X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {

X FPRINTF(stdout, " creating: %s\n", filename);


X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
X }

X return 2; /* dir existed already; don't look for data to extract */
X }
X


X if (*pathcomp == '\0') {
X FPRINTF(stderr, "mapname: conversion of %s failed\n", filename);
X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);
X

X return error;
X
X} /* end function mapname() */
X
X
X
X
X#if 0 /*========== NOTES ==========*/
X
X extract-to dir: a:path/
X buildpath: path1/path2/ ... (NULL-terminated)
X pathcomp: filename
X
X mapname():
X loop over chars in zipfile member name
X checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
X (d:/tmp/unzip/) (disk:[tmp.unzip.)
X (d:/tmp/unzip/jj/) (disk:[tmp.unzip.jj.)
X (d:/tmp/unzip/jj/temp/) (disk:[tmp.unzip.jj.temp.)
X finally add filename itself and check for existence? (could use with rename)
X (d:/tmp/unzip/jj/temp/msg.outdir) (disk:[tmp.unzip.jj.temp]msg.outdir)
X checkdir(name, COPYFREE) --> copy path to name and free space
X


X#endif /* 0 */
X

X
X
X
X/***********************/
X/* Function checkdir() */
X/***********************/
X
Xint checkdir(pathcomp, flag)
X char *pathcomp;
X int flag;
X/*

X * returns: 1 - (on APPEND_NAME) truncated filename
X * 2 - path doesn't exist, not allowed to create
X * 3 - path doesn't exist, tried to create and failed; or
X * path exists and is not a directory, but is supposed to be
X * 4 - path is too long
X * 10 - can't allocate memory for filename buffers
X */
X{
X static int rootlen = 0; /* length of rootpath */
X static char *rootpath; /* user's "extract-to" directory */

X static char *buildpath; /* full path (so far) to extracted file */
X static char *end; /* pointer to end of buildpath ('\0') */
X
X# define FN_MASK 7
X# define FUNCTION (flag & FN_MASK)
X
X
X
X/*---------------------------------------------------------------------------
X APPEND_DIR: append the path component to the path being built and check
X for its existence. If doesn't exist and we are creating directories, do
X so for this one; else signal success or error as appropriate.
X ---------------------------------------------------------------------------*/
X

X if (FUNCTION == APPEND_DIR) {

X int too_long = FALSE;
X#ifdef SHORT_NAMES
X char *old_end = end;
X#endif


X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));

X while ((*end = *pathcomp++) != '\0')
X ++end;

X#ifdef SHORT_NAMES /* path components restricted to 14 chars, typically */
X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
X *(end = old_end + FILENAME_MAX) = '\0';
X#endif


X
X /* GRR: could do better check, see if overrunning buffer as we go:

X * check end-buildpath after each append, set warning variable if
X * within 20 of FILNAMSIZ; then if var set, do careful check when


X * appending. Clear variable when begin new path. */
X

X if ((end-buildpath) > FILNAMSIZ-3) /* need '/', one-char name, '\0' */
X too_long = TRUE; /* check if extracting directory? */


X if (stat(buildpath, &statbuf)) { /* path doesn't exist */
X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpath);
X return 2; /* path doesn't exist: nothing to do */
X }

X if (too_long) {
X FPRINTF(stderr, "checkdir error: path too long: %s\n",

X buildpath);
X fflush(stderr);
X free(buildpath);


X return 4; /* no room for filenames: fatal */
X }

X if (mkdir(buildpath, 0777) == -1) { /* create the directory */


X FPRINTF(stderr, "checkdir error: can't create %s\n\

X unable to process %s.\n", buildpath, filename);


X fflush(stderr);
X free(buildpath);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {

X FPRINTF(stderr, "checkdir error: %s exists but is not directory\n\

X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path existed but wasn't dir */
X }

X if (too_long) {
X FPRINTF(stderr, "checkdir error: path too long: %s\n", buildpath);
X fflush(stderr);
X free(buildpath);


X return 4; /* no room for filenames: fatal */
X }

X *end++ = '/';
X *end = '\0';
X Trace((stderr, "buildpath now = [%s]\n", buildpath));

X return 0;
X


X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------
X GETPATH: copy full path to the string pointed at by pathcomp, and free
X buildpath.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {
X strcpy(pathcomp, buildpath);

X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
X free(buildpath);

X buildpath = end = (char *)NULL;


X return 0;
X }
X

X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {

X#ifdef SHORT_NAMES
X char *old_end = end;
X#endif


X
X Trace((stderr, "appending filename [%s]\n", pathcomp));

X while ((*end = *pathcomp++) != '\0') {
X ++end;

X#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */
X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
X *(end = old_end + FILENAME_MAX) = '\0';
X#endif


X if ((end-buildpath) >= FILNAMSIZ) {

X *--end = '\0';


X FPRINTF(stderr, "checkdir warning: path too long; truncating\n\

Xcheckdir warning: path too long; truncating\n\
X %s\n -> %s\n", filename, buildpath);
X fflush(stderr);
X return 1; /* filename truncated */
X }
X }


X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0; /* could check for existence here, prompt for new name... */
X }
X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X

X/* GRR: for VMS and TOPS-20, add up to 13 to strlen */
X


X if (FUNCTION == INIT) {
X Trace((stderr, "initializing buildpath to "));
X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+1)) ==

X (char *)NULL)


X return 10;
X if ((rootlen > 0) && !renamed_fullpath) {
X strcpy(buildpath, rootpath);
X end = buildpath + rootlen;
X } else {
X *buildpath = '\0';
X end = buildpath;
X }
X Trace((stderr, "[%s]\n", buildpath));

X return 0;
X }
X

X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line.
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));

X if (pathcomp == (char *)NULL) {
X rootlen = 0;
X return 0;
X }


X if ((rootlen = strlen(pathcomp)) > 0) {
X int had_trailing_pathsep=FALSE;
X
X if (pathcomp[rootlen-1] == '/') {
X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (rootlen > 0 && (stat(pathcomp, &statbuf) ||
X !S_ISDIR(statbuf.st_mode))) /* path does not exist */
X {
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || !had_trailing_pathsep
X#endif
X ) {
X rootlen = 0;

X return 2; /* skip (or treat as stored file) */


X }
X /* create the directory (could add loop here to scan pathcomp
X * and create more than one level, but why really necessary?) */

X if (mkdir(pathcomp, 0777) == -1) {


X FPRINTF(stderr,
X "checkdir: can't create extraction directory: %s\n",
X pathcomp);
X fflush(stderr);

X rootlen = 0; /* path didn't exist, tried to create, and */

X return 3; /* failed: file exists, or 2+ levels required */
X }
X }
X if ((rootpath = (char *)malloc(rootlen+2)) == (char *)NULL) {


X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);

X rootpath[rootlen++] = '/';
X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));
X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X
X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);

X return 0;
X }
X

X return 99; /* should never reach */
X

X} /* end function checkdir() */


X
X
X
X
X

X#ifdef NO_MKDIR
X
X/********************/
X/* Function mkdir() */
X/********************/
X
Xint mkdir(path, mode)
X char *path;
X int mode; /* ignored */
X/*
X * returns: 0 - successful
X * -1 - failed (errno not set, however)
X */
X{
X char command[FILNAMSIZ+40]; /* buffer for system() call */
X
X /* GRR 930416: added single quotes around path to avoid bug with
X * creating directories with ampersands in name; not yet tested */
X sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
X if (system(command))
X return -1;


X return 0;
X}
X

X#endif /* NO_MKDIR */


X
X
X
X
X

X#ifndef MTS


X
X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()
X{

X static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
X time_t m_time;
X int yr, mo, dy, hh, mm, ss, leap, days;
X struct utimbuf tp;
X# define YRBASE 1970
X#ifndef BSD4_4
X#ifdef BSD
X static struct timeb tbp;
X#else /* !BSD */
X extern long timezone;
X#endif /* ?BSD */
X#endif /* !BSD4_4 */
X
X
X/*---------------------------------------------------------------------------
X If symbolic links are supported, allocate a storage area, put the uncom-
X pressed "data" in it, and create the link. Since we know it's a symbolic
X link to start with, we shouldn't have to worry about overflowing unsigned
X ints with unsigned longs.
X ---------------------------------------------------------------------------*/
X
X#ifdef SYMLINKS
X if (symlnk) {
X unsigned ucsize = (unsigned)lrec.ucsize;
X char *linktarget = (char *)malloc((unsigned)lrec.ucsize+1);
X
X fclose(outfile); /* close "data" file... */
X outfile = fopen(filename, FOPR); /* ...and reopen for reading */
X if (!linktarget || (fread(linktarget, 1, ucsize, outfile) != ucsize)) {
X FPRINTF(stderr, "\nwarning: symbolic link (%s) failed\n",
X filename);
X if (linktarget)
X free(linktarget);


X fclose(outfile);
X return;
X }

X fclose(outfile); /* close "data" file for good... */
X unlink(filename); /* ...and delete it */
X linktarget[ucsize] = '\0';
X FPRINTF(stdout, "-> %s ", linktarget);
X if (symlink(linktarget, filename)) /* create the real link */
X perror("symlink error");
X free(linktarget);
X return; /* can't set time on symlinks */
X }
X#endif /* SYMLINKS */
X
X fclose(outfile);
X
X/*---------------------------------------------------------------------------
X Change the file permissions from default ones to those stored in the
X zipfile.
X ---------------------------------------------------------------------------*/
X
X#ifndef NO_CHMOD
X if (chmod(filename, 0xffff & pInfo->file_attr))
X perror("chmod (file attributes) error");
X#endif
X
X/*---------------------------------------------------------------------------
X Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
X time: adjust base year from 1980 to 1970, do usual conversions from
X yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
X light savings time differences.
X ---------------------------------------------------------------------------*/
X
X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);


X mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;

X dy = (lrec.last_mod_file_date & 0x1f) - 1;
X hh = (lrec.last_mod_file_time >> 11) & 0x1f;
X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
X ss = (lrec.last_mod_file_time & 0x1f) * 2;
X
X /* leap = # of leap yrs from YRBASE up to but not including current year */
X leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
X
X /* how many days from YRBASE to this year? (& add expired days this year) */
X days = (yr * 365) + (leap - 492) + yday[mo];
X
X /* if year is a leap year and month is after February, add another day */
X if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
X ++days; /* OK through 2199 */
X
X /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
X m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
X
X /* adjust for local timezone */
X#ifdef BSD
X#ifdef BSD4_4
X m_time -= localtime(&m_time)->tm_gmtoff; /* seconds EAST of GMT: subtr. */
X#else
X ftime(&tbp); /* get `timezone' */
X m_time += tbp.timezone * 60L; /* seconds WEST of GMT: add */
X#endif /* ?BSD4_4 */
X#else /* !BSD */
X tzset(); /* get `timezone' */
X m_time += timezone; /* seconds WEST of GMT: add */
X#endif /* ?BSD */
X
X /* adjust for daylight savings time (or local equivalent) */
X#ifndef BSD4_4 /* (DST already added to tm_gmtoff, so skip tm_isdst) */
X if (localtime(&m_time)->tm_isdst)
X m_time -= 60L * 60L; /* adjust for daylight savings time */
X#endif
X
X /* set the file's access and modification times */
X tp.actime = tp.modtime = m_time;
X if (utime(filename, &tp)) {
X#ifdef AOS_VS
X FPRINTF(stderr, "... can't set time for %s", filename);
X#else
X FPRINTF(stderr, "warning: can't set the time for %s\n", filename);
X#endif
X FFLUSH(stderr);
X }


X
X} /* end function close_outfile() */
X

X#endif /* !MTS */
X
X
X
X


X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if defined(CRAY) || defined(NetBSD)
X char buf1[40];
X#if defined(CRAY)
X char buf2[40];
X#endif


X#endif
X
X PRINTF(LoadFarString(CompiledWith),
X

X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else

X# if defined(CRAY) && defined(_RELEASE)
X "cc ", (sprintf(buf1, "version %d", _RELEASE), buf1),
X# else
X# ifdef __VERSION__
X "cc ", __VERSION__,
X# else
X "cc", "",
X# endif
X# endif
X#endif
X
X "Unix",
X
X#if defined(sgi) || defined(__sgi)
X " (Silicon Graphics IRIX)",
X#else
X#ifdef sun
X# ifdef sparc
X# ifdef __SVR4
X " (Sun Sparc/Solaris)",
X# else /* may or may not be SunOS */
X " (Sun Sparc)",
X# endif
X# else
X# if defined(sun386) || defined(i386)
X " (Sun 386i)",
X# else
X# if defined(mc68020) || defined(__mc68020__)
X " (Sun 3)",
X# else /* mc68010 or mc68000: Sun 2 or earlier */
X " (Sun 2)",


X# endif
X# endif
X# endif

X#else
X#ifdef __hpux
X " (HP/UX)",
X#else
X#ifdef __osf__
X " (DEC OSF/1)",
X#else
X#ifdef _AIX
X " (IBM AIX)",
X#else
X#ifdef aiws
X " (IBM RT/AIX)",
X#else
X#if defined(CRAY) || defined(cray)
X# ifdef _UNICOS
X (sprintf(buf2, " (Cray UNICOS release %d)", _UNICOS), buf2),
X# else
X " (Cray UNICOS)",
X# endif
X#else
X#if defined(uts) || defined(UTS)
X " (Amdahl UTS)",
X#else
X#ifdef NeXT
X# ifdef mc68000
X " (NeXTStep/black)",
X# else
X " (NeXTStep for Intel)",
X# endif
X#else /* the next dozen or so are somewhat order-dependent */
X#ifdef LINUX
X " (Linux)",
X#else
X#ifdef MINIX
X " (Minix)",
X#else
X#ifdef M_UNIX
X " (SCO Unix)",
X#else
X#ifdef M_XENIX
X " (SCO Xenix)",
X#else
X#ifdef __NetBSD__
X# ifdef NetBSD0_8
X (sprintf(buf1, " (NetBSD 0.8%c)", (char)(NetBSD0_8 - 1 + 'A')), buf1),
X# else
X# ifdef NetBSD0_9
X (sprintf(buf1, " (NetBSD 0.9%c)", (char)(NetBSD0_9 - 1 + 'A')), buf1),
X# else
X# ifdef NetBSD1_0
X (sprintf(buf1, " (NetBSD 1.0%c)", (char)(NetBSD1_0 - 1 + 'A')), buf1),
X# else
X (BSD4_4 == 0.5)? " (NetBSD before 0.9)" : " (NetBSD 1.1 or later)",


X# endif
X# endif
X# endif

X#else
X#ifdef __FreeBSD__
X (BSD4_4 == 0.5)? " (FreeBSD 1.x)" : " (FreeBSD 2.0 or later)",
X#else
X#ifdef __bsdi__
X (BSD4_4 == 0.5)? " (BSD/386 1.0)" : " (BSD/386 1.1 or later)",
X#else
X#ifdef __386BSD__
X (BSD4_4 == 1)? " (386BSD, post-4.4 release)" : " (386BSD)",
X#else
X#if defined(i486) || defined(__i486) || defined(__i486__)
X " (Intel 486)",
X#else
X#if defined(i386) || defined(__i386) || defined(__i386__)
X " (Intel 386)",
X#else
X#ifdef pyr
X " (Pyramid)",
X#else
X#ifdef ultrix
X# ifdef mips
X " (DEC/MIPS)",
X# else
X# ifdef vax
X " (DEC/VAX)",
X# else /* __alpha? */
X " (DEC/Alpha)",
X# endif
X# endif
X#else
X#ifdef gould
X " (Gould)",
X#else
X#ifdef MTS
X " (MTS)",
X#else
X#ifdef __convexc__
X " (Convex)",
X#else
X "",
X#endif /* Convex */
X#endif /* MTS */
X#endif /* Gould */
X#endif /* DEC */
X#endif /* Pyramid */
X#endif /* 386 */
X#endif /* 486 */
X#endif /* 386BSD */
X#endif /* BSDI BSD/386 */
X#endif /* NetBSD */
X#endif /* FreeBSD */
X#endif /* SCO Xenix */
X#endif /* SCO Unix */
X#endif /* Minix */
X#endif /* Linux */
X#endif /* NeXT */
X#endif /* Amdahl */
X#endif /* Cray */
X#endif /* RT/AIX */
X#endif /* AIX */
X#endif /* OSF/1 */
X#endif /* HP/UX */
X#endif /* Sun */
X#endif /* SGI */


X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X

X} /* end function version() */
X
X#endif /* !SFX */
END_OF_FILE

if test 30753 -ne `wc -c <'unzip-5.12/unix/unix.c'`; then
echo shar: \"'unzip-5.12/unix/unix.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/unix.c'
fi
echo shar: End of archive 10 \(of 20\).
cp /dev/null ark10isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:15:55 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 76
Archive-name: unzip/part11

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/atari/README unzip-5.12/mac/mac.c
# unzip-5.12/unzip.doc
# Wrapped by kent@sparky on Sat Sep 17 23:33:42 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 11 (of 20)."'
if test -f 'unzip-5.12/atari/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/atari/README'\"
else
echo shar: Extracting \"'unzip-5.12/atari/README'\" \(2181 characters\)
sed "s/^X//" >'unzip-5.12/atari/README' <<'END_OF_FILE'
XHere it is... the UnZip 5.1 port for the Atari ST/TT/Falcon!
X
XThis took me longer than I expected thanks to a difference between the
XMiNT library and most UNIX libraries... symlinks are 0x16000
Xinstead of 0xa000... I'm told this isn't even defined in POSIX, so I
Xcan't really complain. At least we've got a filesystem that can use
Xsymlinks!
X
XThis port requires GNU C and allows you to build an unzip/zipinfo/funzip
Xthat supports long filenames (on appropriate filesystems, thanks to the
XMiNT library), as well as symlinks. It also does "proper" (ie, DOS-style)
Xtranslation of text-file end-of-line characters. The programs also build
Xas shared-text binaries, so you can start unzipping several files at once
Xin the background and only a small part of unzip will be duplicated in
Xmemory.
X
XI build unzip with the MiNT library, GNU C 2.5.8 (2.5.7 and lower have a
Xrather sever problem in the optimiser that affects 68000 code only; it
Xadds 68020-only instructions to the 68000 code). Oh, and I tested it
Xextensively under MiNT's minix filesystem as well as the bogus DOS
Xfilesystem that "normal" Atari partitions have.
X
XThe Makefile won't need any editing if you want to built unzip et al. on
Xa minix filesystem; if you want to install it on a DOS filesystem, use
X"cp" instead of "ln" for zipinfo. [Or, to save disk space, make a script/
Xcommand-file which invokes "unzip -Z ...". --CN] This is such a good
Xidea that I'm annoyed that Greg thought of it and I didn't... ;-) If
Xyou're using a shell worth your while, you can alias zipinfo to
X'unzip -Z' and then forget all about this paragraph.
X
XIf you want to compile this using Turbo C (aka Pure C in North America)
Xyou're on your own... That's ok, I'll make a nice binary version of
Xunzip available as soon as the official 5.1 version is released (give or
Xtake a few days).
X
XEnjoy! Cave Newt should be given kudos for keeping this monster easy to
Xport... ;-) [Hah! But thanks anyway. :-) --CN]
X
XPLEASE email me to tell me if you've uploaded the source or binary
Xversions of Unzip 5.x to any BBS systems or commercial online systems so
Xwe can update the Where file!
X
X-Chris-
Xcher...@semprini.waterloo-rdp.on.ca
END_OF_FILE
if test 2181 -ne `wc -c <'unzip-5.12/atari/README'`; then
echo shar: \"'unzip-5.12/atari/README'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/atari/README'
fi
if test -f 'unzip-5.12/mac/mac.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/mac.c'\"
else
echo shar: Extracting \"'unzip-5.12/mac/mac.c'\" \(31814 characters\)
sed "s/^X//" >'unzip-5.12/mac/mac.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X mac.c
X
X Macintosh-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X This source file incorporates the contents of what was formerly macfile.c,
X which supported commands (such as mkdir()) not available directly on the
X Mac, and which also determined whether HFS (Hierarchical File System) or
X MFS (Macintosh File System) was in use.
X
X Contains: do_wild()


X mapattr()
X mapname()
X checkdir()

X close_outfile()
X version()
X IsHFSDisk()
X MacFSTest()
X macmkdir()
X ResolveMacVol()
X macopen()
X macfopen()
X maccreat()
X macread()
X macwrite()
X macclose()
X maclseek()


X
X ---------------------------------------------------------------------------*/
X
X
X

X#include "unzip.h"
X
X#ifdef MACOS
X#ifndef FSFCBLen
X# define FSFCBLen (*(short *)0x3F6)
X#endif
X
X#define read_only file_attr /* for readability only */
X
Xstatic short wAppVRefNum;
Xstatic long lAppDirID;
Xint HFSFlag; /* set if disk has hierarchical file system */


X
Xstatic int created_dir; /* used in mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */
X

X#define MKDIR(path) macmkdir(path, gnVRefNum, glDirID)


X
X
X
X
X

X/**********************/
X/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
X/**********************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{

X static DIR *dir = NULL;


X static char *dirname, *wildname, matchname[FILNAMSIZ];
X static int firstcall=TRUE, have_dirname, dirnamelen;

X struct direct *file;


X
X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, ':')) == NULL) {
X dirname = ":";


X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {

X ++wildname; /* point at character after ':' */


X dirnamelen = wildname - wildspec;

X if ((dirname = (char *)malloc(dirnamelen+1)) == NULL) {
X fprintf(stderr, "warning: can't allocate wildcard buffers\n");


X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }
X strncpy(dirname, wildspec, dirnamelen);
X dirname[dirnamelen] = '\0';

X have_dirname = TRUE;
X }
X

X if ((dir = opendir(dirname)) != NULL) {
X while ((file = readdir(dir)) != NULL) {


X if (match(file->d_name, wildname, 0)) { /* 0 == case sens. */
X if (have_dirname) {
X strcpy(matchname, dirname);
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X }
X /* if we get to here directory is exhausted, so close it */
X closedir(dir);

X dir = NULL;


X }
X
X /* return the raw wildspec in case that works (e.g., directory not
X * searchable, but filespec was not wild and file is readable) */
X strcpy(matchname, wildspec);
X return matchname;
X }
X
X /* last time through, might have failed opendir but returned raw wildspec */

X if (dir == NULL) {


X firstcall = TRUE; /* nothing left to try--reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X }
X

X#ifndef THINK_C /* Think C only matches one at most (for now) */


X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */

X while ((file = readdir(dir)) != NULL)


X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }

X#endif


X
X closedir(dir); /* have read at least one dir entry; nothing left */

X dir = NULL;


X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X

X} /* end function do_wild() */


X
X
X
X
X

X/**********************/
X/* Function mapattr() */
X/**********************/
X
Xint mapattr()
X{

X /* only care about read-only bit, so just look at MS-DOS side of attrs */
X pInfo->read_only = (unsigned)(crec.external_file_attributes & 1);
X return 0;
X
X} /* end function mapattr() */


X
X
X
X
X

X/************************/
X/* Function mapname() */
X/************************/
X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
X{ /* 3 if error (skip file), 10 if no memory (skip file) */
X char pathcomp[FILNAMSIZ]; /* path-component buffer */

X char *pp, *cp=NULL; /* character pointers */
X char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */


X int quote = FALSE; /* flags */
X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X
X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X

X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X
X /* user gave full pathname: don't prepend rootpath */
X renamed_fullpath = (renamed && (*filename == '/'));
X
X if (checkdir((char *)NULL, INIT) == 10)
X return 10; /* initialize path buffer, unless no memory */
X

X pp = pathcomp; /* point to translation buffer */

X if (!(renamed_fullpath || jflag))
X *pp++ = ':';


X *pp = '\0';
X

X if (jflag) /* junking directories */
X cp = (char *)strrchr(filename, '/');

X if (cp == NULL) /* no '/' or not junking dirs */


X cp = filename; /* point to internal zipfile-member pathname */
X else
X ++cp; /* point to start of last component of path */
X
X/*---------------------------------------------------------------------------
X Begin main loop through characters in filename.
X ---------------------------------------------------------------------------*/
X
X while ((workch = (uch)*cp++) != 0) {
X
X if (quote) { /* if character quoted, */
X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';
X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */

X lastsemi = NULL; /* leave directory semi-colons alone */


X break;
X
X case ';': /* VMS version (or DEC-20 attrib?) */

X lastsemi = pp; /* keep for now; remove VMS ";##" */
X *pp++ = (char)workch; /* later, if requested */
X break;


X
X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X

X default:
X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X

X /* if not saving them, remove with VMS version numbers (appended ";###") */


X if (!V_flag && lastsemi) {
X pp = lastsemi + 1;
X while (isdigit((uch)(*pp)))
X ++pp;
X if (*pp == '\0') /* only digits between ';' and end: nuke */
X *lastsemi = '\0';
X }
X
X/*---------------------------------------------------------------------------
X Report if directory was created (and no file to create: filename ended
X in '/'), check name to be sure it exists, and combine path and name be-
X fore exiting.
X ---------------------------------------------------------------------------*/
X
X if (filename[strlen(filename) - 1] == '/') {
X checkdir(filename, GETPATH);
X if (created_dir && QCOND2) {

X fprintf(stdout, " creating: %s\n", filename);


X return IZ_CREATED_DIR; /* set dir time (note trailing '/') */
X }
X return 2; /* dir existed already; don't look for data to extract */
X }
X
X if (*pathcomp == '\0') {

X fprintf(stderr, "mapname: conversion of %s failed\n", filename);


X return 3;
X }
X
X checkdir(pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
X checkdir(filename, GETPATH);
X
X return error;
X

X} /* end function mapname() */


X
X
X
X
X

X if ((end-buildpath) > FILNAMSIZ-3) /* need ':', one-char name, '\0' */


X too_long = TRUE; /* check if extracting directory? */
X if (stat(buildpath, &statbuf)) { /* path doesn't exist */
X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpath);
X return 2; /* path doesn't exist: nothing to do */
X }
X if (too_long) {

X fprintf(stderr, "checkdir error: path too long: %s\n",


X buildpath);
X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }

X if (MKDIR(buildpath) == -1) { /* create the directory */
X fprintf(stderr, "checkdir error: can't create %s\n\


X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {

X fprintf(stderr, "checkdir error: %s exists but is not directory\n\


X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {

X fprintf(stderr, "checkdir error: path too long: %s\n", buildpath);


X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }

X *end++ = ':';


X *end = '\0';
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0;
X
X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------
X GETPATH: copy full path to the string pointed at by pathcomp, and free
X buildpath.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {
X strcpy(pathcomp, buildpath);
X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
X free(buildpath);

X buildpath = end = NULL;


X return 0;
X }
X
X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {
X#ifdef SHORT_NAMES
X char *old_end = end;
X#endif
X
X Trace((stderr, "appending filename [%s]\n", pathcomp));
X while ((*end = *pathcomp++) != '\0') {
X ++end;
X#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */
X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
X *(end = old_end + FILENAME_MAX) = '\0';
X#endif
X if ((end-buildpath) >= FILNAMSIZ) {
X *--end = '\0';

X fprintf(stderr, "checkdir warning: path too long; truncating\n\


Xcheckdir warning: path too long; truncating\n\
X %s\n -> %s\n", filename, buildpath);
X fflush(stderr);
X return 1; /* filename truncated */
X }
X }
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0; /* could check for existence here, prompt for new name... */
X }
X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X

X if (FUNCTION == INIT) {
X Trace((stderr, "initializing buildpath to "));

X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+2)) == NULL)


X return 10;
X if ((rootlen > 0) && !renamed_fullpath) {
X strcpy(buildpath, rootpath);
X end = buildpath + rootlen;
X } else {
X *buildpath = '\0';
X end = buildpath;
X }
X Trace((stderr, "[%s]\n", buildpath));
X return 0;
X }
X
X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line.
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));

X if (pathcomp == NULL) {


X rootlen = 0;
X return 0;
X }
X if ((rootlen = strlen(pathcomp)) > 0) {
X int had_trailing_pathsep=FALSE;
X

X if (pathcomp[rootlen-1] == ':') {


X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (rootlen > 0 && (stat(pathcomp, &statbuf) ||
X !S_ISDIR(statbuf.st_mode))) /* path does not exist */
X {
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || !had_trailing_pathsep
X#endif
X ) {
X rootlen = 0;

X return 2; /* treat as stored file */


X }
X /* create the directory (could add loop here to scan pathcomp
X * and create more than one level, but why really necessary?) */

X if (MKDIR(pathcomp) == -1) {
X fprintf(stderr,


X "checkdir: can't create extraction directory: %s\n",
X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, and */
X return 3; /* failed: file exists, or 2+ levels required */
X }
X }

X if ((rootpath = (char *)malloc(rootlen+2)) == NULL) {


X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);

X rootpath[rootlen++] = ':';


X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));
X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X
X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);
X return 0;
X }
X
X return 99; /* should never reach */
X

X} /* end function checkdir() */


X
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()
X{

X long m_time;
X DateTimeRec dtr;
X ParamBlockRec pbr;
X HParamBlockRec hpbr;
X OSErr err;
X
X
X if (fileno(outfile) == 1) /* don't attempt to close or set time on stdout */


X return;
X
X fclose(outfile);

X
X /*
X * Macintosh bases all file modification times on the number of seconds
X * elapsed since Jan 1, 1904, 00:00:00. Therefore, to maintain
X * compatibility with MS-DOS archives, which date from Jan 1, 1980,
X * with NO relation to GMT, the following conversions must be made:
X * the Year (yr) must be incremented by 1980;
X * and converted to seconds using the Mac routine Date2Secs(),
X * almost similar in complexity to the Unix version :-)
X * J. Lee
X */
X
X dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
X dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
X dtr.day = (lrec.last_mod_file_date & 0x1f);
X
X dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
X dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
X dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
X
X Date2Secs(&dtr, (unsigned long *)&m_time);
X c2pstr(filename);
X if (HFSFlag) {
X hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X hpbr.fileParam.ioVRefNum = gnVRefNum;
X hpbr.fileParam.ioDirID = glDirID;
X hpbr.fileParam.ioFDirIndex = 0;
X err = PBHGetFInfo(&hpbr, 0L);
X hpbr.fileParam.ioFlMdDat = m_time;
X if ( !fMacZipped )
X hpbr.fileParam.ioFlCrDat = m_time;
X hpbr.fileParam.ioDirID = glDirID;
X if (err == noErr)
X err = PBHSetFInfo(&hpbr, 0L);
X if (err != noErr)
X printf("error: can't set the time for %s\n", filename);
X } else {
X pbr.fileParam.ioNamePtr = (StringPtr)filename;
X pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
X pbr.fileParam.ioFDirIndex = 0;
X err = PBGetFInfo(&pbr, 0L);
X pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
X if (err == noErr)
X err = PBSetFInfo(&pbr, 0L);
X if (err != noErr)
X printf("error: can't set the time for %s\n", filename);
X }
X
X /* set read-only perms if needed */
X if ((err == noErr) && pInfo->read_only) {
X if (HFSFlag) {
X hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X hpbr.fileParam.ioVRefNum = gnVRefNum;
X hpbr.fileParam.ioDirID = glDirID;
X err = PBHSetFLock(&hpbr, 0);
X } else
X err = SetFLock((ConstStr255Param)filename, 0);
X }
X p2cstr(filename);
X
X} /* end function close_outfile() */


X
X
X
X
X

X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if 0


X char buf[40];
X#endif
X
X printf(LoadFarString(CompiledWith),

X
X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else

X# if 0
X "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
X# else

X# ifdef THINK_C
X "Think C", "",
X# else
X# ifdef MPW
X "MPW C", "",
X# else


X "unknown compiler", "",

X# endif
X# endif
X# endif

X#endif
X
X "MacOS",
X
X#if defined(foobar) || defined(FOOBAR)
X " (Foo BAR)", /* hardware or OS version */
X#else
X "",
X#endif /* Foo BAR */


X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X
X} /* end function version() */
X

X#endif /* !SFX */


X
X
X
X
X

X/************************/
X/* Function IsHFSDisk() */
X/************************/
X
Xstatic int IsHFSDisk(short wRefNum)
X{
X /* get info about the specified volume */
X if (HFSFlag == true) {
X HParamBlockRec hpbr;
X Str255 temp;
X short wErr;
X
X hpbr.volumeParam.ioCompletion = 0;
X hpbr.volumeParam.ioNamePtr = temp;
X hpbr.volumeParam.ioVRefNum = wRefNum;
X hpbr.volumeParam.ioVolIndex = 0;
X wErr = PBHGetVInfo(&hpbr, 0);
X
X if (wErr == noErr && hpbr.volumeParam.ioVFSID == 0
X && hpbr.volumeParam.ioVSigWord == 0x4244) {
X return true;
X }
X }
X
X return false;
X} /* IsHFSDisk */


X
X
X
X
X

X/************************/
X/* Function MacFSTest() */
X/************************/
X
Xvoid MacFSTest(int vRefNum)
X{
X Str255 st;
X
X /* is this machine running HFS file system? */
X if (FSFCBLen <= 0) {
X HFSFlag = false;
X }
X else
X {
X HFSFlag = true;
X }
X
X /* get the file's volume reference number and directory ID */
X if (HFSFlag == true) {
X WDPBRec wdpb;
X OSErr err = noErr;
X
X if (vRefNum != 0) {
X wdpb.ioCompletion = false;
X wdpb.ioNamePtr = st;
X wdpb.ioWDIndex = 0;
X wdpb.ioVRefNum = vRefNum;
X err = PBHGetVol(&wdpb, false);
X
X if (err == noErr) {
X wAppVRefNum = wdpb.ioWDVRefNum;
X lAppDirID = wdpb.ioWDDirID;
X }
X }
X
X /* is the disk we're using formatted for HFS? */
X HFSFlag = IsHFSDisk(wAppVRefNum);
X }
X
X return;
X} /* mactest */


X
X
X
X
X

X/***********************/
X/* Function macmkdir() */
X/***********************/
X
Xint macmkdir(char *path, short nVRefNum, long lDirID)
X{
X OSErr err = -1;
X
X if (path != 0 && strlen(path)<256 && HFSFlag == true) {
X HParamBlockRec hpbr;
X Str255 st;
X
X c2pstr(path);
X if ((nVRefNum == 0) && (lDirID == 0))
X {
X hpbr.fileParam.ioNamePtr = st;
X hpbr.fileParam.ioCompletion = NULL;
X err = PBHGetVol((WDPBPtr)&hpbr, false);
X nVRefNum = hpbr.wdParam.ioWDVRefNum;
X lDirID = hpbr.wdParam.ioWDDirID;
X }
X else
X {
X err = noErr;
X }
X if (err == noErr) {
X hpbr.fileParam.ioCompletion = NULL;
X hpbr.fileParam.ioVRefNum = nVRefNum;
X hpbr.fileParam.ioDirID = lDirID;
X hpbr.fileParam.ioNamePtr = (StringPtr)path;
X err = PBDirCreate(&hpbr, false);
X }
X p2cstr(path);
X }
X
X return (int)err;
X} /* macmkdir */


X
X
X
X
X

X/****************************/
X/* Function ResolveMacVol() */
X/****************************/
X
Xvoid ResolveMacVol(short nVRefNum, short *pnVRefNum, long *plDirID, StringPtr pst)
X{
X if (HFSFlag)
X {
X WDPBRec wdpbr;
X Str255 st;
X OSErr err;
X
X wdpbr.ioCompletion = (ProcPtr)NULL;
X wdpbr.ioNamePtr = st;
X wdpbr.ioVRefNum = nVRefNum;
X wdpbr.ioWDIndex = 0;
X wdpbr.ioWDProcID = 0;
X wdpbr.ioWDVRefNum = 0;
X err = PBGetWDInfo( &wdpbr, false );
X if ( err == noErr )
X {
X if (pnVRefNum)
X *pnVRefNum = wdpbr.ioWDVRefNum;
X if (plDirID)
X *plDirID = wdpbr.ioWDDirID;
X if (pst)
X BlockMove( st, pst, st[0]+1 );
X }
X }
X else
X {
X if (pnVRefNum)
X *pnVRefNum = nVRefNum;
X if (plDirID)
X *plDirID = 0;
X if (pst)
X *pst = 0;


X }
X}
X
X
X
X
X

X/**********************/
X/* Function macopen() */
X/**********************/
X
Xshort macopen(char *sz, short nFlags, short nVRefNum, long lDirID)
X{
X OSErr err;
X Str255 st;
X char chPerms = (!nFlags) ? fsRdPerm : fsRdWrPerm;
X short nFRefNum;
X
X c2pstr( sz );
X BlockMove( sz, st, sz[0]+1 );
X p2cstr( sz );
X if (HFSFlag)
X {
X if (nFlags > 1)
X err = HOpenRF( nVRefNum, lDirID, st, chPerms, &nFRefNum);
X else
X err = HOpen( nVRefNum, lDirID, st, chPerms, &nFRefNum);
X }
X else
X {
X /*
X * Have to use PBxxx style calls since the high level
X * versions don't support specifying permissions
X */
X ParamBlockRec pbr;
X
X pbr.ioParam.ioNamePtr = st;
X pbr.ioParam.ioVRefNum = gnVRefNum;
X pbr.ioParam.ioVersNum = 0;
X pbr.ioParam.ioPermssn = chPerms;
X pbr.ioParam.ioMisc = 0;
X if (nFlags >1)
X err = PBOpenRF( &pbr, false );
X else
X err = PBOpen( &pbr, false );
X nFRefNum = pbr.ioParam.ioRefNum;
X }
X if ( err || (nFRefNum == 1) )
X return -1;
X else {
X if ( nFlags )
X SetEOF( nFRefNum, 0 );
X return nFRefNum;


X }
X}
X
X
X
X
X

X/***********************/
X/* Function macfopen() */
X/***********************/
X
XFILE *macfopen(char *filename, char *mode, short nVRefNum, long lDirID)
X {
X short outfd, fDataFork=TRUE;
X MACINFO mi;
X OSErr err;
X
X fMacZipped = FALSE;
X c2pstr(filename);
X if (extra_field &&
X (lrec.extra_field_length > sizeof(MACINFOMIN)) &&
X (lrec.extra_field_length <= sizeof(MACINFO))) {
X BlockMove(extra_field, &mi, lrec.extra_field_length);
X if ((makeword((uch *)&mi.header) == 1992) &&
X (makeword((uch *)&mi.data) ==
X lrec.extra_field_length-sizeof(ZIP_EXTRA_HEADER)) &&
X (mi.signature == 'JLEE')) {
X gostCreator = mi.finfo.fdCreator;
X gostType = mi.finfo.fdType;
X fDataFork = (mi.flags & 1) ? TRUE : FALSE;
X fMacZipped = true;
X /* If it was Zipped w/Mac version, the filename has either */
X /* a 'd' or 'r' appended. Remove the d/r when unzipping */
X filename[0]-=1;
X }
X }
X if (!fMacZipped) {
X if (!aflag)
X gostType = gostCreator = '\?\?\?\?';
X else {
X gostCreator = CREATOR;
X gostType = 'TEXT';
X }
X }
X p2cstr(filename);
X
X if ((outfd = creat(filename, 0)) != -1) {
X if (fMacZipped) {
X c2pstr(filename);
X if (HFSFlag) {
X HParamBlockRec hpbr;
X
X hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X hpbr.fileParam.ioVRefNum = gnVRefNum;
X hpbr.fileParam.ioDirID = glDirID;
X hpbr.fileParam.ioFlFndrInfo = mi.finfo;
X hpbr.fileParam.ioFlCrDat = mi.lCrDat;
X hpbr.fileParam.ioFlMdDat = mi.lMdDat;
X err = PBHSetFInfo(&hpbr, 0);
X } else {
X err = SetFInfo((StringPtr)filename , 0, &mi.finfo);
X }
X p2cstr(filename);
X }
X outfd = open(filename, (fDataFork) ? 1 : 2);
X }
X
X if (outfd == -1)
X return NULL;
X else
X return (FILE *)outfd;


X }
X
X
X
X
X

X/***********************/
X/* Function maccreat() */
X/***********************/
X
Xshort maccreat(char *sz, short nVRefNum, long lDirID, OSType ostCreator, OSType ostType)
X{
X OSErr err;
X Str255 st;
X FInfo fi;
X
X c2pstr( sz );
X BlockMove( sz, st, sz[0]+1 );
X p2cstr( sz );
X if (HFSFlag)
X {
X err = HGetFInfo( nVRefNum, lDirID, st, &fi );
X if (err == fnfErr)
X err = HCreate( nVRefNum, lDirID, st, ostCreator, ostType );
X else if (err == noErr)
X {
X fi.fdCreator = ostCreator;
X fi.fdType = ostType;
X err = HSetFInfo( nVRefNum, lDirID, st, &fi );
X }
X }
X else
X {
X err = GetFInfo( st, nVRefNum, &fi );
X if (err == fnfErr)
X err = Create( st, nVRefNum, ostCreator, ostType );
X else if (err == noErr)
X {
X fi.fdCreator = ostCreator;
X fi.fdType = ostType;
X err = SetFInfo( st, nVRefNum, &fi );
X }
X }
X if (err == noErr)
X return noErr;
X else
X return -1;


X}
X
X
X
X
X

X/**********************/
X/* Function macread() */
X/**********************/
X
Xshort macread(short nFRefNum, char *pb, unsigned cb)
X{
X long lcb = cb;
X
X (void)FSRead( nFRefNum, &lcb, pb );
X
X return (short)lcb;


X}
X
X
X
X
X

X/***********************/
X/* Function macwrite() */
X/***********************/
X
Xlong macwrite(short nFRefNum, char *pb, unsigned cb)
X{
X long lcb = cb;
X
X#ifdef THINK_C
X if ( (nFRefNum == 1) )
X screenDump( pb, lcb );
X else
X#endif
X (void)FSWrite( nFRefNum, &lcb, pb );
X
X return (long)lcb;


X}
X
X
X
X
X

X/***********************/
X/* Function macclose() */
X/***********************/
X
Xshort macclose(short nFRefNum)
X{
X return FSClose( nFRefNum );


X}
X
X
X
X
X

X/***********************/
X/* Function maclseek() */
X/***********************/
X
Xlong maclseek(short nFRefNum, long lib, short nMode)
X{
X ParamBlockRec pbr;
X
X if (nMode == SEEK_SET)
X nMode = fsFromStart;
X else if (nMode == SEEK_CUR)
X nMode = fsFromMark;
X else if (nMode == SEEK_END)
X nMode = fsFromLEOF;
X pbr.ioParam.ioRefNum = nFRefNum;
X pbr.ioParam.ioPosMode = nMode;
X pbr.ioParam.ioPosOffset = lib;
X (void)PBSetFPos(&pbr, 0);
X return pbr.ioParam.ioPosOffset;
X}
X
X#endif /* MACOS */
END_OF_FILE
if test 31814 -ne `wc -c <'unzip-5.12/mac/mac.c'`; then
echo shar: \"'unzip-5.12/mac/mac.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/mac.c'
fi
if test -f 'unzip-5.12/unzip.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unzip.doc'\"
else
echo shar: Extracting \"'unzip-5.12/unzip.doc'\" \(33336 characters\)
sed "s/^X//" >'unzip-5.12/unzip.doc' <<'END_OF_FILE'
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
XNAME
X unzip - list, test and extract compressed files in a ZIP
X archive
X
XSYNOPSIS
X unzip [-Z] [-cflptuvz[abjnoqsCLV$]] file[.zip] [file(s) ...]
X [-x xfile(s) ...] [-d exdir]
X
XDESCRIPTION
X unzip will list, test, or extract files from a ZIP archive,
X commonly found on MS-DOS systems. The default behavior
X (with no options) is to extract into the current directory
X (and subdirectories below it) all files from the specified
X ZIP archive. A companion program, zip(1L), creates ZIP
X archives; both programs are compatible with archives created
X by PKWARE's PKZIP and PKUNZIP for MS-DOS, but in many cases
X the program options or default behaviors differ.

X filename; and if that also fails, the suffix .zip is

X appended. Note that self-extracting ZIP files are sup-
X ported, as with any other ZIP archive; just specify the
X .exe suffix (if any) explicitly.
X
X [file(s)]
X An optional list of archive members to be processed,
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 1
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X separated by spaces. (VMS versions compiled with
X VMSCLI defined must delimit files with commas instead.
X See -v in OPTIONS below.) Regular expressions (wild-
X cards) may be used to match multiple members; see
X above. Again, be sure to quote expressions that would
X otherwise be expanded or modified by the operating sys-
X tem.


X
X [-x xfile(s)]
X An optional list of archive members to be excluded from

X processing. Since wildcard characters match directory
X separators (`/'), this option may be used to exclude
X any files which are in subdirectories. For example,
X ``unzip foo *.[ch] -x */*'' would extract all C source
X files in the main directory, but none in any subdirec-
X tories. Without the -x option, all C source files in
X all directories within the zipfile would be extracted.
X
X [-d exdir]
X An optional directory to which to extract files. By
X default, all files and subdirectories are recreated in
X the current directory; the -d option allows extraction
X in an arbitrary directory (always assuming one has per-
X mission to write to the directory). This option need
X not appear at the end of the command line; it is also
X accepted immediately after the zipfile specification,
X or between the file(s) and the -x option. The option
X and directory may be concatenated without any white
X space between them, but note that this may cause normal
X shell behavior to be suppressed. In particular,
X ``-d ~'' (tilde) is expanded by Unix C shells into the
X name of the user's home directory, but ``-d~'' is
X treated as a literal subdirectory ``~'' of the current
X directory.
X
XOPTIONS
X Note that, in order to support obsolescent hardware, unzip's
X usage screen is limited to 22 or 23 lines and should there-
X fore be considered a reminder of the basic unzip syntax
X rather than an exhaustive list of all possible flags.
X
X -Z zipinfo(1L) mode. If the first option on the command
X line is -Z, the remaining options are taken to be
X zipinfo(1L) options. See the appropriate manual page
X for a description of these options.
X
X -c extract files to stdout/screen (``CRT''). This option
X is similar to the -p option except that the name of
X each file is printed as it is extracted, the -a option
X is allowed, and ASCII-EBCDIC conversion is automati-
X cally performed if appropriate. This option is not
X listed in the unzip usage screen.
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 2
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X -f freshen existing files, i.e., extract only those files
X which already exist on disk and which are newer than
X the disk copies. By default unzip queries before
X overwriting, but the -o option may be used to suppress
X the queries. Note that under many operating systems,
X the TZ (timezone) environment variable must be set
X correctly in order for -f and -u to work properly
X (under Unix the variable is usually set automatically).
X The reasons for this are somewhat subtle but have to do
X with the differences between DOS-format file times
X (always local time) and Unix-format times (always in
X GMT) and the necessity to compare the two. A typical
X TZ value is ``PST8PDT'' (US Pacific time with automatic
X adjustment for Daylight Savings Time or ``summer
X time'').
X
X -l list archive files (short format). The names,
X uncompressed file sizes and modification dates and
X times of the specified files are printed, along with
X totals for all files specified. In addition, the zip-
X file comment and individual file comments (if any) are
X displayed. If a file was archived from a single-case
X file system (for example, the old MS-DOS FAT file sys-
X tem) and the -L option was given, the filename is con-
X verted to lowercase and is prefixed with a caret (^).
X
X -p extract files to pipe (stdout). Nothing but the file
X data is sent to stdout, and the files are always
X extracted in binary format, just as they are stored (no
X conversions).
X
X -t test archive files. This option extracts each speci-
X fied file in memory and compares the CRC (cyclic redun-
X dancy check, an enhanced checksum) of the expanded file
X with the original file's stored CRC value.
X
X -u update existing files and create new ones if needed.
X This option performs the same function as the -f
X option, extracting (with query) files which are newer
X than those with the same name on disk, and in addition
X it extracts those files which do not already exist on
X disk. See -f above for information on setting the
X timezone properly.
X
X -v be verbose or print diagnostic version info. This
X option has evolved and now behaves as both an option
X and a modifier. As an option it has two purposes:
X when a zipfile is specified with no other options, -v
X lists archive files verbosely, adding to the -l info
X the compression method, compressed size, compression
X ratio and 32-bit CRC. When no zipfile is specified
X (that is, the complete command is simply ``unzip -v''),
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 3
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X a diagnostic screen is printed. In addition to the
X normal header with release date and version, unzip
X lists the home Info-ZIP ftp site and where to find a
X list of other ftp and non-ftp sites; the target operat-
X ing system for which it was compiled, as well as (pos-
X sibly) the hardware on which it was compiled, the com-
X piler and version used, and the compilation date; any
X special compilation options which might affect the
X program's operation (see also DECRYPTION below); and
X any options stored in environment variables which might
X do the same (see ENVIRONMENT OPTIONS below). As a
X modifier it works in conjunction with other options
X (e.g., -t) to produce more verbose or debugging output;
X this is not yet fully implemented but will be in future
X releases.
X
X -z display only the archive comment.
X
XMODIFIERS
X -a convert text files. Ordinarily all files are extracted
X exactly as they are stored (as ``binary'' files). The
X -a option causes files identified by zip as text files
X (those with the `t' label in zipinfo listings, rather
X than `b') to be automatically extracted as such, con-
X verting line endings, end-of-file characters and the
X character set itself as necessary. (For example, Unix
X files use line feeds (LFs) for end-of-line (EOL) and
X have no end-of-file (EOF) marker; Macintoshes use car-
X riage returns (CRs) for EOLs; and most PC operating
X systems use CR+LF for EOLs and control-Z for EOF. In
X addition, IBM mainframes and the Michigan Terminal Sys-
X tem use EBCDIC rather than the more common ASCII char-
X acter set, and NT supports Unicode.) Note that zip's
X identification of text files is by no means perfect;
X some ``text'' files may actually be binary and vice
X versa. unzip therefore prints ``[text]'' or
X ``[binary]'' as a visual check for each file it
X extracts when using the -a option. The -aa option
X forces all files to be extracted as text, regardless of
X the supposed file type.
X
X -b treat all files as binary (no text conversions). This
X is a shortcut for ---a.
X
X -C match filenames case-insensitively. unzip's philosophy
X is ``you get what you ask for'' (this is also responsi-
X ble for the -L/-U change; see the relevant options
X below). Because some filesystems are fully case-
X sensitive (notably those under the Unix operating sys-
X tem) and because both ZIP archives and unzip itself are
X portable across platforms, unzip's default behavior is
X to match both wildcard and literal filenames case-
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 4
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X sensitively. That is, specifying ``makefile'' on the
X command line will only match ``makefile'' in the
X archive, not ``Makefile'' or ``MAKEFILE'' (and simi-
X larly for wildcard specifications). Since this does
X not correspond to the behavior of many other
X operating/file systems (for example, OS/2 HPFS which
X preserves mixed case but is not sensitive to it), the
X -C option may be used to force all filename matches to
X be case-insensitive. In the example above, all three
X files would then match ``makefile'' (or ``make*'', or
X similar). The -C option affects files in both the nor-
X mal file list and the excluded-file list (xlist).
X
X -j junk paths. The archive's directory structure is not
X recreated; all files are deposited in the extraction
X directory (by default, the current one).
X
X -L convert to lowercase any filename originating on an
X uppercase-only operating system or filesystem. (This
X was unzip's default behavior in releases prior to 5.11;
X the new default behavior is identical to the old
X behavior with the -U option, which is now obsolete and
X will be removed in a future release.) Depending on the
X archiver, files archived under single-case filesystems
X (VMS, old MS-DOS FAT, etc.) may be stored as all-
X uppercase names; this can be ugly or inconvenient when
X extracting to a case-preserving filesystem such as OS/2
X HPFS or a case-sensitive one such as under Unix. By
X default unzip lists and extracts such filenames exactly
X as they're stored (excepting truncation, conversion of
X unsupported characters, etc.); this option causes the
X names of all files from certain systems to be converted
X to lowercase.
X
X -n never overwrite existing files. If a file already
X exists, skip the extraction of that file without
X prompting. By default unzip queries before extracting
X any file which already exists; the user may choose to
X overwrite only the current file, overwrite all files,
X skip extraction of the current file, skip extraction of
X all existing files, or rename the current file.
X
X -o overwrite existing files without prompting. This is a
X dangerous option, so use it with care. (It is often
X used with -f, however.)
X
X -q perform operations quietly (-qq = even quieter). Ordi-
X narily unzip prints the names of the files it's
X extracting or testing, the extraction methods, any file
X or zipfile comments which may be stored in the archive,
X and possibly a summary when finished with each archive.
X The -q[q] options suppress the printing of some or all
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 5
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X of these messages.
X
X -s [OS/2, NT, MS-DOS] convert spaces in filenames to
X underscores. Since all PC operating systems allow
X spaces in filenames, unzip by default extracts
X filenames with spaces intact (e.g., ``EA DATA. SF'').
X This can be awkward, however, since MS-DOS in particu-
X lar does not gracefully support spaces in filenames.
X Conversion of spaces to underscores can eliminate the
X awkwardness in some cases.
X
X -U (obsolete; to be removed in a future release) leave
X filenames uppercase if created under MS-DOS, VMS, etc.
X See -L above.
X
X -V retain (VMS) file version numbers. VMS files can be
X stored with a version number, in the format
X file.ext;##. By default the ``;##'' version numbers
X are stripped, but this option allows them to be
X retained. (On filesystems which limit filenames to
X particularly short lengths, the version numbers may be
X truncated or stripped regardless of this option.)
X
X -X [VMS] restore owner/protection info (may require system
X privileges). Ordinary file attributes are always
X restored, but this option allows UICs to be restored as
X well. [The next version of unzip will support Unix
X UID/GID info as well, and possibly NT permissions.]
X
X -$ [MS-DOS, OS/2, NT, Amiga] restore the volume label if
X the extraction medium is removable (e.g., a diskette).
X Doubling the option (-$$) allows fixed media (hard
X disks) to be labelled as well. By default, volume
X labels are ignored.
X
XENVIRONMENT OPTIONS
X unzip's default behavior may be modified via options placed
X in an environment variable. This can be done with any
X option, but it is probably most useful with the -a, -L, -C,
X -q, -o, or -n modifiers: make unzip auto-convert text files
X by default, make it convert filenames from uppercase systems
X to lowercase, make it match names case-insensitively, make
X it quieter, or make it always overwrite or never overwrite
X files as it extracts them. For example, to make unzip act
X as quietly as possible, only reporting errors, one would use
X one of the following commands:
X
X UNZIP=-qq; export UNZIP Unix Bourne shell
X setenv UNZIP -qq Unix C shell
X set UNZIP=-qq OS/2 or MS-DOS
X define UNZIP_OPTS "-qq" VMS (quotes for lowercase)
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 6
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X Environment options are, in effect, considered to be just
X like any other command-line options, except that they are
X effectively the first options on the command line. To over-
X ride an environment option, one may use the ``minus opera-
X tor'' to remove it. For instance, to override one of the
X quiet-flags in the example above, use the command
X
X unzip --q[other options] zipfile
X
X The first hyphen is the normal switch character, and the
X second is a minus sign, acting on the q option. Thus the
X effect here is to cancel one quantum of quietness. To can-
X cel both quiet flags, two (or more) minuses may be used:
X
X unzip -t--q zipfile
X unzip ---qt zipfile
X
X (the two are equivalent). This may seem awkward or confus-
X ing, but it is reasonably intuitive: just ignore the first
X hyphen and go from there. It is also consistent with the
X behavior of Unix nice(1).
X
X As suggested by the examples above, the default variable
X names are UNZIP_OPTS for VMS (where the symbol used to
X install unzip as a foreign command would otherwise be con-
X fused with the environment variable), and UNZIP for all
X other operating systems. For compatibility with zip(1L),
X UNZIPOPT is also accepted (don't ask). If both UNZIP and
X UNZIPOPT are defined, however, UNZIP takes precedence.


X unzip's diagnostic option (-v with no zipfile name) can be
X used to check the values of all four possible unzip and
X zipinfo environment variables.
X

X The timezone variable (TZ) should be set according to the
X local timezone in order for the -f and -u to operate
X correctly. See the description of -f above for details.
X This variable may also be necessary in order for timestamps
X on extracted files to be set correctly.
X
XDECRYPTION
X Encrypted archives are fully supported by Info-ZIP software,
X but due to United States export restrictions, the encryption
X and decryption sources are not packaged with the regular
X unzip and zip distributions. Since the crypt sources were
X written by Europeans, however, they are freely available at
X sites throughout the world; see the file ``Where'' in any
X Info-ZIP source or binary distribution for locations both
X inside and outside the US.
X
X Because of the separate distribution, not all compiled ver-
X sions of unzip support decryption. To check a version for
X crypt support, either attempt to test or extract an
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 7
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X encrypted archive, or else check unzip's diagnostic screen
X (see the -v option above) for ``[decryption]'' as one of the
X special compilation options.
X
X There are no runtime options for decryption; if a zipfile
X member is encrypted, unzip will prompt for the password
X without echoing what is typed. unzip continues to use the
X same password as long as it appears to be valid; it does
X this by testing a 12-byte header. The correct password will
X always check out against the header, but there is a 1-in-256
X chance that an incorrect password will as well. (This is a
X security feature of the PKWARE zipfile format; it helps
X prevent brute-force attacks which might otherwise gain a
X large speed advantage by testing only the header.) In the
X case that an incorrect password is given but it passes the
X header test anyway, either an incorrect CRC will be gen-
X erated for the extracted data or else unzip will fail during
X the extraction because the ``decrypted'' bytes do not con-
X stitute a valid compressed data stream.
X
X If the first password fails the header check on some file,
X unzip will prompt for another password, and so on until all
X files are extracted. If a password is not known, entering a
X null password (that is, just a carriage return) is taken as
X a signal to skip all further prompting. Only unencrypted
X files in the archive(s) will thereafter be extracted.
X (Actually that's not quite true; older versions of zip(1L)
X and zipcloak(1L) allowed null passwords, so unzip checks
X each encrypted file to see if the null password works. This
X may result in ``false positives'' and extraction errors, as
X noted above.)
X
X Note that there is presently no way to avoid interactive
X decryption. This is another security feature: plaintext
X passwords given on the command line or stored in files con-
X stitute a risk because they may be seen by others. Future
X releases may (under protest, with great disapproval) support
X such shenanigans.
X
XEXAMPLES
X To use unzip to extract all members of the archive
X letters.zip into the current directory and subdirectories
X below it, creating any subdirectories as necessary:
X
X unzip letters
X
X To extract all members of letters.zip into the current
X directory only:
X
X unzip -j letters
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 8
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X To test letters.zip, printing only a summary message indi-
X cating whether the archive is OK or not:
X
X unzip -tq letters
X
X To test all zipfiles in the current directory, printing only
X the summaries:
X
X unzip -tq \*.zip
X
X (The backslash before the asterisk is only required if the
X shell expands wildcards, as in Unix; double quotes could
X have been used instead, as in the source examples
X below.) To extract to standard output all members of
X letters.zip whose names end in .tex, auto-converting to the
X local end-of-line convention and piping the output into
X more(1):
X
X unzip -ca letters \*.tex | more
X
X To extract the binary file paper1.dvi to standard output and
X pipe it to a printing program:
X
X unzip -p articles paper1.dvi | dvips
X
X To extract all FORTRAN and C source files--*.f, *.c, *.h,
X and Makefile--into the /tmp directory:
X
X unzip source.zip "*.[fch]" Makefile -d /tmp
X
X (the double quotes are necessary only in Unix and only if
X globbing is turned on). To extract all FORTRAN and C source
X files, regardless of case (e.g., both *.c and *.C, and any
X makefile, Makefile, MAKEFILE or similar):
X
X unzip -C source.zip "*.[fch]" makefile -d /tmp
X
X To extract any such files but convert any uppercase MS-DOS
X or VMS names to lowercase and convert the line-endings of
X all of the files to the local standard (without respect to
X any files which might be marked ``binary''):
X
X unzip -aaCL source.zip "*.[fch]" makefile -d /tmp
X
X To extract only newer versions of the files already in the
X current directory, without querying (NOTE: be careful of
X unzipping in one timezone a zipfile created in another--ZIP
X archives to date contain no timezone information, and a
X ``newer'' file from an eastern timezone may, in fact, be
X older):
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 9
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X unzip -fo sources
X
X To extract newer versions of the files already in the
X current directory and to create any files not already there
X (same caveat as previous example):
X
X unzip -uo sources
X
X To display a diagnostic screen showing which unzip and
X zipinfo options are stored in environment variables, whether
X decryption support was compiled in, the compiler with which
X unzip was compiled, etc.:
X
X unzip -v
X
X In the last five examples, assume that UNZIP or UNZIP_OPTS
X is set to -q. To do a singly quiet listing:
X
X unzip -l file.zip
X
X To do a doubly quiet listing:
X
X unzip -ql file.zip
X
X (Note that the ``.zip'' is generally not necessary.) To do
X a standard listing:
X
X unzip --ql file.zip
X or
X unzip -l-q file.zip
X or
X unzip -l--q file.zip (extra minuses don't hurt)
X
XTIPS
X The current maintainer, being a lazy sort, finds it very
X useful to define a pair of aliases: tt for ``unzip -tq''
X and ii for ``unzip -Z'' (or ``zipinfo''). One may then sim-
X ply type ``tt zipfile'' to test an archive, something which
X is worth making a habit of doing. With luck unzip will
X report ``No errors detected in zipfile.zip,'' after which
X one may breathe a sigh of relief.
X
X The maintainer also finds it useful to set the UNZIP
X environment variable to ``-aL'' and is tempted to add ``-C''
X as well. His ZIPINFO variable is set to ``-z''.
X
XDIAGNOSTICS
X The exit status (or error level) approximates the exit codes
X defined by PKWARE and takes on the following values, except
X under VMS:
X
X 0 normal; no errors or warnings detected.
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 10
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X 1 one or more warning errors were encountered, but
X processing completed successfully anyway. This
X includes zipfiles where one or more files was
X skipped due to unsupported compression method or
X encryption with an unknown password.
X
X 2 a generic error in the zipfile format was
X detected. Processing may have completed success-
X fully anyway; some broken zipfiles created by
X other archivers have simple work-arounds.
X
X 3 a severe error in the zipfile format was detected.
X Processing probably failed immediately.
X
X 4-8 unzip was unable to allocate memory for one or
X more buffers.
X
X 9 the specified zipfiles were not found.
X
X 10 invalid options were specified on the command
X line.
X
X 11 no matching files were found.
X
X 50 the disk is (or was) full during extraction.
X
X 51 the end of the ZIP archive was encountered prema-
X turely.
X
X VMS interprets standard Unix (or PC) return values as other,
X scarier-looking things, so by default unzip always returns 0
X (which reportedly gets converted into a VMS status of 1--
X i.e., success). There are two compilation options available
X to modify or expand upon this behavior: defining
X RETURN_CODES results in a human-readable explanation of what
X the real error status was (but still with a faked ``suc-
X cess'' exit value), while defining RETURN_SEVERITY causes
X unzip to exit with a ``real'' VMS status. The latter
X behavior will become the default in future versions unless
X it is found to conflict with officially defined VMS codes.
X The current mapping is as follows: 1 (success) for normal
X exit, 0x7fff0001 for warning errors, and (0x7fff000? +
X 16*normal_unzip_exit_status) for all other errors, where the
X `?' is 2 (error) for unzip values 2 and 9-11, and 4 (fatal
X error) for the remaining ones (3-8, 50, 51). Check the
X ``unzip -v'' output to see whether RETURN_SEVERITY was
X defined at compilation time.
X
XBUGS
X When attempting to extract a corrupted archive, unzip may go
X into an infinite loop and, if not stopped quickly enough,
X fill all available disk space. Compiling with CHECK_EOF
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 11
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X should fix this problem for all zipfiles, but the option was
X introduced too late in the testing process to be made the
X default behavior. Future versions will be robust enough to
X fail gracefully on damaged archives. Check the ``unzip -v''
X output to see whether CHECK_EOF was defined during compila-
X tion.
X
X [MS-DOS] When extracting or testing files from an archive on
X a defective floppy diskette, if the ``Fail'' option is
X chosen from DOS's ``Abort, Retry, Fail?'' message, unzip may
X hang the system, requiring a reboot. Instead, press
X control-C (or control-Break) to terminate unzip.
X
X Under DEC Ultrix, unzip will sometimes fail on long zipfiles
X (bad CRC, not always reproducible). This is apparently due
X either to a hardware bug (cache memory) or an operating sys-
X tem bug (improper handling of page faults?).
X
X Dates and times of stored directories are not restored.
X
X [OS/2] Extended attributes for existing directories are
X never updated. This is a limitation of the operating sys-
X tem; unzip has no way to determine whether the stored attri-
X butes are newer or older than the existing ones.
X
X [VMS] When extracting to another directory, only the [.foo]
X syntax is accepted for the -d option; the simple Unix foo
X syntax is silently ignored (as is the less common VMS
X foo.dir syntax).
X
X [VMS] When the file being extracted already exists, unzip's
X query only allows skipping, overwriting or renaming; there
X should additionally be a choice for creating a new version
X of the file. In fact, the ``overwrite'' choice does create
X a new version; the old version is not overwritten or
X deleted.
X
XSEE ALSO
X funzip(1L), zip(1L), zipcloak(1L), zipgrep(1L), zipinfo(1L),
X zipnote(1L), zipsplit(1L)
X
XAUTHORS
X The primary Info-ZIP authors (current zip-bugs workgroup)
X are: Jean-loup Gailly (Zip); Greg R. Roelofs (UnZip); Mark
X Adler (decompression, fUnZip); Kai Uwe Rommel (OS/2); Igor
X Mandrichenko and Hunter Goatley (VMS); John Bush and Paul
X Kienitz (Amiga); Antoine Verheijen (Macintosh); Chris Her-
X borth (Atari); Henry Gessau (NT); Karl Davis, Sergio Monesi
X and Evan Shattock (Acorn Archimedes); and Robert Heath (Win-
X dows). The author of the original unzip code upon which
X Info-ZIP's is based was Samuel H. Smith; Carl Mascott did
X the first Unix port; and David P. Kirschbaum organized and
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 12
X
XUNZIP(1L) MISC. REFERENCE MANUAL PAGES UNZIP(1L)
X
X led Info-ZIP in its early days. The full list of contribu-
X tors to UnZip has grown quite large; please refer to the
X CONTRIBS file in the UnZip source distribution for a rela-
X tively complete version.
X
XVERSIONS
X v1.2 15 Mar 89 Samuel H. Smith
X v2.0 9 Sep 89 Samuel H. Smith
X v2.x fall 1989 many Usenet contributors
X v3.0 1 May 90 Info-ZIP (DPK, consolidator)
X v3.1 15 Aug 90 Info-ZIP (DPK, consolidator)
X v4.0 1 Dec 90 Info-ZIP (GRR, maintainer)
X v4.1 12 May 91 Info-ZIP
X v4.2 20 Mar 92 Info-ZIP (zip-bugs subgroup, GRR)
X v5.0 21 Aug 92 Info-ZIP (zip-bugs subgroup, GRR)
X v5.01 15 Jan 93 Info-ZIP (zip-bugs subgroup, GRR)
X v5.1 7 Feb 94 Info-ZIP (zip-bugs subgroup, GRR)
X v5.11 2 Aug 94 Info-ZIP (zip-bugs subgroup, GRR)
X v5.12 28 Aug 94 Info-ZIP (zip-bugs subgroup, GRR)
X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 13
X
END_OF_FILE
if test 33336 -ne `wc -c <'unzip-5.12/unzip.doc'`; then
echo shar: \"'unzip-5.12/unzip.doc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unzip.doc'
fi
echo shar: End of archive 11 \(of 20\).
cp /dev/null ark11isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:01 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 77
Archive-name: unzip/part12

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/atari/atari.c unzip-5.12/match.c
# unzip-5.12/unix/unzip.1
# Wrapped by kent@sparky on Sat Sep 17 23:33:42 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 12 (of 20)."'
if test -f 'unzip-5.12/atari/atari.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/atari/atari.c'\"
else
echo shar: Extracting \"'unzip-5.12/atari/atari.c'\" \(26647 characters\)
sed "s/^X//" >'unzip-5.12/atari/atari.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X atari.c
X
X Atari-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X


X Contains: readdir()
X do_wild() <-- generic enough to put in file_io.c?

X mapattr()
X mapname()
X checkdir()

X mkdir()


X close_outfile()
X version()
X

X Due to the amazing MiNT library being very, very close to BSD unix's
X library, I'm using the unix.c as a base for this. Note: If you're not
X going to compile this with the MiNT libraries (for GNU C, Turbo C, Pure C,
X Lattice C, or Heat & Serve C), you're going to be in for some nasty work.
X Most of the modifications in this file were made by Chris Herborth
X (cher...@semprini.waterloo-rdp.on.ca) and /should/ be marked with [cjh].


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
X#include <dirent.h> /* MiNTlibs has dirent [cjh] */


X
Xstatic int created_dir; /* used in mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */
X

X/**********************/
X/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
X/**********************/
X
Xchar *do_wild(wildspec)
X char *wildspec; /* only used first time on a given dir */
X{
X static DIR *dir = NULL;
X static char *dirname, *wildname, matchname[FILNAMSIZ];
X static int firstcall=TRUE, have_dirname, dirnamelen;

X struct dirent *file;


X
X
X /* Even when we're just returning wildspec, we *always* do so in
X * matchname[]--calling routine is allowed to append four characters
X * to the returned string, and wildspec may be a pointer to argv[].
X */
X if (firstcall) { /* first call: must initialize everything */
X firstcall = FALSE;
X
X /* break the wildspec into a directory part and a wildcard filename */

X if ((wildname = strrchr(wildspec, '/')) == NULL) {
X dirname = ".";


X dirnamelen = 1;
X have_dirname = FALSE;
X wildname = wildspec;
X } else {

X ++wildname; /* point at character after '/' */


X dirnamelen = wildname - wildspec;
X if ((dirname = (char *)malloc(dirnamelen+1)) == NULL) {
X fprintf(stderr, "warning: can't allocate wildcard buffers\n");
X strcpy(matchname, wildspec);
X return matchname; /* but maybe filespec was not a wildcard */
X }
X strncpy(dirname, wildspec, dirnamelen);

X dirname[dirnamelen] = '\0'; /* terminate for strcpy below */

X have_dirname = TRUE;
X }
X
X if ((dir = opendir(dirname)) != NULL) {
X while ((file = readdir(dir)) != NULL) {

X if (file->d_name[0] == '.' && wildname[0] != '.')
X continue; /* Unix: '*' and '?' do not match leading dot */

X /* Need something here for TOS filesystem? [cjh] */

X /* If we've gotten this far, we've read and matched at least one entry
X * successfully (in a previous call), so dirname has been copied into
X * matchname already.
X */
X while ((file = readdir(dir)) != NULL)

X /* May need special TOS handling here. [cjh] */


X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }

X
X closedir(dir); /* have read at least one dir entry; nothing left */
X dir = NULL;
X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X

X} /* end function do_wild() */


X
X
X
X
X

X/**********************/
X/* Function mapattr() */
X/**********************/
X
Xint mapattr()
X{

X ulg tmp = crec.external_file_attributes;
X
X switch (pInfo->hostnum) {
X case UNIX_:

X /* minix filesystem under MiNT on Atari [cjh] */


X case VMS_:
X pInfo->file_attr = (unsigned)(tmp >> 16);
X return 0;
X case AMIGA_:
X tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
X pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
X break;
X /* all remaining cases: expand MSDOS read-only bit into write perms */
X case FS_FAT_:
X case FS_HPFS_:
X case FS_NTFS_:
X case MAC_:
X case ATARI_: /* (used to set = 0666) */

X /* TOS filesystem [cjh] */


X case TOPS20_:
X default:
X tmp = !(tmp & 1) << 1; /* read-only bit --> write perms bits */
X pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
X break;
X } /* end switch (host-OS-created-by) */
X
X /* for originating systems with no concept of "group," "other," "system": */
X umask( (int)(tmp=umask(0)) ); /* apply mask to expanded r/w(/x) perms */
X pInfo->file_attr &= ~tmp;
X

X return 0;
X
X} /* end function mapattr() */


X
X
X
X
X

X/************************/
X/* Function mapname() */
X/************************/
X
Xint mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
X int renamed; /* 2 if warning (skip file because dir doesn't exist), */
X{ /* 3 if error (skip file), 10 if no memory (skip file) */
X char pathcomp[FILNAMSIZ]; /* path-component buffer */
X char *pp, *cp=NULL; /* character pointers */
X char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */
X int quote = FALSE; /* flags */
X int error = 0;
X register unsigned workch; /* hold the character being tested */
X
X
X/*---------------------------------------------------------------------------
X Initialize various pointers and counters and stuff.
X ---------------------------------------------------------------------------*/
X

X if (pInfo->vollabel)
X return IZ_VOL_LABEL; /* can't set disk volume labels in Unix */

X
X /* can create path as long as not just freshening, or if user told us */
X create_dirs = (!fflag || renamed);
X
X created_dir = FALSE; /* not yet */
X
X /* user gave full pathname: don't prepend rootpath */
X renamed_fullpath = (renamed && (*filename == '/'));
X
X if (checkdir((char *)NULL, INIT) == 10)
X return 10; /* initialize path buffer, unless no memory */
X

X *pathcomp = '\0'; /* initialize translation buffer */

X pp = pathcomp; /* point to translation buffer */

X#ifdef MTS
X case ' ': /* change spaces to underscore under */
X *pp++ = '_'; /* MTS; leave as spaces under Unix */
X break;
X#endif

X
X default:
X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X
X *pp = '\0'; /* done with pathcomp: terminate it */
X

X /* if not saving them, remove VMS version numbers (appended ";###") */

X} /* end function mapname() */
X
X
X
X


X#if 0 /*========== NOTES ==========*/
X
X extract-to dir: a:path/
X buildpath: path1/path2/ ... (NULL-terminated)
X pathcomp: filename
X
X mapname():
X loop over chars in zipfile member name
X checkdir(path component, COMPONENT | CREATEDIR) --> map as required?
X (d:/tmp/unzip/) (disk:[tmp.unzip.)
X (d:/tmp/unzip/jj/) (disk:[tmp.unzip.jj.)
X (d:/tmp/unzip/jj/temp/) (disk:[tmp.unzip.jj.temp.)
X finally add filename itself and check for existence? (could use with rename)
X (d:/tmp/unzip/jj/temp/msg.outdir) (disk:[tmp.unzip.jj.temp]msg.outdir)
X checkdir(name, COPYFREE) --> copy path to name and free space
X

X#endif /* 0 */
X

X/* SHORT_NAMES required for TOS, but it has to co-exist for minix fs... [cjh] */


X#ifdef SHORT_NAMES
X char *old_end = end;
X#endif
X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));
X while ((*end = *pathcomp++) != '\0')
X ++end;

X/* SHORT_NAMES required for TOS, but it has to co-exist for minix fs... [cjh] */


X#ifdef SHORT_NAMES /* path components restricted to 14 chars, typically */
X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
X *(end = old_end + FILENAME_MAX) = '\0';
X#endif
X
X /* GRR: could do better check, see if overrunning buffer as we go:
X * check end-buildpath after each append, set warning variable if
X * within 20 of FILNAMSIZ; then if var set, do careful check when
X * appending. Clear variable when begin new path. */
X

X if ((end-buildpath) > FILNAMSIZ-3) /* need '/', one-char name, '\0' */


X too_long = TRUE; /* check if extracting directory? */
X if (stat(buildpath, &statbuf)) { /* path doesn't exist */
X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpath);
X return 2; /* path doesn't exist: nothing to do */
X }
X if (too_long) {
X fprintf(stderr, "checkdir error: path too long: %s\n",
X buildpath);
X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }

X if (mkdir(buildpath, 0777) == -1) { /* create the directory */


X fprintf(stderr, "checkdir error: can't create %s\n\
X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {
X fprintf(stderr, "checkdir error: %s exists but is not directory\n\
X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {
X fprintf(stderr, "checkdir error: path too long: %s\n", buildpath);
X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }

X *end++ = '/';

X/* SHORT_NAMES required for TOS, but it has to co-exist for minix fs... [cjh] */


X#ifdef SHORT_NAMES
X char *old_end = end;
X#endif
X
X Trace((stderr, "appending filename [%s]\n", pathcomp));
X while ((*end = *pathcomp++) != '\0') {
X ++end;

X/* SHORT_NAMES required for TOS, but it has to co-exist for minix fs... [cjh] */


X#ifdef SHORT_NAMES /* truncate name at 14 characters, typically */
X if ((end-old_end) > FILENAME_MAX) /* GRR: proper constant? */
X *(end = old_end + FILENAME_MAX) = '\0';
X#endif
X if ((end-buildpath) >= FILNAMSIZ) {
X *--end = '\0';
X fprintf(stderr, "checkdir warning: path too long; truncating\n\
Xcheckdir warning: path too long; truncating\n\
X %s\n -> %s\n", filename, buildpath);
X fflush(stderr);
X return 1; /* filename truncated */
X }
X }
X Trace((stderr, "buildpath now = [%s]\n", buildpath));
X return 0; /* could check for existence here, prompt for new name... */
X }
X
X/*---------------------------------------------------------------------------
X INIT: allocate and initialize buffer space for the file currently being
X extracted. If file was renamed with an absolute path, don't prepend the
X extract-to path.
X ---------------------------------------------------------------------------*/
X

X/* GRR: for VMS and TOPS-20, add up to 13 to strlen */

X
X if (FUNCTION == INIT) {
X Trace((stderr, "initializing buildpath to "));

X if ((buildpath = (char *)malloc(strlen(filename)+rootlen+1)) == NULL)

X if (pathcomp[rootlen-1] == '/') {


X pathcomp[--rootlen] = '\0';
X had_trailing_pathsep = TRUE;
X }
X if (rootlen > 0 && (stat(pathcomp, &statbuf) ||
X !S_ISDIR(statbuf.st_mode))) /* path does not exist */
X {
X if (!create_dirs /* || iswild(pathcomp) */
X#ifdef OLD_EXDIR
X || !had_trailing_pathsep
X#endif
X ) {
X rootlen = 0;

X return 2; /* skip (or treat as stored file) */


X }
X /* create the directory (could add loop here to scan pathcomp
X * and create more than one level, but why really necessary?) */

X if (mkdir(pathcomp, 0777) == -1) {


X fprintf(stderr,
X "checkdir: can't create extraction directory: %s\n",
X pathcomp);
X fflush(stderr);
X rootlen = 0; /* path didn't exist, tried to create, and */
X return 3; /* failed: file exists, or 2+ levels required */
X }
X }
X if ((rootpath = (char *)malloc(rootlen+2)) == NULL) {
X rootlen = 0;
X return 10;
X }
X strcpy(rootpath, pathcomp);

X rootpath[rootlen++] = '/';


X rootpath[rootlen] = '\0';
X }
X Trace((stderr, "rootpath now = [%s]\n", rootpath));
X return 0;
X }
X#endif /* !SFX || SFX_EXDIR */
X
X/*---------------------------------------------------------------------------
X END: free rootpath, immediately prior to program exit.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == END) {
X Trace((stderr, "freeing rootpath\n"));
X if (rootlen > 0)
X free(rootpath);
X return 0;
X }
X
X return 99; /* should never reach */
X

X} /* end function checkdir() */
X
X
X
X


X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()
X{

X static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

X long m_time;


X int yr, mo, dy, hh, mm, ss, leap, days;
X struct utimbuf tp;
X# define YRBASE 1970

X extern long timezone; /* seems ok for Atari if undefine __STRICT_ANSI__ */
X /* [cjh] */


X
X/*---------------------------------------------------------------------------
X If symbolic links are supported, allocate a storage area, put the uncom-
X pressed "data" in it, and create the link. Since we know it's a symbolic
X link to start with, we shouldn't have to worry about overflowing unsigned
X ints with unsigned longs.

X ---------------------------------------------------------------------------*/
X
X /* symlinks allowed on minix filesystems [cjh]
X * Hopefully this will work properly... We won't bother to try if
X * MiNT isn't present; the symlink should fail if we're on a TOS
X * filesystem.
X * BUG: should we copy the original file to the "symlink" if the
X * link fails?
X */


X if (symlnk) {
X unsigned ucsize = (unsigned)lrec.ucsize;
X char *linktarget = (char *)malloc((unsigned)lrec.ucsize+1);
X
X fclose(outfile); /* close "data" file... */
X outfile = fopen(filename, FOPR); /* ...and reopen for reading */
X if (!linktarget || (fread(linktarget, 1, ucsize, outfile) != ucsize)) {

X fprintf(stderr, "\nwarning: symbolic link (%s) failed\n",


X filename);
X if (linktarget)
X free(linktarget);
X fclose(outfile);

X return;
X }


X fclose(outfile); /* close "data" file for good... */
X unlink(filename); /* ...and delete it */
X linktarget[ucsize] = '\0';

X fprintf(stdout, "-> %s ", linktarget);


X if (symlink(linktarget, filename)) /* create the real link */
X perror("symlink error");
X free(linktarget);

X return; /* can't set time on symlinks */
X }

X /* This seems ok, if you undefine __STRICT_ANSI__; use tzset(). [cjh] */


X tzset(); /* get `timezone' */
X m_time += timezone; /* seconds WEST of GMT: add */

X
X /* adjust for daylight savings time (or local equivalent) */

X if (localtime(&m_time)->tm_isdst)
X m_time -= 60L * 60L; /* adjust for daylight savings time */

X
X /* set the file's access and modification times */
X tp.actime = tp.modtime = m_time;
X if (utime(filename, &tp))

X fprintf(stderr, "warning: can't set the time for %s\n", filename);
X
X} /* end function close_outfile() */
X
X
X
X


X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#ifdef __TURBOC__


X char buf[40];
X#endif
X
X printf(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else
X# if 0
X "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
X# else

X# ifdef __TURBOC__
X "Turbo C", (sprintf(buf, " (0x%04x = %d)", __TURBOC__, __TURBOC__), buf),


X# else
X "unknown compiler", "",
X# endif
X# endif
X#endif
X

X#ifdef __MINT__
X "Atari TOS/MiNT",
X#else
X "Atari TOS",
X#endif
X
X#if defined(atarist) || defined(ATARIST)
X " (Atari ST/TT/Falcon030)",


X#else
X "",
X#endif
X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X
X} /* end function version() */
X
X#endif /* !SFX */

END_OF_FILE
if test 26647 -ne `wc -c <'unzip-5.12/atari/atari.c'`; then
echo shar: \"'unzip-5.12/atari/atari.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/atari/atari.c'
fi
if test -f 'unzip-5.12/match.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/match.c'\"
else
echo shar: Extracting \"'unzip-5.12/match.c'\" \(10263 characters\)
sed "s/^X//" >'unzip-5.12/match.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X match.c
X
X The match() routine recursively compares a string to a "pattern" (regular
X expression), returning TRUE if a match is found or FALSE if not. This
X version is specifically for use with unzip.c: as did the previous match()
X routines from SEA and J. Kercheval, it leaves the case (upper, lower, or
X mixed) of the string alone, but converts any uppercase characters in the
X pattern to lowercase if indicated by the global var pInfo->lcflag (which
X is to say, string is assumed to have been converted to lowercase already,
X if such was necessary).
X
X GRR: reversed order of text, pattern in matche() (now same as match());
X added ignore_case/ic flags, Case() macro.
X
X PaulK: replaced matche() with recmatch() from Zip, modified to have an
X ignore_case argument; replaced test frame with simpler one.
X
X ---------------------------------------------------------------------------
X
X Copyright on recmatch() from Zip's util.c (although recmatch() was almost
X certainly written by Mark Adler...ask me how I can tell :-) ):
X
X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
X Kai Uwe Rommel and Igor Mandrichenko.
X


X Permission is granted to any individual or institution to use, copy,

X or redistribute this software so long as all of the original files are
X included unmodified, that it is not sold for profit, and that this copy-
X right notice is retained.
X
X ---------------------------------------------------------------------------
X
X Match the pattern (wildcard) against the string (fixed):
X
X match(string, pattern, ignore_case);
X
X returns TRUE if string matches pattern, FALSE otherwise. In the pattern:
X
X `*' matches any sequence of characters (zero or more)
X `?' matches any single character
X [SET] matches any character in the specified set,
X [!SET] or [^SET] matches any character not in the specified set.
X
X A set is composed of characters or ranges; a range looks like ``character
X hyphen character'' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
X characters allowed in the [..] pattern construct. Other characters are
X allowed (i.e., 8-bit characters) if your system will support them.
X
X To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
X side or outside a [..] construct and match the character exactly, precede
X it with a ``\'' (backslash).
X
X Note that "*.*" and "*." are treated specially under MS-DOS if DOSWILD is
X defined. See the DOSWILD section below for an explanation. Note also
X that with VMSWILD defined, '%' is used instead of '?', and sets (ranges)
X are delimited by () instead of [].


X
X ---------------------------------------------------------------------------*/
X
X
X

X/* define ToLower() in here (for Unix, define ToLower to be macro (using
X * isupper()); otherwise just use tolower() */
X#include "unzip.h"
X
X#if 0 /* this is not useful until it matches Amiga names insensitively */
X#ifdef AMIGA /* some other platforms might also want to use this */
X# define ANSI_CHARSET /* MOVE INTO UNZIP.H EVENTUALLY */


X#endif
X#endif /* 0 */
X

X#ifdef ANSI_CHARSET
X# ifdef ToLower
X# undef ToLower
X# endif
X /* uppercase letters are values 41 thru 5A, C0 thru D6, and D8 thru DE */
X# define IsUpper(c) (c>=0xC0 ? c<=0xDE && c!=0xD7 : c>=0x41 && c<=0x5A)
X# define ToLower(c) (IsUpper((uch) c) ? (unsigned) c | 0x20 : (unsigned) c)
X#endif
X#define Case(x) (ic? ToLower(x) : (x))
X
X#ifdef VMSWILD
X# define WILDCHAR '%'
X# define BEG_RANGE '('
X# define END_RANGE ')'
X#else
X# define WILDCHAR '?'
X# define BEG_RANGE '['
X# define END_RANGE ']'
X#endif
X
X#if 0 /* GRR: add this to unzip.h someday... */
X#if !(defined(MSDOS) && defined(DOSWILD))
X#define match(s,p,ic) (recmatch((uch *)p,(uch *)s,ic) == 1)
Xint recmatch OF((uch *pattern, uch *string, int ignore_case));


X#endif
X#endif /* 0 */

Xstatic int recmatch OF((uch *pattern, uch *string, int ignore_case));
X
X
X
X/* match() is a shell to recmatch() to return only Boolean values. */
X
Xint match(string, pattern, ignore_case)
X char *string, *pattern;
X int ignore_case;
X{
X#if (defined(MSDOS) && defined(DOSWILD))
X char *dospattern;
X int j = strlen(pattern);
X
X/*---------------------------------------------------------------------------
X Optional MS-DOS preprocessing section: compare last three chars of the
X wildcard to "*.*" and translate to "*" if found; else compare the last
X two characters to "*." and, if found, scan the non-wild string for dots.
X If in the latter case a dot is found, return failure; else translate the
X "*." to "*". In either case, continue with the normal (Unix-like) match
X procedure after translation. (If not enough memory, default to normal
X match.) This causes "a*.*" and "a*." to behave as MS-DOS users expect.
X ---------------------------------------------------------------------------*/
X
X if ((dospattern = (char *)malloc(j+1)) != NULL) {
X strcpy(dospattern, pattern);
X if (!strcmp(dospattern+j-3, "*.*")) {
X dospattern[j-2] = '\0'; /* nuke the ".*" */
X } else if (!strcmp(dospattern+j-2, "*.")) {
X char *p = strchr(string, '.');
X
X if (p) { /* found a dot: match fails */
X free(dospattern);
X return 0;
X }
X dospattern[j-1] = '\0'; /* nuke the end "." */
X }
X j = recmatch((uch *)dospattern, (uch *)string, ignore_case);
X free(dospattern);
X return j == 1;
X } else
X#endif /* MSDOS && DOSWILD */
X return recmatch((uch *)pattern, (uch *)string, ignore_case) == 1;
X}
X
X
X
Xstatic int recmatch(p, s, ic)
X uch *p; /* sh pattern to match */
X uch *s; /* string to which to match it */
X int ic; /* true for case insensitivity */
X/* Recursively compare the sh pattern p with the string s and return 1 if
X * they match, and 0 or 2 if they don't or if there is a syntax error in the
X * pattern. This routine recurses on itself no more deeply than the number
X * of characters in the pattern. */
X{
X unsigned int c; /* pattern char or start of range in [-] loop */
X
X /* Get first character, the pattern for new recmatch calls follows */
X c = *p++;
X
X /* If that was the end of the pattern, match if string empty too */
X if (c == 0)
X return *s == 0;
X
X /* '?' (or '%') matches any character (but not an empty string) */
X if (c == WILDCHAR)
X return *s ? recmatch(p, s + 1, ic) : 0;
X
X /* '*' matches any number of characters, including zero */
X#ifdef AMIGA
X if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
X c = '*', p++;
X#endif /* AMIGA */
X if (c == '*') {
X if (*p == 0)
X return 1;
X for (; *s; s++)
X if ((c = recmatch(p, s, ic)) != 0)
X return (int)c;
X return 2; /* 2 means give up--match will return false */
X }
X
X /* Parse and process the list of characters and ranges in brackets */
X if (c == BEG_RANGE) {
X int e; /* flag true if next char to be taken literally */
X uch *q; /* pointer to end of [-] group */
X int r; /* flag true to match anything but the range */
X
X if (*s == 0) /* need a character to match */
X return 0;
X p += (r = (*p == '!' || *p == '^')); /* see if reverse */
X for (q = p, e = 0; *q; q++) /* find closing bracket */
X if (e)
X e = 0;
X else
X if (*q == '\\') /* GRR: change to ^ for MS-DOS, OS/2? */
X e = 1;
X else if (*q == END_RANGE)
X break;
X if (*q != END_RANGE) /* nothing matches if bad syntax */
X return 0;
X for (c = 0, e = *p == '-'; p < q; p++) { /* go through the list */
X if (e == 0 && *p == '\\') /* set escape flag if \ */
X e = 1;
X else if (e == 0 && *p == '-') /* set start of range if - */
X c = *(p-1);
X else {
X unsigned int cc = Case(*s);
X
X if (*(p+1) != '-')
X for (c = c ? c : *p; c <= *p; c++) /* compare range */
X if ((unsigned)Case(c) == cc) /* typecast for MSC bug */
X return r ? 0 : recmatch(q + 1, s + 1, ic);
X c = e = 0; /* clear range, escape flags */
X }
X }
X return r ? recmatch(q + 1, s + 1, ic) : 0; /* bracket match failed */
X }
X
X /* if escape ('\'), just compare next character */
X if (c == '\\' && (c = *p++) == 0) /* if \ at end, then syntax error */
X return 0;
X
X /* just a character--compare it */
X return Case((uch)c) == Case(*s) ? recmatch(p, ++s, ic) : 0;
X
X} /* end function recmatch() */


X
X
X
X
X

Xint iswild(p) /* originally only used for stat()-bug workaround in */
X char *p; /* VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
X{ /* now used in process_zipfiles() as well */
X for (; *p; ++p)
X if (*p == '\\' && *(p+1))
X ++p;
X#ifdef VMS
X else if (*p == '%' || *p == '*')
X#else /* !VMS */
X#ifdef AMIGA
X else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
X#else /* !AMIGA */
X else if (*p == '?' || *p == '*' || *p == '[')
X#endif /* ?AMIGA */
X#endif /* ?VMS */
X return TRUE;
X
X return FALSE;
X
X} /* end function iswild() */


X
X
X
X
X

X#ifdef TEST_MATCH
X
X#define put(s) {fputs(s,stdout); fflush(stdout);}
X
Xvoid main()
X{
X char pat[256], str[256];


X
X for (;;) {

X put("Pattern (return to exit): ");
X gets(pat);
X if (!pat[0])
X break;
X for (;;) {
X put("String (return for new pattern): ");
X gets(str);
X if (!str[0])
X break;
X printf("Case sensitive: %s insensitive: %s\n",
X match(str, pat, 0) ? "YES" : "NO",
X match(str, pat, 1) ? "YES" : "NO");
X }
X }
X exit(0);
X}
X
X#endif /* TEST_MATCH */
END_OF_FILE
if test 10263 -ne `wc -c <'unzip-5.12/match.c'`; then
echo shar: \"'unzip-5.12/match.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/match.c'
fi
if test -f 'unzip-5.12/unix/unzip.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/unzip.1'\"
else
echo shar: Extracting \"'unzip-5.12/unix/unzip.1'\" \(30113 characters\)
sed "s/^X//" >'unzip-5.12/unix/unzip.1' <<'END_OF_FILE'
X.\" Info-ZIP grants permission to any individual or institution to use, copy,
X.\" or redistribute this software, so long as: (1) all of the original files
X.\" are included; (2) it is not sold for profit; and (3) this notice is re-
X.\" tained.
X.\"
X.\" unzip.1 by Greg Roelofs, Fulvio Marino, Jim van Zandt and others.
X.\"
X.\" =========================================================================
X.\" define .Y macro (for user-command examples; normal Courier font):
X.de Y
X.ft CW
X.in +4n
X.nf
X\&\\$1
X.ft
X.in
X.fi
X..
X.\" =========================================================================
X.TH UNZIP 1L "28 Aug 94 (v5.12)"
X.SH NAME
Xunzip \- list, test and extract compressed files in a ZIP archive
X.PD
X.\" =========================================================================
X.SH SYNOPSIS
X\fBunzip\fP [\fB\-Z\fP] [\fB\-cflptuvz\fP[\fBabjnoqsCLV$\fP]]
X\fIfile\fP[\fI.zip\fP] [\fIfile(s)\fP\ .\|.\|.]
X[\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.] [\fB\-d\fP\ \fIexdir\fP]
X.PD
X.\" =========================================================================
X.SH DESCRIPTION
X\fIunzip\fP will list, test, or extract files from a ZIP archive, commonly
Xfound on MS-DOS systems. The default behavior (with no options) is to extract
Xinto the current directory (and subdirectories below it) all files from the
Xspecified ZIP archive. A companion program, \fIzip\fP(1L), creates ZIP
Xarchives; both programs are compatible with archives created by PKWARE's
X\fIPKZIP\fP and \fIPKUNZIP\fP for MS-DOS, but in many cases the program
Xoptions or default behaviors differ.
X.PD
X.\" =========================================================================
X.SH ARGUMENTS
X.TP
X.IR file [ .zip ]
XPath of the ZIP archive(s). If the file specification is a wildcard,
Xeach matching file is processed in an order determined by the operating
Xsystem (or file system). Only the filename can be a wildcard; the path
Xitself cannot. Wildcard expressions are similar to Unix \fIegrep\fP(1)
X(regular) expressions and may contain:
X.RS
X.IP *
Xmatches a sequence of 0 or more characters
X.IP ?
Xmatches exactly 1 character
X.IP [.\|.\|.]
Xmatches any single character found inside the brackets; ranges are specified
Xby a beginning character, a hyphen, and an ending character. If an exclamation
Xpoint or a caret (`!' or `^') follows the left bracket, then the range of
Xcharacters within the brackets is complemented (that is, anything \fIexcept\fP
Xthe characters inside the brackets is considered a match).
X.RE
X.IP
X(Be sure to quote any character which might otherwise be interpreted or
Xmodified by the operating system, particularly under Unix and VMS.) If no
Xmatches are found, the specification is assumed to be a literal filename;
Xand if that also fails, the suffix \fC.zip\fP is appended. Note that
Xself-extracting ZIP files are supported, as with any other ZIP archive;
Xjust specify the \fC.exe\fP suffix (if any) explicitly.
X.IP [\fIfile(s)\fP]
XAn optional list of archive members to be processed, separated by spaces.
X(VMS versions compiled with VMSCLI defined must delimit files with commas
Xinstead. See \fB\-v\fP in \fBOPTIONS\fP below.)
XRegular expressions (wildcards) may be used to match multiple members; see
Xabove. Again, be sure to quote expressions that would otherwise be expanded
Xor modified by the operating system.
X.IP [\fB\-x\fP\ \fIxfile(s)\fP]
XAn optional list of archive members to be excluded from processing.
XSince wildcard characters match directory separators (`/'), this option
Xmay be used to exclude any files which are in subdirectories. For
Xexample, ``\fCunzip foo *.[ch] -x */*\fR'' would extract all C source files
Xin the main directory, but none in any subdirectories. Without the \fB\-x\fP
Xoption, all C source files in all directories within the zipfile would be
Xextracted.
X.IP [\fB\-d\fP\ \fIexdir\fP]
XAn optional directory to which to extract files. By default, all files
Xand subdirectories are recreated in the current directory; the \fB\-d\fP
Xoption allows extraction in an arbitrary directory (always assuming one
Xhas permission to write to the directory). This option need not appear
Xat the end of the command line; it is also accepted immediately after the
Xzipfile specification, or between the \fIfile(s)\fP and the \fB\-x\fP
Xoption. The option and directory may
Xbe concatenated without any white space between them, but note that this
Xmay cause normal shell behavior to be suppressed. In particular,
X``\fC\-d\ ~\fR'' (tilde) is expanded by Unix C shells into the name
Xof the user's home directory, but ``\fC\-d~\fR'' is treated as a
Xliteral subdirectory ``\fB~\fP'' of the current directory.
X.\" =========================================================================
X.SH OPTIONS
XNote that, in order to support obsolescent hardware, \fIunzip\fP's usage
Xscreen is limited to 22 or 23 lines and should therefore be considered a
Xreminder of the basic \fIunzip\fP syntax rather than an exhaustive list
Xof all possible flags.
X.TP
X.B \-Z
X\fIzipinfo\fP(1L) mode. If the first option on the command line is \fB\-Z\fP,
Xthe remaining options are taken to be \fIzipinfo\fP(1L) options. See the
Xappropriate manual page for a description of these options.
X.TP
X.B \-c
Xextract files to stdout/screen (``CRT''). This option is similar to the
X\fB\-p\fP option except that the name of each file is printed as it is
Xextracted, the \fB\-a\fP option is allowed, and ASCII-EBCDIC conversion
Xis automatically performed if appropriate. This option is not listed in
Xthe \fIunzip\fP usage screen.
X.TP
X.B \-f
Xfreshen existing files, i.e., extract only those files which
Xalready exist on disk and which are newer than the disk copies. By
Xdefault \fIunzip\fP queries before overwriting, but the \fB\-o\fP option
Xmay be used to suppress the queries. Note that under many operating systems,
Xthe TZ (timezone) environment variable must be set correctly in order for
X\fB\-f\fP and \fB\-u\fP to work properly (under Unix the variable is usually
Xset automatically). The reasons for this are somewhat subtle but
Xhave to do with the differences between DOS-format file times (always local
Xtime) and Unix-format times (always in GMT) and the necessity to compare the
Xtwo. A typical TZ value is ``PST8PDT'' (US Pacific time with automatic
Xadjustment for Daylight Savings Time or ``summer time'').
X.TP
X.B \-l
Xlist archive files (short format). The names, uncompressed file sizes and
Xmodification dates and times of the specified files are printed, along
Xwith totals for all files specified. In addition, the zipfile comment and
Xindividual file comments (if any) are displayed. If a file was archived
Xfrom a single-case file system (for example, the old MS-DOS FAT file system)
Xand the \fB\-L\fP option was given, the filename is converted to lowercase
Xand is prefixed with a caret (^).
X.TP
X.B \-p
Xextract files to pipe (stdout). Nothing but the file data is sent to
Xstdout, and the files are always extracted in binary format, just as they
Xare stored (no conversions).
X.TP
X.B \-t
Xtest archive files. This option extracts each specified file in memory
Xand compares the CRC (cyclic redundancy check, an enhanced checksum) of
Xthe expanded file with the original file's stored CRC value.
X.TP
X.B \-u
Xupdate existing files and create new ones if needed. This option performs
Xthe same function as the \fB\-f\fP option, extracting (with query) files
Xwhich are newer than those with the same name on disk, and in addition it
Xextracts those files which do not already exist on disk. See \fB\-f\fP
Xabove for information on setting the timezone properly.
X.TP
X.B \-v
Xbe verbose or print diagnostic version info. This option has evolved and
Xnow behaves as both an option and a modifier. As an option it has two
Xpurposes: when a zipfile is specified with no other options, \fB\-v\fP
Xlists archive files verbosely, adding to the \fB\-l\fP info the compression
Xmethod, compressed size, compression ratio and 32-bit CRC. When no zipfile
Xis specified (that is, the complete command is simply ``\fCunzip -v\fR''), a
Xdiagnostic screen is printed. In addition to the normal header with release
Xdate and version, \fIunzip\fP lists the home Info-ZIP ftp site and where to
Xfind a list of other ftp and non-ftp sites; the target operating system for
Xwhich it was compiled, as well as (possibly) the hardware on which it was
Xcompiled, the compiler and version used, and the compilation date; any special
Xcompilation options which might affect the program's operation (see also
X\fBDECRYPTION\fP below); and any options stored in environment variables
Xwhich might do the same (see \fBENVIRONMENT OPTIONS\fP below). As a
Xmodifier it works in conjunction with other options (e.g., \fB\-t\fP) to
Xproduce more verbose or debugging output; this is not yet fully implemented
Xbut will be in future releases.
X.TP
X.B \-z
Xdisplay only the archive comment.
X.PD
X.\" =========================================================================
X.SH MODIFIERS
X.TP
X.B \-a
Xconvert text files. Ordinarily all files are extracted exactly as they
Xare stored (as ``binary'' files). The \fB\-a\fP option causes files identified
Xby \fIzip\fP as text files (those with the `t' label in \fIzipinfo\fP
Xlistings, rather than `b') to be automatically extracted as such, converting
Xline endings, end-of-file characters and the character set itself as necessary.
X(For example, Unix files use line feeds (LFs) for end-of-line (EOL) and
Xhave no end-of-file (EOF) marker; Macintoshes use carriage returns (CRs)
Xfor EOLs; and most PC operating systems use CR+LF for EOLs and control-Z for
XEOF. In addition, IBM mainframes and the Michigan Terminal System use EBCDIC
Xrather than the more common ASCII character set, and NT supports Unicode.)
XNote that \fIzip\fP's identification of text files is by no means perfect; some
X``text'' files may actually be binary and vice versa. \fIunzip\fP therefore
Xprints ``\fC[text]\fR'' or ``\fC[binary]\fR'' as a visual check for each file
Xit extracts when using the \fB\-a\fP option. The \fB\-aa\fP option forces
Xall files to be extracted as text, regardless of the supposed file type.
X.TP
X.B \-b
Xtreat all files as binary (no text conversions). This is a shortcut for
X\fB\-\-\-a\fP.
X.TP
X.B \-C
Xmatch filenames case-insensitively. \fIunzip\fP's philosophy is ``you get
Xwhat you ask for'' (this is also responsible for the \fB\-L\fP/\fB\-U\fP
Xchange; see the relevant options below). Because some filesystems are fully
Xcase-sensitive (notably those under the Unix operating system) and because
Xboth ZIP archives and \fIunzip\fP itself are portable across platforms,
X\fIunzip\fP's default behavior is to match both wildcard and literal filenames
Xcase-sensitively. That is, specifying ``\fCmakefile\fR'' on the command line
Xwill \fIonly\fP match ``makefile'' in the archive, not ``Makefile'' or
X``MAKEFILE'' (and similarly for wildcard specifications). Since this does
Xnot correspond to the behavior of many other operating/file systems (for
Xexample, OS/2 HPFS which preserves mixed case but is not sensitive to it),
Xthe \fB\-C\fP option may be used to force all filename matches to be
Xcase-insensitive. In the example above, all three files would then match
X``\fCmakefile\fR'' (or ``\fCmake*\fR'', or similar). The \fB\-C\fP option
Xaffects files in both the normal file list and the excluded-file list (xlist).
X.TP
X.B \-j
Xjunk paths. The archive's directory structure is not recreated; all files
Xare deposited in the extraction directory (by default, the current one).
X.TP
X.B \-L
Xconvert to lowercase any filename originating on an uppercase-only operating
Xsystem or filesystem. (This was \fIunzip\fP's default behavior in releases
Xprior to 5.11; the new default behavior is identical to the old behavior with
Xthe \fB\-U\fP option, which is now obsolete and will be removed in a future
Xrelease.) Depending on the archiver, files archived under single-case
Xfilesystems (VMS, old MS-DOS FAT, etc.) may be stored as all-uppercase names;
Xthis can be ugly or inconvenient when extracting to a case-preserving
Xfilesystem such as OS/2 HPFS or a case-sensitive one such as under
XUnix. By default \fIunzip\fP lists and extracts such filenames exactly as
Xthey're stored (excepting truncation, conversion of unsupported characters,
Xetc.); this option causes the names of all files from certain systems to be
Xconverted to lowercase.
X.TP
X.B \-n
Xnever overwrite existing files. If a file already exists, skip the extraction
Xof that file without prompting. By default \fIunzip\fP queries before
Xextracting any file which already exists; the user may choose to overwrite
Xonly the current file, overwrite all files, skip extraction of the current
Xfile, skip extraction of all existing files, or rename the current file.
X.TP
X.B \-o
Xoverwrite existing files without prompting. This is a dangerous option, so
Xuse it with care. (It is often used with \fB\-f\fP, however.)
X.TP
X.B \-q
Xperform operations quietly (\fB\-qq\fP = even quieter). Ordinarily \fIunzip\fP
Xprints the names of the files it's extracting or testing, the extraction
Xmethods, any file or zipfile comments which may be stored in the archive,
Xand possibly a summary when finished with each archive. The \fB\-q\fP[\fBq\fP]
Xoptions suppress the printing of some or all of these messages.
X.TP
X.B \-s
X[OS/2, NT, MS-DOS] convert spaces in filenames to underscores. Since all PC
Xoperating systems allow spaces in filenames, \fIunzip\fP by default extracts
Xfilenames with spaces intact (e.g., ``\fCEA\ DATA.\ SF\fR''). This can be
Xawkward, however, since MS-DOS in particular does not gracefully support
Xspaces in filenames. Conversion of spaces to underscores can eliminate the
Xawkwardness in some cases.
X.TP
X.B \-U
X(obsolete; to be removed in a future release) leave filenames uppercase if
Xcreated under MS-DOS, VMS, etc. See \fB\-L\fP above.
X.TP
X.B \-V
Xretain (VMS) file version numbers. VMS files can be stored with a version
Xnumber, in the format \fCfile.ext;##\fP. By default the ``\fC;##\fR'' version
Xnumbers are stripped, but this option allows them to be retained. (On
Xfilesystems which limit filenames to particularly short lengths, the version
Xnumbers may be truncated or stripped regardless of this option.)
X.TP
X.B \-X
X[VMS] restore owner/protection info (may require system privileges). Ordinary
Xfile attributes are always restored, but this option allows UICs to be restored
Xas well. [The next version of \fIunzip\fP will support Unix UID/GID info as
Xwell, and possibly NT permissions.]
X.TP
X.B \-$
X[MS-DOS, OS/2, NT, Amiga] restore the volume label if the extraction medium is
Xremovable (e.g., a diskette). Doubling the option (\fB\-$$\fP) allows fixed
Xmedia (hard disks) to be labelled as well. By default, volume labels are
Xignored.
X.PD
X.\" =========================================================================
X.SH ENVIRONMENT OPTIONS
X\fIunzip\fP's default behavior may be modified via options placed in
Xan environment variable. This can be done with any option, but it
Xis probably most useful with the \fB\-a\fP, \fB\-L\fP, \fB\-C\fP, \fB\-q\fP,
X\fB\-o\fP, or \fB\-n\fP modifiers: make \fIunzip\fP auto-convert text
Xfiles by default, make it convert filenames from uppercase systems to
Xlowercase, make it match names case-insensitively, make it quieter,
Xor make it always overwrite or never overwrite files as it extracts
Xthem. For example, to make \fIunzip\fP act as quietly as possible, only
Xreporting errors, one would use one of the following commands:
X.LP
X.DT
X.ft CW
X.in +4n
X.ta \w'UNZIP=\-qq; export UNZIP'u+4n
X.in
X.ft
X.PD 0
X.Y "UNZIP=\-qq; export UNZIP\t\fRUnix Bourne shell"
X.Y "setenv UNZIP \-qq\t\fRUnix C shell"
X.Y "set UNZIP=\-qq\t\fROS/2 or MS-DOS"
X.Y "define UNZIP_OPTS ""\-qq""\t\fRVMS (quotes for \fIlowercase\fP)"
X.PD
X.LP
XEnvironment options are, in effect, considered to be just like any other
Xcommand-line options, except that they are effectively the first options
Xon the command line. To override an environment option, one may use the
X``minus operator'' to remove it. For instance, to override one of the
Xquiet-flags in the example above, use the command
X.LP
X.Y "unzip \-\-q[\fIother options\fC] zipfile"
X.LP
XThe first hyphen is the normal
Xswitch character, and the second is a minus sign, acting on the q option.
XThus the effect here is to cancel one quantum of quietness. To cancel
Xboth quiet flags, two (or more) minuses may be used:
X.LP
X.PD 0
X.Y "unzip \-t\-\-q zipfile"
X.Y "unzip \-\-\-qt zipfile"
X.PD
X.LP
X(the two are equivalent). This may seem awkward
Xor confusing, but it is reasonably intuitive: just ignore the first
Xhyphen and go from there. It is also consistent with the behavior of
XUnix \fInice\fP(1).
X.LP
XAs suggested by the examples above, the default variable names are UNZIP_OPTS
Xfor VMS (where the symbol used to install \fIunzip\fP as a foreign command
Xwould otherwise be confused with the environment variable), and UNZIP
Xfor all other operating systems. For compatibility with \fIzip\fP(1L),
XUNZIPOPT is also accepted (don't ask). If both UNZIP and UNZIPOPT
Xare defined, however, UNZIP takes precedence. \fIunzip\fP's diagnostic
Xoption (\fB\-v\fP with no zipfile name) can be used to check the values
Xof all four possible \fIunzip\fP and \fIzipinfo\fP environment variables.
X.LP
XThe timezone variable (TZ) should be set according to the local timezone
Xin order for the \fB\-f\fP and \fB\-u\fP to operate correctly. See the
Xdescription of \fB\-f\fP above for details. This variable may also be
Xnecessary in order for timestamps on extracted files to be set correctly.
X.PD
X.\" =========================================================================
X.SH DECRYPTION
XEncrypted archives are fully supported by Info-ZIP software, but due to
XUnited States export restrictions, the encryption and decryption sources
Xare not packaged with the regular \fIunzip\fP and \fIzip\fP distributions.
XSince the crypt sources were written by Europeans, however, they are
Xfreely available at sites throughout the world; see the file ``Where'' in
Xany Info-ZIP source or binary distribution for locations both inside and
Xoutside the US.
X.LP
XBecause of the separate distribution, not all compiled versions of \fIunzip\fP
Xsupport decryption. To check a version for crypt support, either attempt to
Xtest or extract an encrypted archive, or else check \fIunzip\fP's diagnostic
Xscreen (see the \fB\-v\fP option above) for ``\fC[decryption]\fR'' as one of
Xthe special compilation options.
X.LP
XThere are no runtime options for decryption; if a zipfile member is encrypted,
X\fIunzip\fP will prompt for the password without echoing what is typed.
X\fIunzip\fP continues to use the same password as long as it appears to be
Xvalid; it does this by testing a 12-byte header. The correct password will
Xalways check out against the header, but there is a 1-in-256 chance that an
Xincorrect password will as well. (This is a security feature of the PKWARE
Xzipfile format; it helps prevent brute-force attacks which might otherwise
Xgain a large speed advantage by testing only the header.) In the case that
Xan incorrect password is
Xgiven but it passes the header test anyway, either an incorrect CRC will be
Xgenerated for the extracted data or else \fIunzip\fP will fail during the
Xextraction because the ``decrypted'' bytes do not constitute a valid
Xcompressed data stream.
X.LP
XIf the first password fails the header check on some file, \fIunzip\fP will
Xprompt for another password, and so on until all files are extracted. If
Xa password is not known, entering a null password (that is, just a carriage
Xreturn) is taken as a signal to skip all further prompting. Only unencrypted
Xfiles in the archive(s) will thereafter be extracted. (Actually that's not
Xquite true; older versions of \fIzip\fP(1L) and \fIzipcloak\fP(1L) allowed
Xnull passwords, so \fIunzip\fP checks each encrypted file to see if the null
Xpassword works. This may result in ``false positives'' and extraction
Xerrors, as noted above.)
X.LP
XNote that there is presently no way to avoid interactive decryption. This
Xis another security feature: plaintext passwords given on the command line
Xor stored in files constitute a risk because they may be seen by others.
XFuture releases may (under protest, with great disapproval) support such
Xshenanigans.
X.PD
X.\" =========================================================================
X.SH EXAMPLES
XTo use \fIunzip\fP to extract all members of the archive \fIletters.zip\fP
Xinto the current directory and subdirectories below it, creating any
Xsubdirectories as necessary:
X.LP
X.Y "unzip letters"
X.LP
XTo extract all members of \fIletters.zip\fP into the current directory only:
X.LP
X.Y "unzip -j letters"
X.LP
XTo test \fIletters.zip\fP, printing only a summary message indicating
Xwhether the archive is OK or not:
X.LP
X.Y "unzip -tq letters"
X.LP
XTo test \fIall\fP zipfiles in the current directory, printing only the
Xsummaries:
X.LP
X.Y "unzip -tq \e*.zip"
X.LP
X(The backslash before the asterisk is only required if the shell expands
Xwildcards, as in Unix; double quotes could have been used instead, as in
Xthe source examples below.)\ \ To extract to standard output all members of
X\fIletters.zip\fP whose names end in \fI.tex\fP, auto-converting to the
Xlocal end-of-line convention and piping the output into \fImore\fP(1):
X.LP
X.Y "unzip \-ca letters \e*.tex | more"
X.LP
XTo extract the binary file \fIpaper1.dvi\fP to standard output and pipe it
Xto a printing program:
X.LP
X.Y "unzip \-p articles paper1.dvi | dvips"
X.LP
XTo extract all FORTRAN and C source files--*.f, *.c, *.h, and Makefile--into
Xthe /tmp directory:
X.LP
X.Y "unzip source.zip ""*.[fch]"" Makefile -d /tmp"
X.LP
X(the double quotes are necessary only in Unix and only if globbing is turned
Xon). To extract all FORTRAN and C source files, regardless of case (e.g.,
Xboth *.c and *.C, and any makefile, Makefile, MAKEFILE or similar):
X.LP
X.Y "unzip \-C source.zip ""*.[fch]"" makefile -d /tmp"
X.LP
XTo extract any such files but convert any uppercase MS-DOS or VMS names to
Xlowercase and convert the line-endings of all of the files to the local
Xstandard (without respect to any files which might be marked ``binary''):
X.LP
X.Y "unzip \-aaCL source.zip ""*.[fch]"" makefile -d /tmp"
X.LP
XTo extract only newer versions of the files already in the current
Xdirectory, without querying (NOTE: be careful of unzipping in one timezone a
Xzipfile created in another--ZIP archives to date contain no timezone
Xinformation, and a ``newer'' file from an eastern timezone may, in fact, be
Xolder):
X.LP
X.Y "unzip \-fo sources"
X.LP
XTo extract newer versions of the files already in the current directory and
Xto create any files not already there (same caveat as previous example):
X.LP
X.Y "unzip \-uo sources"
X.LP
XTo display a diagnostic screen showing which \fIunzip\fP and \fIzipinfo\fP
Xoptions are stored in environment variables, whether decryption support was
Xcompiled in, the compiler with which \fIunzip\fP was compiled, etc.:
X.LP
X.Y "unzip \-v"
X.LP
XIn the last five examples, assume that UNZIP or UNZIP_OPTS is set to -q.
XTo do a singly quiet listing:
X.LP
X.Y "unzip \-l file.zip"
X.LP
XTo do a doubly quiet listing:
X.LP
X.Y "unzip \-ql file.zip"
X.LP
X(Note that the ``\fC.zip\fR'' is generally not necessary.) To do a standard
Xlisting:
X.LP
X.PD 0
X.Y "unzip \-\-ql file.zip"
X.LP
Xor
X.Y "unzip \-l\-q file.zip"
X.LP
Xor
X.Y "unzip \-l\-\-q file.zip\t\fR(extra minuses don't hurt)"
X.PD
X.\" =========================================================================
X.SH TIPS
XThe current maintainer, being a lazy sort, finds it very useful to define
Xa pair of aliases: \fCtt\fP for ``\fCunzip \-tq\fR'' and \fCii\fP for
X``\fCunzip \-Z\fR'' (or ``\fCzipinfo\fR''). One may then simply type
X``\fCtt zipfile\fR'' to test an archive, something which is worth making a
Xhabit of doing. With luck \fIunzip\fP will report ``\fCNo errors detected
Xin zipfile.zip\fP,'' after which one may breathe a sigh of relief.
X.LP
XThe maintainer also finds it useful to set the UNZIP environment variable
Xto ``\fC\-aL\fR'' and is tempted to add ``\fC\-C\fR'' as well. His ZIPINFO
Xvariable is set to ``\fC\-z\fR''.
X.PD
X.\" =========================================================================
X.SH DIAGNOSTICS
XThe exit status (or error level) approximates the exit codes defined by PKWARE
Xand takes on the following values, except under VMS:
X.RS
X.IP 0
Xnormal; no errors or warnings detected.
X.IP 1
Xone or more warning errors were encountered, but processing completed
Xsuccessfully anyway. This includes zipfiles where one or more files
Xwas skipped due to unsupported compression method or encryption with an
Xunknown password.
X.IP 2
Xa generic error in the zipfile format was detected. Processing may have
Xcompleted successfully anyway; some broken zipfiles created by other
Xarchivers have simple work-arounds.
X.IP 3
Xa severe error in the zipfile format was detected. Processing probably
Xfailed immediately.
X.IP 4-8
X\fIunzip\fP was unable to allocate memory for one or more buffers.
X.IP 9
Xthe specified zipfiles were not found.
X.IP 10
Xinvalid options were specified on the command line.
X.IP 11
Xno matching files were found.
X.IP 50
Xthe disk is (or was) full during extraction.
X.IP 51
Xthe end of the ZIP archive was encountered prematurely.
X.RE
X.LP
XVMS interprets standard Unix (or PC) return values as other, scarier-looking
Xthings, so by default \fIunzip\fP always returns 0 (which reportedly gets
Xconverted into a VMS status of 1--i.e., success). There are two compilation
Xoptions available to modify or expand upon this behavior: defining
XRETURN_CODES results in a human-readable explanation of what the real
Xerror status was (but still with a faked ``success'' exit value), while
Xdefining RETURN_SEVERITY causes \fIunzip\fP to exit with a ``real'' VMS
Xstatus. The latter behavior will become the default in future
Xversions unless it is found to conflict with officially defined VMS codes.
XThe current mapping is as follows: 1 (success) for normal exit, 0x7fff0001
Xfor warning errors, and (0x7fff000? + 16*normal_unzip_exit_status) for all
Xother errors, where the `?' is 2 (error) for \fIunzip\fP values 2 and 9-11,
Xand 4 (fatal error) for the remaining ones (3-8, 50, 51). Check the
X``\fCunzip \-v\fR'' output to see whether RETURN_SEVERITY was defined at
Xcompilation time.
X.PD
X.\" =========================================================================
X.SH BUGS
XWhen attempting to extract a corrupted archive, \fIunzip\fP may go into
Xan infinite loop and, if not stopped quickly enough, fill all available disk
Xspace. Compiling with CHECK_EOF should fix this problem for all zipfiles,
Xbut the option was introduced too late in the testing process to be made
Xthe default behavior. Future versions will be robust enough to fail
Xgracefully on damaged archives. Check the ``\fCunzip \-v\fR'' output to
Xsee whether CHECK_EOF was defined during compilation.
X.LP
X[MS-DOS] When extracting or testing files from an archive on a defective
Xfloppy diskette, if the ``Fail'' option is chosen from DOS's ``Abort, Retry,
XFail?'' message, \fIunzip\fP may hang the system, requiring a reboot. Instead,
Xpress control-C (or control-Break) to terminate \fIunzip\fP.
X.LP
XUnder DEC Ultrix, \fIunzip\fP will sometimes fail on long zipfiles (bad CRC,
Xnot always reproducible). This is apparently due either to a hardware bug
X(cache memory) or an operating system bug (improper handling of page faults?).
X.LP
XDates and times of stored directories are not restored.
X.LP
X[OS/2] Extended attributes for existing directories are never updated. This
Xis a limitation of the operating system; \fIunzip\fP has no way to determine
Xwhether the stored attributes are newer or older than the existing ones.
X.LP
X[VMS] When extracting to another directory, only the \fI[.foo]\fP syntax is
Xaccepted for the \fB\-d\fP option; the simple Unix \fIfoo\fP syntax is
Xsilently ignored (as is the less common VMS \fIfoo.dir\fP syntax).
X.LP
X[VMS] When the file being extracted already exists, \fIunzip\fP's query only
Xallows skipping, overwriting or renaming; there should additionally be a
Xchoice for creating a new version of the file. In fact, the ``overwrite''
Xchoice does create a new version; the old version is not overwritten or
Xdeleted.
X.PD
X.\" =========================================================================
X.SH SEE ALSO
X\fIfunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipgrep\fP(1L),
X\fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
X.PD
X.\" =========================================================================
X.SH AUTHORS
XThe primary Info-ZIP authors (current zip-bugs workgroup) are: Jean-loup
XGailly (Zip); Greg R. Roelofs (UnZip); Mark Adler (decompression, fUnZip);
XKai Uwe Rommel (OS/2); Igor Mandrichenko and Hunter Goatley (VMS); John Bush
Xand Paul Kienitz (Amiga); Antoine Verheijen (Macintosh); Chris Herborth
X(Atari); Henry Gessau (NT); Karl Davis, Sergio Monesi and Evan Shattock
X(Acorn Archimedes); and Robert Heath (Windows). The author of the original
Xunzip code upon which Info-ZIP's is based was Samuel H. Smith; Carl Mascott
Xdid the first Unix port; and David P. Kirschbaum organized and led Info-ZIP
Xin its early days. The full list of contributors to UnZip has grown quite
Xlarge; please refer to the CONTRIBS file in the UnZip source distribution
Xfor a relatively complete version.
X.PD
X.\" =========================================================================
X.SH VERSIONS
X.ta \w'vx.xxnn'u +\w'fall 1989'u+3n
X.PD 0
X.IP "v1.2\t15 Mar 89" \w'\t\t'u
XSamuel H. Smith
X.IP "v2.0\t\ 9 Sep 89"
XSamuel H. Smith
X.IP "v2.x\tfall 1989"
Xmany Usenet contributors
X.IP "v3.0\t\ 1 May 90"
XInfo-ZIP (DPK, consolidator)
X.IP "v3.1\t15 Aug 90"
XInfo-ZIP (DPK, consolidator)
X.IP "v4.0\t\ 1 Dec 90"
XInfo-ZIP (GRR, maintainer)
X.IP "v4.1\t12 May 91"
XInfo-ZIP
X.IP "v4.2\t20 Mar 92"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.IP "v5.0\t21 Aug 92"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.IP "v5.01\t15 Jan 93"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.IP "v5.1\t\ 7 Feb 94"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.IP "v5.11\t\ 2 Aug 94"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.IP "v5.12\t28 Aug 94"
XInfo-ZIP (zip-bugs subgroup, GRR)
X.PD
END_OF_FILE
if test 30113 -ne `wc -c <'unzip-5.12/unix/unzip.1'`; then
echo shar: \"'unzip-5.12/unix/unzip.1'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/unzip.1'
fi
echo shar: End of archive 12 \(of 20\).
cp /dev/null ark12isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:06 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 78
Archive-name: unzip/part13

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/funzip.c unzip-5.12/mac/thinkc.hqx
# unzip-5.12/unix/Makefile unzip-5.12/vms/makesfx.com
# Wrapped by kent@sparky on Sat Sep 17 23:33:43 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 13 (of 20)."'
if test -f 'unzip-5.12/funzip.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/funzip.c'\"
else
echo shar: Extracting \"'unzip-5.12/funzip.c'\" \(14247 characters\)
sed "s/^X//" >'unzip-5.12/funzip.c' <<'END_OF_FILE'
X/* funzip.c -- put in the public domain by Mark Adler */
X
X#define VERSION "3.83 of 28 August 1994"


X
X
X/* You can do whatever you like with this source file, though I would
X prefer that if you modify it and redistribute it that you include
X comments to that effect with your name and the date. Thank you.
X
X History:
X vers date who what
X ---- --------- -------------- ------------------------------------

X 1.0 13 Aug 92 M. Adler really simple unzip filter.
X 1.1 13 Aug 92 M. Adler cleaned up somewhat, give help if
X stdin not redirected, warn if more
X zip file entries after the first.
X 1.2 15 Aug 92 M. Adler added check of lengths for stored
X entries, added more help.
X 1.3 16 Aug 92 M. Adler removed redundant #define's, added
X decryption.
X 1.4 27 Aug 92 G. Roelofs added exit(0).
X 1.5 1 Sep 92 K. U. Rommel changed read/write modes for OS/2.
X 1.6 6 Sep 92 G. Roelofs modified to use dummy crypt.c and
X crypt.h instead of -DCRYPT.
X 1.7 23 Sep 92 G. Roelofs changed to use DOS_OS2; included
X crypt.c under MS-DOS.
X 1.8 9 Oct 92 M. Adler improved inflation error msgs.
X 1.9 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch;
X renamed inflate_entry() to inflate();
X adapted to use new, in-place zdecode.
X 2.0 22 Oct 92 M. Adler allow filename argument, prompt for
X passwords and don't echo, still allow
X command-line password entry, but as an
X option.
X 2.1 23 Oct 92 J-l. Gailly fixed crypt/store bug,
X G. Roelofs removed crypt.c under MS-DOS, fixed
X decryption check to compare single byte.
X 2.2 28 Oct 92 G. Roelofs removed declaration of key.
X 2.3 14 Dec 92 M. Adler replaced fseek (fails on stdin for SCO
X Unix V.3.2.4). added quietflg for
X inflate.c.
X 3.0 11 May 93 M. Adler added gzip support
X 3.1 9 Jul 93 K. U. Rommel fixed OS/2 pipe bug (PIPE_ERROR)
X 3.2 4 Sep 93 G. Roelofs moved crc_32_tab[] to tables.h; used FOPx
X from unzip.h; nuked OUTB macro and outbuf;
X replaced flush(); inlined FlushOutput();
X renamed decrypt to encrypted
X 3.3 29 Sep 93 G. Roelofs replaced ReadByte() with NEXTBYTE macro;
X revised (restored?) flush(); added FUNZIP
X 3.4 21 Oct 93 G. Roelofs renamed quietflg to qflag; changed outcnt,
X H. Gessau second updcrc() arg and flush() arg to ulg;
X added inflate_free(); added "g =" to null
X getc(in) to avoid compiler warnings
X 3.5 31 Oct 93 H. Gessau changed DOS_OS2 to DOS_NT_OS2
X 3.6 6 Dec 93 H. Gessau added "near" to mask_bits[]
X 3.7 9 Dec 93 G. Roelofs added extent typecasts to fwrite() checks
X 3.8 28 Jan 94 GRR/JlG initialized g variable in main() for gcc
X 3.81 22 Feb 94 M. Hanning-Lee corrected usage message
X 3.82 27 Feb 94 G. Roelofs added some typecasts to avoid warnings
X 3.83 22 Jul 94 G. Roelofs changed fprintf to FPRINTF for DLLs
X - 2 Aug 94 - public release with UnZip 5.11
X - 28 Aug 94 - public release with UnZip 5.12


X */
X
X
X/*

X
X All funzip does is take a zip file from stdin and decompress the
X first entry to stdout. The entry has to be either deflated or
X stored. If the entry is encrypted, then the decryption password
X must be supplied on the command line as the first argument.
X
X funzip needs to be linked with inflate.o and crypt.o compiled from
X the unzip source. If decryption is desired, the full version of
X crypt.c (and crypt.h) from zcrypt21.zip or later must be used.
X
X */
X
X#define FUNZIP
X#include "unzip.h"
X#include "crypt.h"
X
X#ifdef EBCDIC
X# undef EBCDIC /* don't need ebcdic[] */
X#endif
X#include "tables.h" /* crc_32_tab[] */
X
X/* PKZIP header definitions */
X#define ZIPMAG 0x4b50 /* two-byte zip lead-in */
X#define LOCREM 0x0403 /* remaining two bytes in zip signature */
X#define LOCSIG 0x04034b50L /* full signature */
X#define LOCFLG 4 /* offset of bit flag */
X#define CRPFLG 1 /* bit for encrypted entry */
X#define EXTFLG 8 /* bit for extended local header */
X#define LOCHOW 6 /* offset of compression method */
X#define LOCTIM 8 /* file mod time (for decryption) */
X#define LOCCRC 12 /* offset of crc */
X#define LOCSIZ 16 /* offset of compressed size */
X#define LOCLEN 20 /* offset of uncompressed length */
X#define LOCFIL 24 /* offset of file name field length */
X#define LOCEXT 26 /* offset of extra field length */
X#define LOCHDR 28 /* size of local header, including LOCREM */
X#define EXTHDR 16 /* size of extended local header, inc sig */
X
X/* GZIP header definitions */
X#define GZPMAG 0x8b1f /* two-byte gzip lead-in */
X#define GZPHOW 0 /* offset of method number */
X#define GZPFLG 1 /* offset of gzip flags */
X#define GZPMUL 2 /* bit for multiple-part gzip file */
X#define GZPISX 4 /* bit for extra field present */
X#define GZPISF 8 /* bit for filename present */
X#define GZPISC 16 /* bit for comment present */
X#define GZPISE 32 /* bit for encryption */
X#define GZPTIM 2 /* offset of Unix file modification time */
X#define GZPEXF 6 /* offset of extra flags */
X#define GZPCOS 7 /* offset of operating system compressed on */
X#define GZPHDR 8 /* length of minimal gzip header */
X
X/* Macros for getting two-byte and four-byte header values */
X#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
X#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))


X
X/* Function prototypes */

Xulg updcrc OF((uch *, ulg));
Xint inflate OF((void));
Xvoid err OF((int, char *));
Xvoid main OF((int, char **));
X
X/* Globals */
XFILE *in, *out; /* input and output files */
Xunion work area; /* inflate sliding window */
Xuch *outptr; /* points to next byte in output buffer */
Xulg outcnt; /* bytes in output buffer */
Xulg outsiz; /* total bytes written to out */
Xint encrypted; /* flag to turn on decryption */
Xint qflag = 1; /* turn off messages in inflate.c */
X
X/* Masks for inflate.c */
Xush near mask_bits[] = {


X 0x0000,
X 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
X 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
X};
X
X

Xulg updcrc(s, n)
Xuch *s; /* pointer to bytes to pump through */
Xulg n; /* number of bytes in s[] */
X/* Run a set of bytes through the crc shift register. If s is a NULL
X pointer, then initialize the crc shift register contents instead.
X Return the current crc in either case. */
X{
X register ulg c; /* temporary variable */
X
X static ulg crc = 0xffffffffL; /* shift register contents */
X
X if (s == (uch *)NULL)
X c = 0xffffffffL;
X else
X {
X c = crc;
X while (n--)
X c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
X }
X crc = c;
X return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
X}
X
X
Xvoid err(n, m)
Xint n;
Xchar *m;
X/* Exit on error with a message and a code */
X{
X FPRINTF(stderr, "funzip error: %s\n", m);
X exit(n);
X}
X
X
Xint flush(w) /* used by inflate.c (FLUSH macro) */
Xulg w; /* number of bytes to flush */
X{
X updcrc(slide, w);
X if (fwrite((char *)slide,1,(extent)w,out) != (extent)w && !PIPE_ERROR)
X err(9, "out of space on stdout");
X outsiz += w;


X return 0;
X}
X
X

Xvoid main(argc, argv)
Xint argc;
Xchar **argv;
X/* Given a zip file on stdin, decompress the first entry to stdout. */
X{
X ush n;
X uch h[LOCHDR]; /* first local header (GZPHDR < LOCHDR) */
X int g = 0; /* true if gzip format */
X#ifdef CRYPT
X char *s = " [-password]";
X char *p; /* password */
X#else /* !CRYPT */
X char *s = "";
X#endif /* ?CRYPT */
X
X /* skip executable name */
X argc--;
X argv++;
X
X#ifdef CRYPT
X /* get the command line password, if any */
X p = (char *)NULL;
X if (argc && **argv == '-')
X {
X argc--;
X p = 1 + *argv++;
X }
X#endif /* CRYPT */
X
X /* if no file argument and stdin not redirected, give the user help */
X if (argc == 0 && isatty(0))
X {
X FPRINTF(stderr, "fUnZip (filter UnZip), version %s\n", VERSION);
X FPRINTF(stderr, "usage: ... | funzip%s | ...\n", s);
X FPRINTF(stderr, " ... | funzip%s > outfile\n", s);
X FPRINTF(stderr, " funzip%s infile.zip > outfile\n", s);
X FPRINTF(stderr, " funzip%s infile.gz > outfile\n", s);
X FPRINTF(stderr, "Extracts to stdout the gzip file or first zip entry of\
X stdin or the given file.\n");
X exit(3);
X }
X
X /* prepare to be a binary filter */
X if (argc)
X {
X if ((in = fopen(*argv, FOPR)) == (FILE *)NULL)
X err(2, "cannot find input file");
X }
X else
X {
X#ifdef DOS_NT_OS2
X setmode(0, O_BINARY); /* some buggy C libraries require BOTH setmode() */
X#endif /* call AND the fdopen() in binary mode :-( */
X if ((in = fdopen(0, FOPR)) == (FILE *)NULL)
X err(2, "cannot find stdin");
X }
X#ifdef DOS_NT_OS2
X setmode(1, O_BINARY);
X#endif
X if ((out = fdopen(1, FOPW)) == (FILE *)NULL)
X err(2, "cannot write to stdout");
X
X /* read local header, check validity, and skip name and extra fields */
X n = getc(in); n |= getc(in) << 8;
X if (n == ZIPMAG)
X {
X if (fread((char *)h, 1, LOCHDR, in) != LOCHDR || SH(h) != LOCREM)
X err(3, "invalid zip file");
X if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
X err(3, "first entry not deflated or stored--can't funzip");
X for (n = SH(h + LOCFIL); n--; ) g = getc(in);
X for (n = SH(h + LOCEXT); n--; ) g = getc(in);
X g = 0;
X encrypted = h[LOCFLG] & CRPFLG;
X }
X else if (n == GZPMAG)
X {
X if (fread((char *)h, 1, GZPHDR, in) != GZPHDR)
X err(3, "invalid gzip file");
X if (h[GZPHOW] != DEFLATED)
X err(3, "gzip file not deflated");
X if (h[GZPFLG] & GZPMUL)
X err(3, "cannot handle multi-part gzip files");
X if (h[GZPFLG] & GZPISX)
X {
X n = getc(in); n |= getc(in) << 8;
X while (n--) g = getc(in);
X }
X if (h[GZPFLG] & GZPISF)
X while ((g = getc(in)) != 0 && g != EOF) ;
X if (h[GZPFLG] & GZPISC)
X while ((g = getc(in)) != 0 && g != EOF) ;
X g = 1;
X encrypted = h[GZPFLG] & GZPISE;
X }
X else
X err(3, "input not a zip or gzip file");
X
X /* if entry encrypted, decrypt and validate encryption header */
X if (encrypted)
X#ifdef CRYPT
X {
X ush i, e;
X
X if (p == (char *)NULL)
X if ((p = (char *)malloc(PWLEN+1)) == (char *)NULL)
X err(1, "out of memory");
X else if ((p = getp("Enter password: ", p, PWLEN+1)) == (char *)NULL)
X err(1, "no tty to prompt for password");
X init_keys(p);
X for (i = 0; i < RAND_HEAD_LEN; i++)
X e = NEXTBYTE;
X if (e != (ush)(h[LOCFLG] & EXTFLG ? h[LOCTIM + 1] : h[LOCCRC + 3]))
X err(3, "incorrect password for first entry");
X }
X#else /* !CRYPT */
X err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
X#endif /* ?CRYPT */
X
X /* prepare output buffer and crc */


X outptr = slide;
X outcnt = 0L;

X outsiz = 0L;
X updcrc(NULL, 0L);
X
X /* decompress */
X if (g || h[LOCHOW])
X { /* deflated entry */
X int r;
X

X if ((r = inflate()) != 0)

X if (r == 3)
X err(1, "out of memory");
X else
X err(4, "invalid compressed data--format violated");
X inflate_free();
X }
X else
X { /* stored entry */
X register ulg n;
X
X n = LG(h + LOCLEN);
X if (n != LG(h + LOCSIZ) - (encrypted ? RAND_HEAD_LEN : 0)) {
X FPRINTF(stderr, "len %ld, siz %ld\n", n, LG(h + LOCSIZ));
X err(4, "invalid compressed data--length mismatch");
X }
X while (n--) {
X ush c = getc(in);
X#ifdef CRYPT
X if (encrypted)
X zdecode(c);
X#endif
X *outptr++ = (uch)c;
X if (++outcnt == WSIZE) /* do FlushOutput() */
X {
X updcrc(slide, outcnt);
X if (fwrite((char *)slide, 1,(extent)outcnt,out) != (extent)outcnt
X && !PIPE_ERROR)
X err(9, "out of space on stdout");
X outsiz += outcnt;


X outptr = slide;
X outcnt = 0L;

X }
X }
X }
X if (outcnt) /* flush one last time; no need to reset outptr/outcnt */
X {
X updcrc(slide, outcnt);
X if (fwrite((char *)slide, 1,(extent)outcnt,out) != (extent)outcnt
X && !PIPE_ERROR)
X err(9, "out of space on stdout");
X outsiz += outcnt;
X }
X fflush(out);
X
X /* if extended header, get it */
X if (g)
X {
X if (fread((char *)h + LOCCRC, 1, 8, in) != 8)
X err(3, "gzip file ended prematurely");
X }
X else
X if ((h[LOCFLG] & EXTFLG) &&
X fread((char *)h + LOCCRC - 4, 1, EXTHDR, in) != EXTHDR)
X err(3, "zip file ended prematurely");
X
X /* validate decompression */
X if (LG(h + LOCCRC) != updcrc(slide, 0L))
X err(4, "invalid compressed data--crc error");
X if (LG(h + (g ? LOCSIZ : LOCLEN)) != outsiz)
X err(4, "invalid compressed data--length error");
X
X /* check if there are more entries */
X if (!g && fread((char *)h, 1, 4, in) == 4 && LG(h) == LOCSIG)
X FPRINTF(stderr,
X "funzip warning: zip file has more than one entry--rest ignored\n");
X
X exit(0);
X}
END_OF_FILE
if test 14247 -ne `wc -c <'unzip-5.12/funzip.c'`; then
echo shar: \"'unzip-5.12/funzip.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/funzip.c'
fi
if test -f 'unzip-5.12/mac/thinkc.hqx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/thinkc.hqx'\"
else
echo shar: Extracting \"'unzip-5.12/mac/thinkc.hqx'\" \(24586 characters\)
sed "s/^X//" >'unzip-5.12/mac/thinkc.hqx' <<'END_OF_FILE'
X(This file must be converted with BinHex 4.0)
X
X:$(9ZHQP`,R4SD@jVB`"38Np+5d&)6!#3#%r--XF!N!3"!*!$6I)!!%cb!!!"fJ#
X3!`)14'9cDh4[F#"'EfaNCA*%!3#3"dakT9J-G@jkDA!ZG'KTEQYMFJ)!N!038Np
X+5d&)6!%!!*`"!*!$8&*25NY"5%`"!!#F!3#3%kThLmN!N!C2c&4"8NC839)J!3$
XrN!3!N!49C!#3"&!!N!03!*!,TGA!%+A9`#`!N"-#!!#C"J!8!*!k!r!!N2m!N2m
X!N2m!N2)9!*!$#!!%rbN"*J#3"4J!N!JM!"3XarP!!)!FM@J!()Ui!*!$#J#3!`J
X!N!-)!*!&&L0TEQ0XG@4P)$a0B@0)C@&NCA*c2J#3!`&B!!#`"3!!4&*@8J'B!#5
X+c!!!rc!!YJ#3#%MN!*!$9!!NLX`!!!%!N!-"!*!$$#S!N!0-!#5-!!03i!!!(!"
X'!!&)390)!*!$%PT26N8!N!-H!!%!!!)!!$)!+NM`!!$rr`)!"#B!+NMN"@eVB@K
XX!*!$%!!NLX`!!2m`!,B!N!98!#5+c!!!!3#3!`%!N!--+J#3!d`!*)`!!e$J!!!
XF!%B!!8K"8dJ!N!-5@Np143#3!ai!!3!!!J!!-J!U52!!!2rr!J!%*J!U513&E@Y
XKD'`!N!-3!#5+c!!!rc!!YJ#3"93!*)V-!!!"!*!$!3#3!``U!*!$6!!NM!!$81!
X!!"`!4J99ERTTF#!e,M%a-d&&!*!$(J!"!!!#!!!b!#T)m!!!rrm#!!3Q!#T)j!9
XYDf&SE!#3!a!!*)V-!!$r-!#f!!""8&"-99TTF!!!!J#3!`9!!*!$!J#3!f!!N"-
X%!*!+CB3!N"%35%%#"!!5!*!$!`#3!f!!N"-%!*!+9a3!N"(f4&)"!J!+!*!$"!#
X3!f!!N"-%!*!+9+!!N"!"9N4#!`-!#3#3!`8!N!0J!*!6"!#3#Jr#!*!3$@!!+J)
X%!!%!N!-'!*!$B!#3%`3!N!S)-J#3%%Lm!!!#"!!1!*!$"`#3!f!!N"-%!*!Frrm
X!!!)%!!X!N!-)!*!$B!#3%`3!N!S+M!#3%4`r2!)%!!`!N!-*!*!$B!#3%`3!N!T
X1pJ#3%!Db2c`#"!!0!*!'!5!!!#%U!*!$9!#3"J0)!!"Ea!!!5Y!!!#TB!*!9*)V
X-!3)!%3#3!`S!N!0J!*!6"!#3#P*B!*!3!Hd"r3%#!!B!N!-,!*!$B!#3%`3!N!T
X1SJ#3%'`!r`!"!J!$!*!$$!#3!f!!N"-%!*!+6rS!N"0)!3)!"!#3!`d!N!0J!*!
X6"!#3#Nr'!*!3@YB!!3%#!!8!N!-1!*!$B!#3%`3!N!TE#!#3%&C5!CJ"!J!2!*!
X$$`#3!f!!N"-%!*!+8ii!N"3"!J!3!*!$%!#3!f!!N"-%!*!J!J3!"`#3!a%!N!0
XJ!*!6"!#3#Y)-!*!3mdJ"!!)%!*!&%J#3!f!!N"-%!*!+9'i!N"!%F!HB!J3!%`#
X3!a-!N!0J!*!6"!#3#P'@!*!3)&"bE`%#!!)!N!-8!*!$B!#3%`3!N#!$!`!)!*!
X'%JJ!!'9B!!!&d!#3"M%!N!0ZFJ!!+&!!N"`$!`!8!*!$"J!4!!!JE`#3!aB!d`!
X$!A`"cJ$6!3i"I!(mP#!!N!Bi!!!Tm+J!+I5S!#Rdb!!Tpe3!+IS%!#RmfJ!TrIJ
X!+Im5!#Rr5!!U!0)!+J0F!#S&k!!U#(3!+JX#!#S0N!!!+K"N!#S6&J!U%d`!+KC
X)!#SBd!!U'k!!+K[5!#SEp!!U++J!N,N'`8!!N!d'`6!!N'N'`-3!"X$!!*!$#!!
X"!%%!J3$"!C!$33'"!F%#!3*"!S%#`3-"!d%$J32""!%%335""-%&!39""B%&`3B
X""N%'J3E""`%(33H""m%)!3K"#)%)`3N"#8%*J3R"#J%+33U"#X%,!3Y"#i%,`3`
X"$%%-J3c"$3%033f"$F%1!3j"$S%1`3m"$d%2J3r"!!%!J3'3!i%#!3+"!`%$J33
X"")%&!3@""J%'J3F""i%)!3L"#3%*J3S"#S%,!3Z"$!%-J3d"$B%1!3k"$`%2J4!
X"%)%4!4'"%J%5J4-"%i%8!45"&3%9J4B"&S%A!4H"'!%BJ4N"'B%D!4U"'`%EJ4`
X"()%G!4f"(J%HJ4m"(i%!!##3!h0VDA"`D@jR1L!P,6)bFb!JEQ9PC#!PFb"MEfe
X`BA3Z)(BPG5iPG5!SBf&Z)'4[)(BPG5iPG5N+!##3!h0VDA"`D@jR1L!P,6)bFb!
XJBfpYF(*PFh0TEfiJE@9dD'pN)#9N#J!!*A-k)#"LB@3JCQPXC@jKE@8JE'9ZCh4
XS)#JPFbN+!!!PFcSJ)'*KC#"PH(4bB5"QD@9XC#"XC@jRG'JJ+#9c+3S!CQPXC5!
XM*@3k)#"LB@3JHQP`CQPXC5"[CQCcCA3J+#9c+6SJ)#9XC!S!*6KcD@jR1L!P,6)
XbFb!J*A-PF`!PFb!J*A-k)#!PE'3JBRPdCA-JFQ9aG@PbC@3JG'mJG@jMEfe`FQ9
XcFb"dEb!PE(8JBRPdCA-l#L#3"#9c)*!'Fh9`F'pcC@3JG'mJFQ9aG@PbC5!PE(8
XJBRPdCA-PFb9c*A-+!!!+*A-k)#"LB@3JCQPX3!!!EfeYC@jd)'aPEQGdD!S!!'a
X[Bf&X)'KPB@4PFJS!&#c(q8!!&#c(q8!!!!%!!2q3#+Te@qi!'!!"!!"8FPT*8%N
X!#ATTF'PZCQmZB`!!!D5A`JQNPm)*T*I##3!D!!)!!&-H68&$5!%+6@&M5'9KC'9
XbF`#3!`'UG9bNUR9FT+TeA+3!&J!"!!"8FP91@NN!"h9ZHQP`,QJ!!!+N-adpT$-
XG2D3c(6d!&J!#!!"5f9084%N""h0dC'P[,QJ!!!1N,ErlT#frqk3Y[rX!'!!#!!"
X5f90*@N8!#(0THQ9IG#jS!(-!!U3VMFUN+ih+T#Z0bJ!@!!)!!&,C3e4C8!%(Bh4
XjF'8ZD!!!!U3VM+#N+ibJT#Z-S!!@!!)!!&,C49*56J%(CA*bEQmZD!!!!U3Y`,1
XN,F#cT#h!X`!B!!)!!&,C8e4553%)Fh4bD@jR,QJ!F`!#T#apRk3XICqN,(fI!"J
X!!J!!8YP-58e*!3KXD@eTG(-ZD!"c!!+N,F"!T#h!3+3Y`%!!'!!#!!"5f9084%3
X"#(0dC'4PCLjS!(-!!k3Y`#+N,F!LT#h!)J!B!!)!!&,C9d0)33!*Gf0SBA*IG#j
XS!!!#T#j4$D3Z83fN,P%0!"J!!J!!8YP69%4-!3KcG'4XD@)ZD!#3!`+N,E[0T#f
XlcD3YZmd!'!!#!!"5f90*4di"#(0TCfjKE#jS!*!$!U3arj!!T$(rN!#N-Iq3!!!
X@!!)!!&,C4N019!%(CQ0ZG'`ZD!!!!UNe"e5T03G8U68(9!!B!!%!!&4b68&$8`!
X*E@&MFh4KG#jS!!!$T#h!LD3Y`)QN,F#*!"B!!J!!8YP858e&!3CdD@eP,QJ!,J!
X#U68(8UNe"e+T03G5!"J!!3!!9(*0380%!!KYB@0NDA)ZD!!!#J!8,-Ij3!!8,-I
Xj3!!!!3!!rj!)URC5B!!B!!%!!&4b49K88J!*CAKdFQ&MG#jM!!!"T*I##D5A`JQ
XNPm)*!"S!!J!!8aj0380)!3T0B@0)C@&NCA*c!*!$!DTeA+5UG9bNUR9FT!!@!!%
X!!&4b98jD53!(G@jkDA!ZD!!!!U3c(6fN-adpT$-G23!@!!)!!&,C8e4%53%(Fh4
XND@mZD!!!!k3Y[rZN,ErlT#frq`!B!!)!!&,C8dPD43!)FfPkC9pd,QJ!F`!#T#Z
X0bU3VMFUN+ih+!"B!!J!!8YP$9&P3!3GMG(P`C5jS!!!#T#Z-S+3VM+#N+ibJ!"B
X!!J!!8YP&8P*1!3GPFR*ZEbjS!!!#T#h!Xk3Y`,1N,F#c!"J!!J!!8YP69&**!3K
XcG(*TEQFZD!"c!!+N,(fIT#apRk3XICm!'!!#!!"5f8a*68N"#'aTE@PdFbjS!(-
X!!U3Y`%#N,F"!T#h!3!!B!!)!!&,C8e4%4!%)Fh4NC'9Q,QJ!F`!$T#h!)U3Y`#+
XN,F!L!"J!!J!!8YPA3dK"!!PhBfKKFPpd,QJ!!!+N,P%0T#j4$D3Z83d!'!!#!!"
X5f9084%`"#(0dC'aTBLjS!*!$!U3YZmfN,E[0T#flc3!B!!)!!&,C8dP(6J%)FfP
XREQ&X,QJ!N!-#T$(rN!#N-Iq3!+3arj!!!"B!!J!!8YP'3dj8!3GQBfjdE#jS!!!
X#U68(9+Ne"e5T03G8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ!!!1N,F#*T#h!LD3
XY`)N!&J!#!!"5f94*688""R4TE@8ZD!!Z!!+T03G5U68(8UNe"e)!'!!"!!"8FNe
X"3d3!#'eKBf4TFLjS!*!$!DTP-PUUC6*DUQ8b@J!@!!%!!&4b3e*C8!!(Bh*jF(3
XZD!!+!"3XarP!!"3XarP!!!!"!!$rN!LUG9[#!"J!!3!!9(*'58a&!!PQD@aPAfP
X[,Q-!!!'NPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"UR9
XFT+TeA+5UG9bN!"B!!3!!9(*96PT*!!GeERTTF#jS!!!#T$-G2D3c(6fN-adp!"B
X!!J!!8YP69%4*!3GcG'4TEbjS!!!$T#frqk3Y[rZN,Erl!"J!!J!!8YP659T&!!K
XcDATPAh3ZD!"c!!+N+ih+T#Z0bU3VMFS!&J!#!!"5f808@9!""f0dHA"P,QJ!!!+
XN+ibJT#Z-S+3VM+!!&J!#!!"5f8958Ni""f9bFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-
X!'!!#!!"5f9088NN"#(0dFQPZCbjS!(-!!U3XICqN,(fIT#apR`!B!!)!!&,C6%P
X053%)E'PYDA4c,QJ!F`!#T#h!3+3Y`%#N,F"!!"J!!J!!8YP69%4%!3KcG'4NC@B
XZD!"c!!1N,F!LT#h!)U3Y`#)!'!!#!!"5f9G$5%%!#AGMD'&bAh3ZD!!!!U3Z83f
XN,P%0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-#T#flcD3YZmfN,E[0!"J
X!!J!!8YP658G1!3KcD@GZB@`ZD!#3!`+N-Iq3!+3arj!!T$(rN!!!&J!#!!"5f8C
X$6P3""fCMER4X,QJ!!!+T03G8U68(9+Ne"e3!'!!"!!"8FNe"3e-!#@eKBh0dBA3
XZD!!!!k3Y`)QN,F#*T#h!L3!@!!)!!&,C9%P043%'G'PYC5jS!#i!!UNe"e+T03G
X5U68(8J!B!!%!!&4b68&$4!!)E@&MC'Pb,QJ!N!-"UQ8b@UTP-PUUC6*D!"B!!3!
X!9(*$8PP3!!GMFRP`G#jS!!!"UH+c2URLXckTiV-q!"J!!3!!9(*838*-!!KdB@*
XXCA-ZD!!!#J!8,-Ij3!!8,-Ij3!!!!3!!rj!)U68(8J!D!!%!!&4b68&$8`!,E@&
XMFf0bC@9Z,Q-!!!'NPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-
X!N!-"T"Bj`+3@1F#N&MR!!"S!!J!!8ap498P$!3Y4G@PMDd4bBAFZD!!!!D3c(6f
XN-adpT$-G23!@!!)!!&,C8e4%53%(Fh4ND@mZD!!!!U3Y[rZN,ErlT#frq`!B!!)
X!!&,C8dPD43!)FfPkC9pd,QJ!,J!"T#fm%k3Y["1N,E`6!"J!!J!!8YP69%4"!3K
XcG'4KFQFZD!!Z!!'N,F#cT#h!Xk3Y`,-!'!!#!!"5f9088NN"#(0dFQPZCbjS!#i
X+!"3XarP!!"3XarP!!!!"!!$rN!LT03G5!"J!!3!!9(*03806!!PYB@0cG'&d,Q-
X!!!'NPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"T&"Z@k4
X3EPZN8'jE!"J!!J!!8h*3390$!3K`BA0MB@`ZD!"c!!'N,F#cT#h!Xk3Y`,-!'!!
X#!!"5f9088NN"#(0dFQPZCbjS!(-!!U3Y[rZN,ErlT#frq`!B!!)!!&,C8dPD43!
X)FfPkC9pd,QJ!F`!"U68(9+Ne"e5T03G8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ
X!!!+N,F#*T#h!LD3Y`)N!&J!#!!"5f94*688""R4TE@8ZD!!Z!!!8,-Ij3!!8,-I
Xj3!!!!3!!rj!)T*ceA`!B!!)!!&0k68&$9!!)6@&M9(*KF(-!!!S!&#c(q8!!&#c
X(q8!!!!%!!2q3#+Ne"e)!'!!"!!"8FNe"3d3!#'eKBf4TFLjM!()!!D5A`JQNPm)
X*T*I##3!D!!)!!&-H68&$5!%+6@&M5'9KC'9bF`#3!`'N&MR!T"Bj`+3@1F!!'!!
X#!!"6(d958Nm"#%9bFQpbFbjS!(-!!D3c,TUN-bkDT$-ZQJ!@!!)!!&-I4NP-43%
X(4QPXCA-ZD!!!!D3VM+#N+ibJT#Z-S!!@!!)!!&,C49*56J%(CA*bEQmZD!!!!D3
XZ83fN,P%0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!F`!#T#frqk3Y[rZN,Er
Xl!"J!!J!!8YP659T&!!KcDATPAh3ZD!"c!!+N,F!LT#h!)U3Y`#)!'!!#!!"5f9G
X$5%%!#AGMD'&bAh3ZD!!!!D3Y`,1N,F#cT#h!X`!B!!)!!&,C8e4553%)Fh4bD@j
XR,QJ!N!-"U68(8UNe"e+T03G5!"J!!3!!9(*0380%!!KYB@0NDA)ZD!!!#J!8,-I
Xj3!!8,-Ij3!!!!3!!rj!)UQlrNJ!@!!%!!&4b68&83`!(E@&dBfJZB`!!!D5A`JQ
XNPm)*T*I##3!D!!)!!&-H68&$5!%+6@&M5'9KC'9bF`#3!`'UG9bNUR9FT+TeA+3
X!&J!"!!"8FP91@NN!"h9ZHQP`,QJ!!!+N-adpT$-G2D3c(6d!&J!#!!"5f9084%N
X""h0dC'P[,QJ!!!1N,ErlT#frqk3Y[rX!'!!#!!"5f90*@N8!#(0THQ9IG#jS!(-
X!!U3VMFUN+ih+T#Z0bJ!@!!)!!&,C3e4C8!%(Bh4jF'8ZD!!!!U3VM+#N+ibJT#Z
X-S!!@!!)!!&,C49*56J%(CA*bEQmZD!!!!U3Y`,1N,F#cT#h!X`!B!!)!!&,C8e4
X553%)Fh4bD@jR,QJ!F`!#T#apRk3XICqN,(fI!"J!!J!!8YP-58e*!3KXD@eTG(-
XZD!"c!!+N,F"!T#h!3+3Y`%!!'!!#!!"5f9084%3"#(0dC'4PCLjS!(-!!k3Y`#+
XN,F!LT#h!)J!B!!)!!&,C9d0)33!*Gf0SBA*IG#jS!!!#T#j4$D3Z83fN,P%0!"J
X!!J!!8YP69%4-!3KcG'4XD@)ZD!#3!`+N,E[0T#flcD3YZmd!'!!#!!"5f90*4di
X"#(0TCfjKE#jS!*!$!U3arj!!T$(rN!#N-Iq3!!!@!!)!!&,C4N019!%(CQ0ZG'`
XZD!!!!UNe"e5T03G8U68(9!!B!!%!!&4b68&$8`!*E@&MFh4KG#jS!!!$T#h!LD3
XY`)QN,F#*!"B!!J!!8YP858e&!3CdD@eP,QJ!,J!#U68(8UNe"e+T03G5!"J!!3!
X!9(*0380%!!KYB@0NDA)ZD!!!#J!8,-Ij3!!8,-Ij3!!!!3!!rj!)UP'S)J!B!!%
X!!&4b49K36!!*CAK`E'pNC5jM!!!"T*I##D5A`JQNPm)*!"S!!J!!8aj0380)!3T
X0B@0)C@&NCA*c!*!$!DTeA+5UG9bNUR9FT!!@!!%!!&4b98jD53!(G@jkDA!ZD!!
X!!U3c(6fN-adpT$-G23!@!!)!!&,C8e4%53%(Fh4ND@mZD!!!!k3Y[rZN,ErlT#f
Xrq`!B!!)!!&,C8dPD43!)FfPkC9pd,QJ!F`!#T#Z0bU3VMFUN+ih+!"B!!J!!8YP
X$9&P3!3GMG(P`C5jS!!!#T#Z-S+3VM+#N+ibJ!"B!!J!!8YP&8P*1!3GPFR*ZEbj
XS!!!#T#h!Xk3Y`,1N,F#c!"J!!J!!8YP69&**!3KcG(*TEQFZD!"c!!+N,(fIT#a
XpRk3XICm!'!!#!!"5f8a*68N"#'aTE@PdFbjS!(-!!U3Y`%#N,F"!T#h!3!!B!!)
X!!&,C8e4%4!%)Fh4NC'9Q,QJ!F`!$T#h!)U3Y`#+N,F!L!"J!!J!!8YPA3dK"!!P
XhBfKKFPpd,QJ!!!+N,P%0T#j4$D3Z83d!'!!#!!"5f9084%`"#(0dC'aTBLjS!*!
X$!U3YZmfN,E[0T#flc3!B!!)!!&,C8dP(6J%)FfPREQ&X,QJ!N!-#T$(rN!#N-Iq
X3!+3arj!!!"B!!J!!8YP'3dj8!3GQBfjdE#jS!!!#U68(9+Ne"e5T03G8!"J!!3!
X!9(*03806!!PYB@0cG'&d,QJ!!!1N,F#*T#h!LD3Y`)N!&J!#!!"5f94*688""R4
XTE@8ZD!!Z!!+T03G5U68(8UNe"e)!'!!"!!"8FNe"3d3!#'eKBf4TFLjS!!!+!"3
XXarP!!"3XarP!!!!"!!$rN!LTfrqS!"J!!3!!9(*&6PC"!!PPERCKFQGc,Q-!!!'
XNPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"UR9FT+TeA+5
XUG9bN!"B!!3!!9(*96PT*!!GeERTTF#jS!!!#T$-G2D3c(6fN-adp!"B!!J!!8YP
X69%4*!3GcG'4TEbjS!!!$T#frqk3Y[rZN,Erl!"J!!J!!8YP659T&!!KcDATPAh3
XZD!"c!!+N+ih+T#Z0bU3VMFS!&J!#!!"5f808@9!""f0dHA"P,QJ!!!+N+ibJT#Z
X-S+3VM+!!&J!#!!"5f8958Ni""f9bFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-!'!!#!!"
X5f9088NN"#(0dFQPZCbjS!(-!!U3XICqN,(fIT#apR`!B!!)!!&,C6%P053%)E'P
XYDA4c,QJ!F`!#T#h!3+3Y`%#N,F"!!"J!!J!!8YP69%4%!3KcG'4NC@BZD!"c!!1
XN,F!LT#h!)U3Y`#)!'!!#!!"5f9G$5%%!#AGMD'&bAh3ZD!!!!U3Z83fN,P%0T#j
X4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-#T#flcD3YZmfN,E[0!"J!!J!!8YP
X658G1!3KcD@GZB@`ZD!#3!`+N-Iq3!+3arj!!T$(rN!!!&J!#!!"5f8C$6P3""fC
XMER4X,QJ!!!+T03G8U68(9+Ne"e3!'!!"!!"8FNe"3e-!#@eKBh0dBA3ZD!!!!k3
XY`)QN,F#*T#h!L3!@!!)!!&,C9%P043%'G'PYC5jS!#i!!UNe"e+T03G5U68(8J!
XB!!%!!&4b68&$4!!)E@&MC'Pb,QJ!!!S!&#c(q8!!&#c(q8!!!!%!!2q3#+ME6B3
X!'J!"!!"8FP918N8!#R9ZFQ9NG@0P,Q-!N!-"T*I##D5A`JQNPm)*!"S!!J!!8aj
X0380)!3T0B@0)C@&NCA*c!*!$!DTeA+5UG9bNUR9FT!!@!!%!!&4b98jD53!(G@j
XkDA!ZD!!!!U3c(6fN-adpT$-G23!@!!)!!&,C8e4%53%(Fh4ND@mZD!!!!k3Y[rZ
XN,ErlT#frq`!B!!)!!&,C8dPD43!)FfPkC9pd,QJ!F`!#T#Z0bU3VMFUN+ih+!"B
X!!J!!8YP$9&P3!3GMG(P`C5jS!!!#T#Z-S+3VM+#N+ibJ!"B!!J!!8YP&8P*1!3G
XPFR*ZEbjS!!!#T#h!Xk3Y`,1N,F#c!"J!!J!!8YP69&**!3KcG(*TEQFZD!"c!!+
XN,(fIT#apRk3XICm!'!!#!!"5f8a*68N"#'aTE@PdFbjS!(-!!U3Y`%#N,F"!T#h
X!3!!B!!)!!&,C8e4%4!%)Fh4NC'9Q,QJ!F`!$T#h!)U3Y`#+N,F!L!"J!!J!!8YP
XA3dK"!!PhBfKKFPpd,QJ!!!+N,P%0T#j4$D3Z83d!'!!#!!"5f9084%`"#(0dC'a
XTBLjS!*!$!U3YZmfN,E[0T#flc3!B!!)!!&,C8dP(6J%)FfPREQ&X,QJ!N!-#T$(
XrN!#N-Iq3!+3arj!!!"B!!J!!8YP'3dj8!3GQBfjdE#jS!!!#U68(9+Ne"e5T03G
X8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ!!!1N,F#*T#h!LD3Y`)N!&J!#!!"5f94
X*688""R4TE@8ZD!!Z!!+T03G5U68(8UNe"e)!'!!"!!"8FNe"3d3!#'eKBf4TFLj
XS!!!+!"3XarP!!"3XarP!!!!"!!$rN!LUG9[3!"S!!3!!9(*96P0)!!TeER0SFQP
XZDbjM!*!$!D5A`JQNPm)*T*I##3!D!!)!!&-H68&$5!%+6@&M5'9KC'9bF`#3!`'
XUG9bNUR9FT+TeA+3!&J!"!!"8FP91@NN!"h9ZHQP`,QJ!!!+N-adpT$-G2D3c(6d
X!&J!#!!"5f9084%N""h0dC'P[,QJ!!!1N,ErlT#frqk3Y[rX!'!!#!!"5f90*@N8
X!#(0THQ9IG#jS!(-!!U3VMFUN+ih+T#Z0bJ!@!!)!!&,C3e4C8!%(Bh4jF'8ZD!!
X!!U3VM+#N+ibJT#Z-S!!@!!)!!&,C49*56J%(CA*bEQmZD!!!!U3Y`,1N,F#cT#h
X!X`!B!!)!!&,C8e4553%)Fh4bD@jR,QJ!F`!#T#apRk3XICqN,(fI!"J!!J!!8YP
X-58e*!3KXD@eTG(-ZD!"c!!+N,F"!T#h!3+3Y`%!!'!!#!!"5f9084%3"#(0dC'4
XPCLjS!(-!!k3Y`#+N,F!LT#h!)J!B!!)!!&,C9d0)33!*Gf0SBA*IG#jS!!!#T#j
X4$D3Z83fN,P%0!"J!!J!!8YP69%4-!3KcG'4XD@)ZD!#3!`+N,E[0T#flcD3YZmd
X!'!!#!!"5f90*4di"#(0TCfjKE#jS!*!$!U3arj!!T$(rN!#N-Iq3!!!@!!)!!&,
XC4N019!%(CQ0ZG'`ZD!!!!UNe"e5T03G8U68(9!!B!!%!!&4b68&$8`!*E@&MFh4
XKG#jS!!!$T#h!LD3Y`)QN,F#*!"B!!J!!8YP858e&!3CdD@eP,QJ!,J!#U68(8UN
Xe"e+T03G5!"J!!3!!9(*0380%!!KYB@0NDA)ZD!!!#J!8,-Ij3!!8,-Ij3!!!!3!
X!rj!)URC%R!!@!!%!!&4b98jD53!(G@jkDA!ZB`!!!D5A`JQNPm)*T*I##3!D!!)
X!!&-H68&$5!%+6@&M5'9KC'9bF`#3!`'UG9bNUR9FT+TeA+3!&J!"!!"8FP91@NN
X!"h9ZHQP`,QJ!!!+N-adpT$-G2D3c(6d!&J!#!!"5f9084%N""h0dC'P[,QJ!!!1
XN,ErlT#frqk3Y[rX!'!!#!!"5f90*@N8!#(0THQ9IG#jS!(-!!U3VMFUN+ih+T#Z
X0bJ!@!!)!!&,C3e4C8!%(Bh4jF'8ZD!!!!U3VM+#N+ibJT#Z-S!!@!!)!!&,C49*
X56J%(CA*bEQmZD!!!!U3Y`,1N,F#cT#h!X`!B!!)!!&,C8e4553%)Fh4bD@jR,QJ
X!F`!#T#apRk3XICqN,(fI!"J!!J!!8YP-58e*!3KXD@eTG(-ZD!"c!!+N,F"!T#h
X!3+3Y`%!!'!!#!!"5f9084%3"#(0dC'4PCLjS!(-!!k3Y`#+N,F!LT#h!)J!B!!)
X!!&,C9d0)33!*Gf0SBA*IG#jS!!!#T#j4$D3Z83fN,P%0!"J!!J!!8YP69%4-!3K
XcG'4XD@)ZD!#3!`+N,E[0T#flcD3YZmd!'!!#!!"5f90*4di"#(0TCfjKE#jS!*!
X$!U3arj!!T$(rN!#N-Iq3!!!@!!)!!&,C4N019!%(CQ0ZG'`ZD!!!!UNe"e5T03G
X8U68(9!!B!!%!!&4b68&$8`!*E@&MFh4KG#jS!!!$T#h!LD3Y`)QN,F#*!"B!!J!
X!8YP858e&!3CdD@eP,QJ!,J!#U68(8UNe"e+T03G5!"J!!3!!9(*0380%!!KYB@0
XNDA)ZD!#3!`'UC6*DUQ8b@UTP-PS!&J!"!!"8FN05@9!!"f0bHA"d,QJ!!!'UGMZ
X@URBlPUTf1jB!'!!"!!"8FPC&8P-!#ACPFR0TEfiZD!!+!"3XarP!!"3XarP!!!!
X"!!$rN!LU9A9Q!"J!!3!!9(**6NC-!!PTEQCXBA4P,Q-!!!'NPm)*T*I##D5A`JN
X!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"UP&M"UT4B`DU8@-'!"J!!3!!9(*
X*6NC-!!PTEQCXBA4P,QJ!!!+UG9bNUR9FT+TeA+3!&J!"!!"8FP91@NN!"h9ZHQP
X`,QJ!!!1N-adpT$-G2D3c(6d!&J!#!!"5f9084%N""h0dC'P[,QJ!!!5N,ErlT#f
Xrqk3Y[rX!'!!#!!"5f90*@N8!#(0THQ9IG#jS!*!$!k3VMFUN+ih+T#Z0bJ!@!!)
X!!&,C3e4C8!%(Bh4jF'8ZD!!!!k3VM+#N+ibJT#Z-S!!@!!)!!&,C49*56J%(CA*
XbEQmZD!!!!k3Y`,1N,F#cT#h!X`!B!!)!!&,C8e4553%)Fh4bD@jR,QJ!N!-$T#a
XpRk3XICqN,(fI!"J!!J!!8YP-58e*!3KXD@eTG(-ZD!#3!`1N,F"!T#h!3+3Y`%!
X!'!!#!!"5f9084%3"#(0dC'4PCLjS!*!$"+3Y`#+N,F!LT#h!)J!B!!)!!&,C9d0
X)33!*Gf0SBA*IG#jS!!!$T#j4$D3Z83fN,P%0!"J!!J!!8YP69%4-!3KcG'4XD@)
XZD!#3!`1N,E[0T#flcD3YZmd!'!!#!!"5f90*4di"#(0TCfjKE#jS!*!$!k3arj!
X!T$(rN!#N-Iq3!!!@!!)!!&,C4N019!%(CQ0ZG'`ZD!!!!kNe"e5T03G8U68(9!!
XB!!%!!&4b68&$8`!*E@&MFh4KG#jS!!!%T#h!LD3Y`)QN,F#*!"B!!J!!8YP858e
X&!3CdD@eP,QJ!,J!$U68(8UNe"e+T03G5!"J!!3!!9(*0380%!!KYB@0NDA)ZD!#
X3""3XarP!!"3XarP!!!!"!!$rN!LNR29b!"J!!J!!8hT03808!!P0B@08FQ&`Fc)
X!#J!8,-Ij3!!8,-Ij3!!!!3!!rj!)UNYjqJ!D!!%!!&4b68&$93!+E@&MG@jkDA!
XZB`#3!`'NPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"UR9
XFT+TeA+5UG9bN!"B!!3!!9(*96PT*!!GeERTTF#jS!!!#T$-G2D3c(6fN-adp!"B
X!!J!!8YP69%4*!3GcG'4TEbjS!!!$T#frqk3Y[rZN,Erl!"J!!J!!8YP659T&!!K
XcDATPAh3ZD!"c!!+N+ih+T#Z0bU3VMFS!&J!#!!"5f808@9!""f0dHA"P,QJ!!!+
XN+ibJT#Z-S+3VM+!!&J!#!!"5f8958Ni""f9bFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-
X!'!!#!!"5f9088NN"#(0dFQPZCbjS!(-!!U3XICqN,(fIT#apR`!B!!)!!&,C6%P
X053%)E'PYDA4c,QJ!F`!#T#h!3+3Y`%#N,F"!!"J!!J!!8YP69%4%!3KcG'4NC@B
XZD!"c!!1N,F!LT#h!)U3Y`#)!'!!#!!"5f9G$5%%!#AGMD'&bAh3ZD!!!!U3Z83f
XN,P%0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-#T#flcD3YZmfN,E[0!"J
X!!J!!8YP658G1!3KcD@GZB@`ZD!#3!`+N-Iq3!+3arj!!T$(rN!!!&J!#!!"5f8C
X$6P3""fCMER4X,QJ!!!+T03G8U68(9+Ne"e3!'!!"!!"8FNe"3e-!#@eKBh0dBA3
XZD!!!!k3Y`)QN,F#*T#h!L3!@!!)!!&,C9%P043%'G'PYC5jS!#i!!UNe"e+T03G
X5U68(8J!B!!%!!&4b68&$4!!)E@&MC'Pb,QJ!N!-"T"Bj`+3@1F#N&MR!!"B!!J!
X!8ap88N&3!3G8FQ&`FbjS!!!"T"Bj`+3@1F#N&MR!!"J!!J!!8ap@38a9!3K@B@a
XeCA-ZD!#3!`+NU-65T+M%dU5Sa0)!&J!#!!"6FP0"6N8""P0"6N8ZD!"S#J!8,-I
Xj3!!8,-Ij3!!!!3!!rj!)URBr8J!8!!%!!&4b68&$,J!&E@&M,Q-!!!'NPm)*T*I
X##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdKPB@4PFR-!N!-"UR9FT+TeA+5UG9bN!"B
X!!3!!9(*96PT*!!GeERTTF#jS!!!#T$-G2D3c(6fN-adp!"B!!J!!8YP69%4*!3G
XcG'4TEbjS!!!$T#frqk3Y[rZN,Erl!"J!!J!!8YP659T&!!KcDATPAh3ZD!"c!!+
XN+ih+T#Z0bU3VMFS!&J!#!!"5f808@9!""f0dHA"P,QJ!!!+N+ibJT#Z-S+3VM+!
X!&J!#!!"5f8958Ni""f9bFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-!'!!#!!"5f9088NN
X"#(0dFQPZCbjS!(-!!U3XICqN,(fIT#apR`!B!!)!!&,C6%P053%)E'PYDA4c,QJ
X!F`!#T#h!3+3Y`%#N,F"!!"J!!J!!8YP69%4%!3KcG'4NC@BZD!"c!!1N,F!LT#h
X!)U3Y`#)!'!!#!!"5f9G$5%%!#AGMD'&bAh3ZD!!!!U3Z83fN,P%0T#j4$3!B!!)
X!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-#T#flcD3YZmfN,E[0!"J!!J!!8YP658G1!3K
XcD@GZB@`ZD!#3!`+N-Iq3!+3arj!!T$(rN!!!&J!#!!"5f8C$6P3""fCMER4X,QJ
X!!!+T03G8U68(9+Ne"e3!'!!"!!"8FNe"3e-!#@eKBh0dBA3ZD!!!!k3Y`)QN,F#
X*T#h!L3!@!!)!!&,C9%P043%'G'PYC5jS!#i!!UNe"e+T03G5U68(8J!B!!%!!&4
Xb68&$4!!)E@&MC'Pb,QJ!!!S!&#c(q8!!&#c(q8!!!!%!!2q3#+Te@l3!&J!"!!"
X8FN05@9!!"f0bHA"d,Q-!!!'NPm)*T*I##D5A`JN!'J!#!!"6(Ne"3dJ"#NeKBdK
XPB@4PFR-!N!-"UH+dG+RLY(5TiV4d!"3!!3!!9(*D59!Z!!9kDA!ZD!!!!UTeA+5
XUG9bNUR9FT!!@!!%!!&4b98jD53!(G@jkDA!ZD!!!!k3c(6fN-adpT$-G23!@!!)
X!!&,C8e4%53%(Fh4ND@mZD!!!"+3Y[rZN,ErlT#frq`!B!!)!!&,C8dPD43!)FfP
XkC9pd,QJ!F`!$T#Z0bU3VMFUN+ih+!"B!!J!!8YP$9&P3!3GMG(P`C5jS!!!$T#Z
X-S+3VM+#N+ibJ!"B!!J!!8YP&8P*1!3GPFR*ZEbjS!!!$T#h!Xk3Y`,1N,F#c!"J
X!!J!!8YP69&**!3KcG(*TEQFZD!"c!!1N,(fIT#apRk3XICm!'!!#!!"5f8a*68N
X"#'aTE@PdFbjS!(-!!k3Y`%#N,F"!T#h!3!!B!!)!!&,C8e4%4!%)Fh4NC'9Q,QJ
X!F`!%T#h!)U3Y`#+N,F!L!"J!!J!!8YPA3dK"!!PhBfKKFPpd,QJ!!!1N,P%0T#j
X4$D3Z83d!'!!#!!"5f9084%`"#(0dC'aTBLjS!*!$!k3YZmfN,E[0T#flc3!B!!)
X!!&,C8dP(6J%)FfPREQ&X,QJ!N!-$T$(rN!#N-Iq3!+3arj!!!"B!!J!!8YP'3dj
X8!3GQBfjdE#jS!!!$U68(9+Ne"e5T03G8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ
X!!!5N,F#*T#h!LD3Y`)N!&J!#!!"5f94*688""R4TE@8ZD!!Z!!1T03G5U68(8UN
Xe"e)!'!!"!!"8FNe"3d3!#'eKBf4TFLjS!*!$!DTP-PUUC6*DUQ8b@J!@!!%!!&4
Xb3e*C8!!(Bh*jF(3ZD!!`!"3XarP!!"3XarP!!!!"!!$rN!LU8D&f!"3!!J!!8Y9
X"6P0*!!4"6P0*!(S!N!5N+ih+T#Z0bJ!@!!)!N!8"!*!$#!4YB@PZ)*!$!!+N+ib
XJT#Z-S+3VM+!!&J!#!!"5f8958Ni""f9bFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-!'!!
X#!!"5f9088NN"#(0dFQPZCbjS!(-!!U3XICqN,(fIT#apR`!B!!)!!&,C6%P053%
X)E'PYDA4c,QJ!F`!#T#h!3+3Y`%#N,F"!!"J!!J!!8YP69%4%!3KcG'4NC@BZD!"
Xc!!1N,F!LT#h!)U3Y`#)!'!!#!!"5f9G$5%%!#AGMD'&bAh3ZD!!!!U3Z83fN,P%
X0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-#T#flcD3YZmfN,E[0!"J!!J!
X!8YP658G1!3KcD@GZB@`ZD!#3!`+N-Iq3!+3arj!!T$(rN!!!&J!#!!"5f8C$6P3
X""fCMER4X,QJ!!!+T03G8U68(9+Ne"e3!'!!"!!"8FNe"3e-!#@eKBh0dBA3ZD!!
X!!k3Y`)QN,F#*T#h!L3!@!!)!!&,C9%P043%'G'PYC5jS!#i!!UNe"e+T03G5U68
X(8J!B!!%!!&4b68&$4!!)E@&MC'Pb,QJ!!!S!&#c(q8!!&#c(q8!!!!%!!2q3#+T
Xf4*`!&J!"!!"8FP91@NN!"h9ZHQP`,Q-!!!'NPm)*T*I##D5A`JN!'J!#!!"6(Ne
X"3dJ"#NeKBdKPB@4PFR-!N!-"UR9FT+TeA+5UG9bN!"B!!3!!9(*96PT*!!GeERT
XTF#jS!!!#T$-G2D3c(6fN-adp!"B!!J!!8YP69%4*!3GcG'4TEbjS!!!$T#frqk3
XY[rZN,Erl!"J!!J!!8YP659T&!!KcDATPAh3ZD!"c!!+N+ih+T#Z0bU3VMFS!&J!
X#!!"5f808@9!""f0dHA"P,QJ!!!+N+ibJT#Z-S+3VM+!!&J!#!!"5f8958Ni""f9
XbFQj[,QJ!!!+N,F#cT#h!Xk3Y`,-!'!!#!!"5f9088NN"#(0dFQPZCbjS!(-!!U3
XXICqN,(fIT#apR`!B!!)!!&,C6%P053%)E'PYDA4c,QJ!F`!#T#h!3+3Y`%#N,F"
X!!"J!!J!!8YP69%4%!3KcG'4NC@BZD!"c!!1N,F!LT#h!)U3Y`#)!'!!#!!"5f9G
X$5%%!#AGMD'&bAh3ZD!!!!U3Z83fN,P%0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'P
XL,QJ!N!-#T#flcD3YZmfN,E[0!"J!!J!!8YP658G1!3KcD@GZB@`ZD!#3!`+N-Iq
X3!+3arj!!T$(rN!!!&J!#!!"5f8C$6P3""fCMER4X,QJ!!!+T03G8U68(9+Ne"e3
X!'!!"!!"8FNe"3e-!#@eKBh0dBA3ZD!!!!k3Y`)QN,F#*T#h!L3!@!!)!!&,C9%P
X043%'G'PYC5jS!#i!!UNe"e+T03G5U68(8J!B!!%!!&4b68&$4!!)E@&MC'Pb,QJ
X!N!-"UQ8b@UTP-PUUC6*D!"B!!3!!9(*$8PP3!!GMFRP`G#jS!!!"URBlPUTf1jD
XUGMZ@!"J!!3!!9(*@49*6!!PfCA*cD@pZ,QJ!#J!8,-Ij3!!8,-Ij3!!!!3!!rj!
X)UP9eCJ!B!!%!!&4b58j'6!!*D@jQE'&dC5jM!!!"T*I##D5A`JQNPm)*!"S!!J!
X!8aj0380)!3T0B@0)C@&NCA*c!*!$!DT4B`DU8@-'UP&M"J!B!!%!!&4b58j'6!!
X*D@jQE'&dC5jS!!!#UR9FT+TeA+5UG9bN!"B!!3!!9(*96PT*!!GeERTTF#jS!!!
X$T$-G2D3c(6fN-adp!"B!!J!!8YP69%4*!3GcG'4TEbjS!!!%T#frqk3Y[rZN,Er
Xl!"J!!J!!8YP659T&!!KcDATPAh3ZD!#3!`1N+ih+T#Z0bU3VMFS!&J!#!!"5f80
X8@9!""f0dHA"P,QJ!!!1N+ibJT#Z-S+3VM+!!&J!#!!"5f8958Ni""f9bFQj[,QJ
X!!!1N,F#cT#h!Xk3Y`,-!'!!#!!"5f9088NN"#(0dFQPZCbjS!*!$!k3XICqN,(f
XIT#apR`!B!!)!!&,C6%P053%)E'PYDA4c,QJ!N!-$T#h!3+3Y`%#N,F"!!"J!!J!
X!8YP69%4%!3KcG'4NC@BZD!#3!`5N,F!LT#h!)U3Y`#)!'!!#!!"5f9G$5%%!#AG
XMD'&bAh3ZD!!!!k3Z83fN,P%0T#j4$3!B!!)!!&,C8e4%6!%)Fh4NE'PL,QJ!N!-
X$T#flcD3YZmfN,E[0!"J!!J!!8YP658G1!3KcD@GZB@`ZD!#3!`1N-Iq3!+3arj!
X!T$(rN!!!&J!#!!"5f8C$6P3""fCMER4X,QJ!!!1T03G8U68(9+Ne"e3!'!!"!!"
X8FNe"3e-!#@eKBh0dBA3ZD!!!"+3Y`)QN,F#*T#h!L3!@!!)!!&,C9%P043%'G'P
XYC5jS!#i!!kNe"e+T03G5U68(8J!B!!%!!&4b68&$4!!)E@&MC'Pb,QJ!N!38,-I
Xj3!!8,-Ij3!!!!3!!rj!)T*ceFJ!B!!)!!&0k68&$9!!*6@&M9(*KF(-b!!S!&#c
X(q8!!&#c(q8!!!!%!!2q3#+T,HIS!'J!"!!"8FNe"3e8!#QeKBh9ZHQP`,Q-!N!-
X"T*I##D5A`JQNPm)*!"S!!J!!8aj0380)!3T0B@0)C@&NCA*c!*!$!DTeA+5UG9b
XNUR9FT!!@!!%!!&4b98jD53!(G@jkDA!ZD!!!!U3c(6fN-adpT$-G23!@!!)!!&,
XC8e4%53%(Fh4ND@mZD!!!!k3Y[rZN,ErlT#frq`!B!!)!!&,C8dPD43!)FfPkC9p
Xd,QJ!F`!#T#Z0bU3VMFUN+ih+!"B!!J!!8YP$9&P3!3GMG(P`C5jS!!!#T#Z-S+3
XVM+#N+ibJ!"B!!J!!8YP&8P*1!3GPFR*ZEbjS!!!#T#h!Xk3Y`,1N,F#c!"J!!J!
X!8YP69&**!3KcG(*TEQFZD!"c!!+N,(fIT#apRk3XICm!'!!#!!"5f8a*68N"#'a
XTE@PdFbjS!(-!!U3Y`%#N,F"!T#h!3!!B!!)!!&,C8e4%4!%)Fh4NC'9Q,QJ!F`!
X$T#h!)U3Y`#+N,F!L!"J!!J!!8YPA3dK"!!PhBfKKFPpd,QJ!!!+N,P%0T#j4$D3
XZ83d!'!!#!!"5f9084%`"#(0dC'aTBLjS!*!$!U3YZmfN,E[0T#flc3!B!!)!!&,
XC8dP(6J%)FfPREQ&X,QJ!N!-#T$(rN!#N-Iq3!+3arj!!!"B!!J!!8YP'3dj8!3G
XQBfjdE#jS!!!#U68(9+Ne"e5T03G8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ!!!1
XN,F#*T#h!LD3Y`)N!&J!#!!"5f94*688""R4TE@8ZD!!Z!!+T03G5U68(8UNe"e)
X!'!!"!!"8FNe"3d3!#'eKBf4TFLjS!*!$!D3@1F#N&MR!T"Bj`!!@!!)!!&-I9&*
X"8!%(9(*KF(-ZD!!!!D3@1F#N&MR!T"Bj`!!B!!)!!&-I9N&-93%)9Q&XG@9c,QJ
X!N!-#T+M%dU5Sa0+NU-65!"B!!J!!8h*638j&!3C638j&,QJ!D+TeA+5UG9bNUR9
XFT!!@!!%!!&4b98jD53!(G@jkDA!ZD!!!!U3c(6fN-adpT$-G23!@!!)!!&,C8e4
X%53%(Fh4ND@mZD!!!!k3Y[rZN,ErlT#frq`!B!!)!!&,C8dPD43!)FfPkC9pd,QJ
X!F`!#T#Z0bU3VMFUN+ih+!"B!!J!!8YP$9&P3!3GMG(P`C5jS!!!#T#Z-S+3VM+#
XN+ibJ!"B!!J!!8YP&8P*1!3GPFR*ZEbjS!!!#T#h!Xk3Y`,1N,F#c!"J!!J!!8YP
X69&**!3KcG(*TEQFZD!"c!!+N,(fIT#apRk3XICm!'!!#!!"5f8a*68N"#'aTE@P
XdFbjS!(-!!U3Y`%#N,F"!T#h!3!!B!!)!!&,C8e4%4!%)Fh4NC'9Q,QJ!F`!$T#h
X!)U3Y`#+N,F!L!"J!!J!!8YPA3dK"!!PhBfKKFPpd,QJ!!!+N,P%0T#j4$D3Z83d
X!'!!#!!"5f9084%`"#(0dC'aTBLjS!*!$!U3YZmfN,E[0T#flc3!B!!)!!&,C8dP
X(6J%)FfPREQ&X,QJ!N!-#T$(rN!#N-Iq3!+3arj!!!"B!!J!!8YP'3dj8!3GQBfj
XdE#jS!!!#U68(9+Ne"e5T03G8!"J!!3!!9(*03806!!PYB@0cG'&d,QJ!!!1N,F#
X*T#h!LD3Y`)N!&J!#!!"5f94*688""R4TE@8ZD!!Z!!+T03G5U68(8UNe"e)!'!!
X"!!"8FNe"3d3!#'eKBf4TFLjS!!"`D@jR#J"PFR*[FL"E*A0G1L!JBQ&N)'9iG(*
XK)'CTC@aN)%053b!P-$KXH#!SFfK[G@aN!*!$B!#3!h!!N!G3!*!$)!!F2c`!!DR
X`"GBr2!!"UI!&kMmm!!'Tm!Aq2c`!!DR`"KSr2!!"UI!'8$mm!!'Tm!C`2c`!!DR
X`"T)r2!!"UI!'XMmm!!'Tm!NX2c`!!DR`!*!$"!#3"`3!N!F%!*!'#6i!N!-+!*!
XE&8*i#NUGcNkk!&41ZJ"N,$a*6N4B6VS(1NIkrmSQM%IkrmJQK%kk!'a1ZJ1L6VS
X(mNkk!0j1ZJ#U3QG)H2rr5'm!"%KA5(J!!5)krl*1ZJ916V8B!#"Y!'a1N!#Tp&(
Xi#Pj`!%kk"-CR"NU3!'F#S%P1G5!i#RKQ$L`m@Np148kk"Y)J$'!'*N!J+`!J4rV
XrB#D!6R8X2%4"9%&1ZJDf)%`LH!N))!5J,Nkk"fT(q[p)*S3X2&088P01ZJDB4rV
Xr0#D-,$a%8N9-6VS'L#"-)!4R$%kk!Ui%J!#3!`aQp%lk"c419[rD3IJ*%#*2F##
XJ,R!"d"&D%G,!3IS!%R!&S#j9MdK[!!+TPdjH6R8ZFR0bB`"(qJIf*VJ+I#"i#RL
Xar!#3"'F)4rS(jLDS!"B[1!U!CJ*BMdje@)p)jrri2Lm!1&(i#PjJ#PQ2,`LTT5!
XIS%!`"dkk!pCRE%IkrTiQL#!3Cq3L3%U4CLkJ+D"*,$a$8N9-6VS&hQG-2Lm!1#"
X-)!4R$%kk!0S%J!#3!`aQp%kk"S*1ZJ*m)(VqB+"T#!!!"fB%S'5J+8kk!ZBLE`!
XdABN[53!f60mIre525MJ",@F#UIp1GA!2UFPBMb"[!!3-8%ljCJi`)%kk!e*Rk+!
XU6VS#J#kI6R91ZJFU6VS!$Nkk"TK1G8kk"aa1G5!k"a"Q!!!b)(J#TR!-d*!!X,J
X#UQBL)(J+l+!P)&!L5#)BB!T"k!!)G!'%'0$#8FRrp*!!L0#*CJ*1G5)!S#iJH!V
XX)!'J*#*36qrr`#"23UJ!%M&T!!3!&U!93UG)D3!-)%qTmM)B6VS#lL4BeF%d'#)
XBEMjR)P*"Ca*53@FQ9N&R!!#Z8N&R!!#B6R8b+2rd6VS#r0056R8b+2rd6VS#c00
X56R8b+2rd6VS#dY1Urrj1G8kk!T)b+3!-5QN!#QBJ9%*U%&*#CRK`BkR*8N*Qq00
X56R91ZJ+8dUN!$Y056R91ZJ+XdUN!$Ja#rraRBQeS8N*Q"0056R9$p4J#[P&Qc!a
XK2caQaP*#CJB+DJ!Arrib)9K")RVmk0+4NNV68Nje-LMrp%kk!QM5MG1Urrj1G6)
XSrr41ZJ)ddSh6U[rq6R91ZJ)SdUN!$Y+0dkVrrNjedSh6U[rq6R9$p4J#[P&Qm!a
XK2caQkJTU!!2rr$)KA%%LH[b-dT(5U[rqNNSe3Irq0,a1F8je-KK1ZJ(J4I8B!0A
XB0"KR-L)BEL4R$P*"CK3b+2rd6VS"k'!B-LMrp%kk!ETJ$M)Srr41ZJ(#B!C1ZJ(
XLdSh6NNje)KK1ZJ(@de*1G5"kr"BJ1[`@5UJ!!'FS-LJ!+'FL*#J!'&P#3qd!%02
XS!!69@6,m2ca#'4,S!$dbr+R`88&Ql%(S!%!%J!#3!d"QaNje)(VldL!kqp*brh3
X!5UJ!!'FD[LJ!2@B80LJ!+%M$C`c8Jl+S!!4P"#)S!!4"k!"!")!!N!0!CY3JH[Z
XZ)&"`%*+!jSN``HD+!%+!!$$#6R8J8()!-KJ`'!*!IrrRL82e'#!d%@!5)LN!"*+
X)-X%br$mm-X)br+R`8FMrl'!f)"#J95"!FJ!b'$!B!N"rrqH*3r8B)!aT6[N!!QF
XB0#N!"'!1-K&)F"!!-X)br%lj)Yp4b2r`)$S!#L"!CJ*K"Nl3!*!%-$bJ[D0')JJ
X`2+LITdDbL'F'3IS!,'!J$$J!"!%[C3C"qJ!LB")-1!!#!5pP"N(k!"KJ"%(k!"j
X$q[r#)SK1GD#p6RAdq%je6RS!!JM!!!01H`!#6R9CMbmm3dp%46m!UD!JAe$i#Pi
XJ#%je+(VkUL*-Np6PJGR"dp41G5KkqT,#r!"!)M3B'#KkqTV5P%je+(VkIX,m!%!
XL0"J)NVVkJNje+(VkE-,m!%!L0"J3dVVkE%je+(Vk@X,m!%!L0"J%"S%!N!-36R9
X1Z[qL-LN!$%TT!!TQ"NkkrlKJ"%kkrpE5U3!16R8JAc)B0"L`@&I*rrT+3QIq6[!
XJr#"I-KJd',#B9mRrqNT#Crj1m#$k)&mb'$3BX%*Z#T!!3@d'd%""m!!#-""RrNl
X`!!!J,`!%,d%!"#)[!!J[A`!%51Fm!#3!*J&)3X6$+!!U!8K&b-A84%K#N!2!`G#
X#60m!2#)I6R8J,`!%,d%!"#)[!!J[A`!%51Fa!%kk!*a-h`#-)Kp1G5![!!3[33!
X%)Lm!##pI!!4)jc%!6VS!I#!"60m!M#)I6R8J,`!%,d%!"#)[!!J[A`!%51Fa!%k
Xk!#a-h`#-)Kp1G5![!!3[33!%)Lm!##pI!!4)jc%!6VS!$#!"60m!M#)I6R9+J'S
XF5S&U$%5!4)&1ZJ!J4)&1G85!6VS!&N5!4)&1G8U"DJT%J8kk!!C%J%je,M`!!2r
XrXS"M"L)!F!"1GE#(BJb!`8K!-J"#3%K!6R@bKf)D,J"#3%K!J-&)3%K(2J")4il
X"-!G)4c)(6R8N!#B"iSMLLE+(B[L!`F#(-J2#`#i$5%I1`%K(dSGP#*+#BJ4%J8j
Xe8d"Jj(i!8IJ+APQ2,`Br"kQJ)"pR!!#Z*N"CMbm,UD8Q(b!,+!054qp(8NFk"f!
X@@Bm["Mm(UD!J(fF!!)K54`D%!!"rrP@2,`#TTM!I#!!!"@EF82J+AXp&QNGQ(#!
X$S%![#kQL)"0R!!"D,`ZTNLK6)%ZJ+A!"6R8J"+%H)!KR!!"#+%J[#kQL)"0R!!!
Xf)%XJ!f!B@Bm["Mm(UD!J(fF!!#*54b"!)$`!!(rq,`JJ8#*-fF#J,UQM8FhrfTR
X%*Na`!8je)%Y+4@B%S#01GD!I6R8b2+R`3rVj%%kk!,!b2+Rb3rVj[%kk!+3b2+R
Xa3rVjLNkk!*Jb2+Rc3rVjT#"i#RLar!#3"'F3)#J!&QF+)#J!('F86[S!G%kk!(!
Xb2+Rd3rVjG%lk!'41ZJ"J-MbTp%2kqA*1qJ"8,`JJE`!),fJ!!J!))$S!GQB!!$`
XJH!+QF!c3N!#`Z!+UCLa1ZJ"Q-MbTm%kk!%)b2+Ra6VS!1M)mUI*1ZJ!b-MbTmdk
Xk!#Sb2+Rd6VS!)L"I6R8`!D&'*%K`$+%H-!'J4c$m6VNJb6$m6[NJbNje-!'K4L*
XS!!LJ(c!")%QJ4dje!*!)6R8J1[rdC`3J3%+3!%je!*!U!3#3!dhb!!"-mJ!!!GS
X!'cC!"eS!N!-F!G)!%%K"8dJ!N!1+@Np143#3!jC,58j%!*!$SPG-6d-!N!1Z58j
X%@!#3!lT$6d4&!!3!aN4"9%%!!!%#8e458`!!!3j%8N9-!!!"'P0C69-!!!%Q3dj
X'4`!!!6*659T&!!!"2N4#8e3!!!&+4%*A8`!!!9C$8N9-!!)"BN4#98F!!J''9%9
XB9!!!!DS!!3#3"b$b2!!!rrm!!!X)!#$br!!!rrm!!!4%!#$c8!!!rrm!!!2d!#$
Xc!*!$rrm!!!@J!#$b3!!!rrm!!%--!#$bB!!#rrm!!%0`!#$bG!!%rrm!!%0i!#$
XbS!!$rrm!!%1!!#$bR!!"rrm8!%1)!#$c%!!!rrm!!%c+!#$bC!!!rrm!!%c1!#$
Xb-!!!rrm!!%c5!#$bQ!!!rrm!!%c@!#$bE!!'rrm!!!3!!#$b82rr!!B!!!3F!#$
XbH!#!rrm!!!VN!#$c'!#!rrm!!!VZ!#$c-!!#rrm!!%cD!#$bU!!%rrm!!%cH!#$
XbV!!$rrm!!%cL!#$bM!!#rrm!!%cQ!#$bP!!%rrm!!%cU!#$c3!!$rrm!!%cZ!#$
XbA!!!rrm!!!3U!#$bT!9YDf&SE!%f"pi:
END_OF_FILE
if test 24586 -ne `wc -c <'unzip-5.12/mac/thinkc.hqx'`; then
echo shar: \"'unzip-5.12/mac/thinkc.hqx'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/thinkc.hqx'
fi
if test -f 'unzip-5.12/unix/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/Makefile'\"
else
echo shar: Extracting \"'unzip-5.12/unix/Makefile'\" \(27036 characters\)
sed "s/^X//" >'unzip-5.12/unix/Makefile' <<'END_OF_FILE'
X#==============================================================================
X# Makefile for UnZip, UnZipSFX and fUnZip: Unix and MS-DOS ("real" makes only)
X# Version: 5.12 25 August 1994
X#==============================================================================
X
X
X# INSTRUCTIONS (such as they are):
X#
X# "make vax" -- makes UnZip on a generic Unix VAX in the current directory
X# "make list" -- lists all supported systems (targets)
X# "make help" -- provides pointers on what targets to try if problems occur
X# "make wombat" -- chokes and dies if you haven't added the specifics for your
X# Wombat 68000 (or whatever) to the systems list
X#
X# CF are flags for the C compiler. LF are flags for the loader. LF2 are more
X# flags for the loader, if they need to be at the end of the line instead of at
X# the beginning (for example, some libraries). FL and FL2 are the corre-
X# sponding flags for fUnZip. LOCAL_UNZIP is an environment variable that can
X# be used to add default C flags to your compile without editing the Makefile
X# (e.g., -DDEBUG_STRUC, or -FPi87 on PCs using Microsoft C).
X#
X# Some versions of make do not define the macro "$(MAKE)"; this is rare, but
X# if things don't work, try using "make" instead of "$(MAKE)" in your system's
X# makerule. Or try adding the following line to your .login file:
X# setenv MAKE "make"
X# (That never works--makes which are too stupid to define MAKE are also too
X# stupid to look in the environment--but try it anyway for kicks. :-) )
X#
X# Memcpy and memset are provided for those systems that don't have them; they
X# are in file_io.c and will be used if -DZMEM is included in CF. These days
X# almost all systems have them.
X#
X# Be sure to test your new UnZip (and UnZipSFX and fUnZip); successful compila-
X# tion does not always imply a working program.
X
X
X#####################
X# MACRO DEFINITIONS #
X#####################
X
X# Defaults most systems use (use LOCAL_UNZIP in environment to add flags,
X# such as -DDOSWILD).
X
X# UnZip flags
XCC = cc# try using "gcc" target rather than changing this (if you do,
XLD = $(CC)# you MUST change LD, too--else "unresolved symbol: ___main")
XLOC = $(LOCAL_UNZIP)
XCF = -O -I. $(LOC)
XLF = -o unzip
XLF2 = -s
X
X# UnZipSFX flags
XSL = -o unzipsfx
XSL2 = $(LF2)
X
X# fUnZip flags
XFL = -o funzip
XFL2 = $(LF2)
X
X# general-purpose stuff
XCP = cp
XLN = ln
XRM = rm -f
XCHMOD = chmod
XSTRIP = strip
XE =
XO = .o
XM = unix
XSHELL = /bin/sh
X
X# object files
XOBJS1 = unzip$O crypt$O envargs$O explode$O extract$O file_io$O
XOBJS2 = inflate$O match$O unreduce$O unshrink$O zipinfo$O
XOBJS = $(OBJS1) $(OBJS2) $M$O
XLOBJS = $(OBJS)
XOBJX = unzipsfx$O crypt$O extract_$O file_io$O inflate$O match$O $M_$O
XLOBJX = $(OBJX)
XOBJF = funzip$O crypt_$O inflate_$O
X#OBJS_OS2 = $(OBJS1:.o=.obj) $(OBJS2:.o=.obj) os2.obj
X#OBJF_OS2 = $(OBJF:.o=.obj)
X
X# installation
XINSTALL = cp# probably can change this to 'install' if you have it
X# on some systems, manext=l and MANDIR=/usr/man/man$(manext) may be appropriate
Xmanext = 1
Xprefix = /usr/local
XBINDIR = $(prefix)/bin# where to install executables
XMANDIR = $(prefix)/man/man$(manext)# where to install man pages
XINSTALLEDBIN = $(BINDIR)/funzip$E $(BINDIR)/zipinfo$E $(BINDIR)/unzipsfx$E \
X $(BINDIR)/unzip$E
XINSTALLEDMAN = $(MANDIR)/unzip.$(manext) $(MANDIR)/funzip.$(manext) \
X $(MANDIR)/unzipsfx.$(manext) $(MANDIR)/zipinfo.$(manext)
X#
XUNZIPS = unzip$E funzip$E unzipsfx$E
X# this is a little ugly...well, no, it's a lot ugly:
XMANS = unix/unzip.1 unix/unzipsfx.1 unix/zipinfo.1 unix/funzip.1
XDOCS = unzip.doc unzipsfx.doc zipinfo.doc funzip.doc
X
X# list of supported systems/targets in this version
XSYSTEMS1 = 386i 3Bx 7300 7300_gcc aix aix_rt amdahl amdahl_eft apollo
XSYSTEMS2 = aviion bcc_dos bsd bsd386 bull coherent convex cray cray_scc
XSYSTEMS3 = cray_v3 cyber_sgi dec dnix encore eta gcc gcc_dos generic
XSYSTEMS4 = generic2 generic3 gould hk68 hp hpux linux minix mips msc_dos
XSYSTEMS5 = next next10 next2x next3x nextfat osf1 pixel ptx pyramid
XSYSTEMS6 = regulus rs6000 sco sco_dos sco_sl sco_x286 sequent sgi solaris
XSYSTEMS7 = stellar sun sysv sysv_gcc sysv6300 tahoe ultrix vax v7 wombat
XSYSTEMS8 = xenix xos
X
X####################
X# DEFAULT HANDLING #
X####################
X
X# By default, print help on which makefile targets to try. (The SYSTEM
X# variable is no longer supported; use "make <target>" instead.)
X
Xhelp:
X @echo ""
X @echo\
X " If you're not sure about the characteristics of your system, try typing"
X @echo\
X ' "make generic". If the compiler barfs and says something unpleasant about'
X @echo\
X ' "timezone redefined," try typing "make clean" followed by "make generic2".'
X @echo\
X ' If, on the other hand, it complains about an undefined symbol _ftime, try'
X @echo\
X ' typing "make clean" followed by "make generic3". One of these actions'
X @echo\
X ' should produce a working copy of unzip on most Unix systems. If you know'
X @echo\
X ' a bit more about the machine on which you work, you might try "make list"'
X @echo\
X ' for a list of the specific systems supported herein. (Many of them do'
X @echo\
X " exactly the same thing, so don't agonize too much over which to pick if"
X @echo\
X ' two or more sound equally likely.) Also check out the INSTALL file for'
X @echo\
X ' notes on compiling various targets. As a last resort, feel free to read'
X @echo\
X ' the numerous comments within the Makefile itself. Note that to compile'
X @echo\
X ' the decryption version of UnZip, you must obtain the full versions of'
X @echo\
X ' crypt.c and crypt.h (see the "Where" file for ftp and mail-server sites).'
X @echo\
X ' Have a mostly pretty good day.'
X @echo ""
X
Xlist:
X @echo ""
X @echo\
X 'Type "make <system>", where <system> is one of the following:'
X @echo ""
X @echo " $(SYSTEMS1)"
X @echo " $(SYSTEMS2)"
X @echo " $(SYSTEMS3)"
X @echo " $(SYSTEMS4)"
X @echo " $(SYSTEMS5)"
X @echo " $(SYSTEMS6)"
X @echo " $(SYSTEMS7)"
X @echo " $(SYSTEMS8)"
X# @echo ""
X# @echo\
X# 'Targets for related utilities (ZipInfo and fUnZip) include:'
X# @echo ""
X# @echo " $(SYS_UTIL1)"
X# @echo " $(SYS_UTIL2)"
X @echo ""
X @echo\
X 'For further (very useful) information, please read the comments in Makefile.'
X @echo ""
X
Xgeneric_msg:
X @echo ""
X @echo\
X ' Attempting "make generic" now. If this fails for some reason, type'
X @echo\
X ' "make help" and/or "make list" for suggestions.'
X @echo ""
X
X
X###############################################
X# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES #
X###############################################
X
X# this is for GNU make; comment out and notify zip-bugs if it causes errors
X.SUFFIXES: .c $O
X
X.c$O:
X $(CC) -c $(CF) $*.c
X
X# this doesn't work...directories are always a pain with implicit rules
X#.1.doc: unix/$<
X# nroff -Tman -man $< | col -b | uniq | \
X# sed 's/Sun Release ..../Info-ZIP /' > $@
X
X
X# these rules are specific to Suns and are really intended only for the
X# authors' use in creating non-Unix documentation files (which are pro-
X# vided with both source and binary distributions). We should probably
X# add a ".1.man" rule for more generic systems...
X
Xunzip.doc: unix/unzip.1
X nroff -Tman -man unix/unzip.1 | col -b | uniq | \
X sed 's/Sun Release ..../Info-ZIP /' > $@
X
Xunzipsfx.doc: unix/unzipsfx.1
X nroff -Tman -man unix/unzipsfx.1 | col -b | uniq | \
X sed 's/Sun Release ..../Info-ZIP /' > $@
X
Xzipinfo.doc: unix/zipinfo.1
X nroff -Tman -man unix/zipinfo.1 | col -b | uniq | \
X sed 's/Sun Release ..../Info-ZIP /' > $@
X
Xfunzip.doc: unix/funzip.1
X nroff -Tman -man unix/funzip.1 | col -b | uniq | \
X sed 's/Sun Release ..../Info-ZIP /' > $@
X
X
Xall: generic_msg generic
Xunzips: $(UNZIPS)
Xdocs: $(DOCS)
Xunzipsman: unzips docs
Xunzipsdocs: unzips docs
X
X# this really only works for Unix targets, unless specify E and O on cmd line
Xclean:
X rm -f $(OBJS) $(OBJF) $(OBJX) $(UNZIPS)
X
Xinstall: $(UNZIPS) $(MANS)
X $(INSTALL) $(UNZIPS) $(BINDIR)
X $(RM) $(BINDIR)/zipinfo$E
X $(LN) $(BINDIR)/unzip$E $(BINDIR)/zipinfo$E
X $(INSTALL) unix/unzip.1 $(MANDIR)/unzip.$(manext)
X $(INSTALL) unix/unzipsfx.1 $(MANDIR)/unzipsfx.$(manext)
X $(INSTALL) unix/zipinfo.1 $(MANDIR)/zipinfo.$(manext)
X $(INSTALL) unix/funzip.1 $(MANDIR)/funzip.$(manext)
X $(CHMOD) 755 $(INSTALLEDBIN)
X $(CHMOD) 644 $(INSTALLEDMAN)
X
X# alternatively, could use zip method: -cd $(BINDIR); rm -f $(UNZIPS) [etc.]
Xuninstall:
X rm -f $(INSTALLEDBIN) $(INSTALLEDMAN)
X
X
X# EDIT HERE FOR PARALLEL MAKES on Sequent (and others?)--screws up MS-DOS
X# make utilities if default: change "unzip$E:" to "unzip$E:&"
X
Xunzip$E: $(OBJS) # add `&' for parallel makes
X $(LD) $(LF) $(LOBJS) $(LF2)
X
Xunzipsfx$E: $(OBJX) # add `&' for parallel makes
X $(LD) $(SL) $(LOBJX) $(SL2)
X
Xfunzip$E: $(OBJF) # add `&' for parallel makes
X $(LD) $(FL) $(OBJF) $(FL2)
X
Xzipinfo$E: unzip$E
X @echo\
X ' This is a Unix-specific target. ZipInfo is not enabled in some MS-DOS'
X @echo\
X ' versions of UnZip; if it is in yours, copy unzip.exe to zipinfo.exe'
X @echo\
X ' or else invoke as "unzip -Z" (in a batch file, for example).'
X $(LN) unzip$E zipinfo$E
X
X
Xcrypt$O: crypt.c unzip.h zip.h crypt.h
Xenvargs$O: envargs.c unzip.h
Xexplode$O: explode.c unzip.h
Xextract$O: extract.c unzip.h crypt.h
Xfile_io$O: file_io.c unzip.h crypt.h tables.h
Xfunzip$O: funzip.c unzip.h crypt.h tables.h
Xinflate$O: inflate.c inflate.h unzip.h
Xmatch$O: match.c unzip.h
Xunreduce$O: unreduce.c unzip.h
Xunshrink$O: unshrink.c unzip.h
Xunzip$O: unzip.c unzip.h crypt.h version.h
Xzipinfo$O: zipinfo.c unzip.h
X
Xcrypt_$O: crypt.c unzip.h zip.h crypt.h # funzip only
X $(CP) crypt.c crypt_.c
X $(CC) -c $(CF) -DFUNZIP crypt_.c
X $(RM) crypt_.c
X
Xextract_$O: extract.c unzip.h crypt.h # unzipsfx only
X $(CP) extract.c extract_.c
X $(CC) -c $(CF) -DSFX extract_.c
X $(RM) extract_.c
X
Xinflate_$O: inflate.c inflate.h unzip.h crypt.h # funzip only
X $(CP) inflate.c inflate_.c
X $(CC) -c $(CF) -DFUNZIP inflate_.c
X $(RM) inflate_.c
X
Xmsdos$O: msdos/msdos.c unzip.h # MS-DOS only
X $(CC) -c $(CF) msdos/msdos.c
X
Xmsdos_$O: msdos/msdos.c unzip.h # MS-DOS unzipsfx only
X $(CP) msdos\msdos.c msdos_.c > nul
X $(CC) -c $(CF) -DSFX msdos_.c
X $(RM) msdos_.c
X
X#os2$O: os2/os2.c unzip.h # OS/2 only
X# $(CC) -c $(CF) os2/os2.c
X
Xunix$O: unix/unix.c unzip.h # Unix only
X $(CC) -c $(CF) unix/unix.c
X
Xunix_$O: unix/unix.c unzip.h # Unix unzipsfx only
X $(CP) unix/unix.c unix_.c
X $(CC) -c $(CF) -DSFX unix_.c
X $(RM) unix_.c
X
Xunzipsfx$O: unzip.c unzip.h crypt.h version.h # unzipsfx only
X $(CP) unzip.c unzipsfx.c
X $(CC) -c $(CF) -DSFX unzipsfx.c
X $(RM) unzipsfx.c
X
X
Xunix_make:
X# @echo\
X# '(Ignore any errors from `make'"' due to the following command; it's harmless.)"
X -@2>&1 $(LN) unix/Makefile . > /dev/null || echo > /dev/null
X
X
X################################
X# INDIVIDUAL MACHINE MAKERULES #
X################################
X
X##### TABS ARE REQUIRED FOR MANY VERSIONS OF "MAKE"! #####
X
X
X#----------------------------------------------------------------------------
X# Generic targets (can't assume make utility groks "$(MAKE)")
X#----------------------------------------------------------------------------
X
Xgeneric: unzips # first try if unknown
X
Xgeneric2: unix_make # second try if unknown: hope make is called "make"
X make unzips CF="$(CF) -DBSD"
X
Xgeneric3: unix_make # third try if unknown: hope make is called "make"
X make unzips CF="$(CF) -DSYSV"
X
X#----------------------------------------------------------------------------
X# "Normal" group (both big- and little-endian, structure-padding or not):
X#----------------------------------------------------------------------------
X
X386i: unzips # sun386i, SunOS 4.0.2
X3Bx: unzips # AT&T 3B2/1000-80; should work on any WE32XXX machine
X#aix_rt: unzips # IBM RT 6150 under AIX 2.2.1
Xapollo: unzips # Apollo Domain/OS machines
Xbull: unzips # Bull DPX/2, BOS 2.00.45 (doesn't require -Xk switch)
Xconvex: unzips # Convex C-120 and C-210 (-O is enough; -ext is default)
Xcray: unzips # Cray-2 and Y-MP, using default (possibly old) compiler
Xdec: unzips # DEC 5820 (MIPS RISC), test version of Ultrix v4.0
Xencore: unzips # Multimax
Xeta: unzips # ETA-10P*, hybrid SysV with BSD 4.3 enhancements
Xgould: unzips # Gould PN9000 running UTX/32 2.1Bu01
Xhp: unzips # HP 9000 series (68020), 4.3BSD or HP-UX A.B3.10 Ver D
Xhpux: unzips # (to match zip's makefile entry)
Xmips: unzips # MIPS M120-5(?), SysV.3 [error in sys/param.h file?]
Xnext10: unzips # NeXT (generic; use next2x or next3x for better opt.)
Xosf1: unzips # DECstation, including Alpha-based; DEC OSF/1 v1.x
Xpyr_: unzips # [failsafe target for pyramid target below]
Xpyr_ucb: unzips # Pyramids running BSD universe by default (see below)
Xsco: unzips # Xenix/386 (tested on 2.3.1); SCO Unix 3.2.0.
Xstellar: unzips # gs-2000
Xsun: unzips # old target; no good with solaris...use "sunos" now
Xsunos: unzips # Sun 3, 4; SunOS 4.x (SOME SYSTEMS ARE SYSTEM V!)
Xtahoe: unzips # tahoe (CCI Power6/32), 4.3BSD
Xultrix: unzips # VAXen, DEC 58x0 (MIPS guts), DECstation 2100; v4.x
Xvax: unzips # general-purpose VAX target (not counting VMS)
Xxenix: unzips # Xenix/386 (tested on 2.3.1); SCO Unix 3.2.0.
X
X#----------------------------------------------------------------------------
X# BSD group (for timezone structs [struct timeb]):
X#----------------------------------------------------------------------------
X
Xbsd: _bsd # generic BSD (BSD 4.2 & Ultrix handled in unzip.h)
Xbsd386: _bsd # BSDI BSD/386 version 1.0
X
X_bsd: unix_make
X $(MAKE) unzips CF="$(CF) -DBSD"
X
X#----------------------------------------------------------------------------
X# SysV group (for extern long timezone and ioctl.h instead of sgtty.h):
X#----------------------------------------------------------------------------
X
Xaix_rt: _sysv # IBM RT 6150 under AIX 2.2.1
Xamdahl: _sysv # Amdahl (IBM) mainframe, UTS (SysV) 1.2.4 and 2.0.1
Xaviion: _sysv # Data General AViiONs, DG/UX 4.3x
Xpyr_att: _sysv # Pyramids running AT&T (SysV) universe by default
Xsgi: _sysv # Silicon Graphics Iris 4D, Irix 3.3.2, 4.0.x (5.x?)
Xsolaris: _sysv # Sun SPARC & x86, Solaris 2.x
Xsysv: _sysv # generic System V Unix (Xenix handled in unzip.h)
Xxos: _sysv # Olivetti LSX-3005..3045, X/OS 2.3 and 2.4
X
X_sysv: unix_make
X $(MAKE) unzips CF="$(CF) -DSYSV"
X
X#----------------------------------------------------------------------------
X# Version 7 group (old/obsolescent):
X#----------------------------------------------------------------------------
X
Xpixel: _v7 # Pixel 80, 100 (68000-based, V7/mostly BSD4.1 compat.)
Xv7: _v7 # generic Unix Version 7 box (prob. only Pixel...)
X
X_v7:
X make unzips CF="$(CF) -DV7 -DNO_PARAM_H -DSHORT_NAMES -DBSD -DZMEM"
X
X#----------------------------------------------------------------------------
X# "Unique" group (require non-standard options):
X#----------------------------------------------------------------------------
X
X# AT&T 7300 (M68000/SysV.3) (add -DSYSV? -DNO_LIMITS?)
X7300: unix_make
X $(MAKE) unzips CF="$(CF) -DNO_DIR -DNO_MKDIR -DNO_STRNICMP"
X
X7300_gcc: unix_make
X $(MAKE) unzips CC=gcc LD=gcc LF2="" \
X CF="-O2 -I. -DNO_DIR -DNO_MKDIR -DNO_STDLIB_H -DNO_STRNICMP $(LOC)"
X $(STRIP) $(UNZIPS)
X
X# IBM AIX 3.x on an RS/6000: see rs6000 target below
Xaix: rs6000
X
X# Amdahl UTS 2.1.4 with "extended file types" filesystem (aarrrggghhhh...)
Xamdahl_eft: unix_make
X $(MAKE) unzips CF="$(CF) -eft -DSYSV"
X
X# MS-DOS: Borland C++ 3.0 (can change UnZip memory model to small for more
X# speed but no ZipInfo support [-ml -> -ms in _bcc_dos], but may run out of
X# memory when inflating--should not be true anymore in 5.11)
Xbcc_dos: _bcc_dos fu_bcc sfx_bcc
X
X_bcc_dos: bcc_rsp # v-- change to -ml for large model
X $(MAKE) unzip.exe CF="-w -ms -O2 -I. $(LOC)" CC=bcc LD=bcc E=.exe\
X O=.obj M=msdos LOBJS="" LF="@bcc_rsp" LF2=""
X del bcc_rsp
X
Xbcc_rsp:
X echo $(OBJS1:.o=.obj) > bcc_rsp
X echo msdos.obj $(OBJS2:.o=.obj) >> bcc_rsp
X
Xfu_bcc:
X $(MAKE) funzip.exe CF="-w -ms -O2 -I. $(LOC)" CC=bcc LD=bcc E=.exe\
X O=.obj FL="" FL2="" CP=copy RM=del
X
Xsfx_bcc:
X $(MAKE) unzipsfx.exe CF="-w -ms -O2 -I. $(LOC)" CC=bcc LD=bcc E=.exe\
X O=.obj SL="" SL2="" CP=copy RM=del
X
X# Coherent 3.x/4.x, Mark Williams C. ``For Coherent's CC, it needs either
X# -T0 or -T150000 (or bigger) added to the CFLAGS, otherwise the compiler
X# runs out of memory and dies in zipinfo.c.'' [Fred "Fredex" Smith, 940719]
Xcoherent: unix_make
X $(MAKE) unzips CF="$(CF) -T0"
X
X# Cray-2 and Y-MP, running Unicos 5.1 to 6.1 (SysV + BSD enhancements)
X# and Standard (ANSI) C compiler 1.5, 2.0 or 3.0.
Xcray_scc: unix_make
X $(MAKE) unzips CC=scc LD=scc
X
X# Ditto, for Cray Standard C 3.0 or later.
Xcray_v3: unix_make
X $(MAKE) unzips CC="scc" LD="scc" CF="$(CF) -h scalar3 -h vector3"
X
X# The unzip41 build on a Cyber 910/SGI running Irix v3.3.3 was successful
X# with the following change to Makefile:
Xcyber_sgi: unix_make
X $(MAKE) unzips CF="$(CF) -I/usr/include/bsd"\
X LF="-lbsd $(LF)" SL="-lbsd $(SL)"
X
X# 680x0, DIAB dnix 5.2/5.3 (a Swedish System V clone)
X#
X# Options for the dnix cc:
X# -X7 = cc is strict ANSI C
X# -X9 = warnings if a function is used without a declaration
X#
Xdnix: unix_make
X $(MAKE) unzips CF="$(CF) -X7 -X9 -DDNIX"
X
X# Generic BSDish Unix gcc. ``The -O2 only works with the latest version of
X# gcc; you may have to use -O only for earlier versions. I have no idea why
X# -s causes this bug in gcc.'' [Bug: "nm: unzip: no name list", "collect:
X# /usr/bin/nm returned 1 exit status".] If you don't have strip, don't
X# worry about it (it just makes the executable smaller and can be replaced
X# with "echo" instead).
X#
Xgcc: unix_make
X $(MAKE) unzips CC=gcc LD=gcc CF="-O2 -I. $(LOC)" LF2=""
X $(STRIP) $(UNZIPS)
X
X# MS-DOS with D.J. Delorie's djgpp 1.12. Note that earlier versions of go32
X# (< 1.11) don't support DOS function 0x38 (necessary for "unzip -v foobar").
X# Note also that this set of targets has work-arounds for three bugs in the
X# older version (3.69) of GNU make formerly distributed with djgpp: (1) it
X# sets the MAKE variable incorrectly for spawning with COMMAND.COM (forward
X# slashes instead of backslashes--fixed in 3.71 by not spawning COMMAND.COM),
X# so the usual $(MAKE) has been replaced by "make"; (2) it doesn't handle
X# makefile continuation lines correctly, most likely because of the MS-DOS
X# CR-LF line-endings (seems to be fixed in 3.71?), so long lines are used;
X# and (3) it doesn't handle quotes as in CF="-O2 -Wall etc." correctly, so
X# these macros have been changed to "CF=-O2 -Wall etc." where necessary. The
X# newer GNU make (version 3.71) does not handle quotes correctly and has no
X# known work-around, so don't bother to use it. Likewise, the emx version
X# of GNU make 3.71 which is maintained by Kai Uwe Rommel has other fatal bugs
X# involving the shell (necessary for recursive targets like this one).
X# GRR 940430, 940723, 940814
X#
Xgcc_dos: _gcc_dos fu_gcc sfx_gcc
X
X# this target may be used with djgpp 1.12m1 or later; replace "_gcc_dos" above
X# with "_gcc_dos_new":
X
X_gcc_dos_new: gcc_rsp
X make unzip CC=gcc LD=gcc M=msdos "CF=-O2 -Wall -I. $(LOC)" LOBJS="" "LF=-o unzip @gcc_rsp" LF2=""
X $(STRIP) unzip
X coff2exe unzip
X# use this instead if you want to create a stand-alone executable (bigger)
X# coff2exe -s go32.exe unzip
X stubedit unzip.exe globbing=no
X# del gcc_rsp
X# del unzip
X coff2exe -g zipinfo
X stubedit zipinfo.exe runfile=unzip.exe globbing=no
X
X_gcc_dos: gcc_rsp
X make unzip CC=gcc LD=gcc M=msdos "CF=-O2 -Wall -I. $(LOC)" LOBJS="" "LF=-o unzip @gcc_rsp" LF2=""
X# $(MAKE) unzip CC=gcc LD=gcc M=msdos "CF=-O2 -Wall -I. $(LOC)"\
X# LOBJS="" LF="-o unzip @gcc_rsp" LF2=""
X $(STRIP) unzip
X coff2exe unzip
X# use this instead if you want to create a stand-alone executable (bigger)
X# coff2exe -s go32.exe unzip
X stubedit unzip.exe globbing=no
X# del gcc_rsp
X# del unzip
X#
X# @echo Ignore the following bogus error message:
X# -@copy < nul > zipinfo
X -@find " " < nul > zipinfo
X coff2exe zipinfo
X stubedit zipinfo.exe runfile=unzip.exe globbing=no
X del zipinfo
X
Xgcc_rsp:
X echo $(OBJS1) > gcc_rsp
X echo $(OBJS2) msdos.o >> gcc_rsp
X
Xfu_gcc:
X make funzip CC=gcc LD=gcc "CF=-Wall -O2 -I. $(LOC)" FL2="" CP=copy RM=del
X# $(MAKE) funzip CC=gcc LD=gcc "CF=-Wall -O2 -I. $(LOC)" FL2=""\
X# CP=copy RM=del
X coff2exe funzip
X# use this instead if you want to create a stand-alone executable (bigger)
X# coff2exe -s go32.exe funzip
X# del funzip
X
Xsfx_gcc:
X make unzipsfx CC=gcc LD=gcc M=msdos "CF=-Wall -O2 -I. $(LOC)" SL2="" CP=copy RM=del
X# $(MAKE) unzipsfx CC=gcc LD=gcc M=msdos "CF=-Wall -O2 -I. $(LOC)"\
X# SL2="" CP=copy RM=del
X $(STRIP) unzipsfx
X coff2exe unzipsfx
X# use this instead if you want to create a stand-alone executable (bigger)
X# coff2exe -s go32.exe unzipsfx
X stubedit unzipsfx.exe globbing=no
X# del unzipsfx
X
X# Heurikon HK68 (68010), UniPlus+ System V 5.0, Green Hills C-68000
Xhk68: unix_make
X $(MAKE) unzips CC="gcc" LD="gcc"\
X LF="-n $(LF)" SL="-n $(SL)" FL="-n $(FL)"\
X CF="-ga -X138 -I. $(LOC) -Dlocaltime=localti -Dtimezone=timezon"
X
X# Rules needed to build the unzip program for an SGI Iris Indigo running
X# Irix Version 4.0.1
X#indigo:
X# $(MAKE) unzips CF="-cckr $(CF) -DSYSV $(LOC)"
X
X# Linux pre-0.96 + gcc 2.1; also 0.99.13 + gcc 2.4.5. Linux is Posix
X# (almost SysV but not quite). [apparently don't need -DSHORT_NAMES]
Xlinux: unix_make
X $(MAKE) unzips CC=gcc LD=gcc
X# $(MAKE) unzips CF="$(CF) -DLINUX" CC=gcc LD=gcc (linux pre-defined?)
X
X# Minix 1.5 PC for the 386. Invoke as is to use default cc, or as "make
X# minix CC=gcc" to use gcc. Try "make linux" if you have a working termios.h.
Xminix: unix_make
X $(MAKE) unzips CF="$(CF) -DMINIX -DSHORT_NAMES" CC=$(CC) LD=$(CC)
X
X# MS-DOS: Microsoft C 6.0 and NMAKE. "nmake msc_dos" works fine, aside
X# from an irrelevant message (possibly) about the creation of a temporary
X# file. Environment variable LOCAL_UNZIP (or CL) should be set via "SET
X# LOCAL_UNZIP=-FPi87" if you use the 80x87 library; also add -G2 or -G3 if
X# using a 286/386/486. Note that setting too many things via LOCAL_UNZIP
X# may make the command line too long for the default COMMAND.COM shell, so
X# use CL instead in that case. With VC++ Pro, -O2 instead of -Oait seems to
X# work OK and makes the executables slightly faster. Use at your own risk.
X#
Xmsc_dos: _msc_dos fu_msc sfx_msc
X
X# can change UnZip memory model (-AS) to large (-AL) if necessary, but should
X# no longer be necessary in UnZip 5.11 and later
X_msc_dos: msc_rsp
X $(MAKE) unzip.exe CF="-AS -W3 -Oait -Gs -nologo -I. $(LOC)" CC=cl\
X LD=link E=.exe O=.obj M=msdos LOBJS="" LF="@msc_rsp" LF2=""
X del msc_rsp
X
Xmsc_rsp:
X echo $(OBJS1:.o=.obj) + > msc_rsp
X echo msdos.obj $(OBJS2:.o=.obj)/noi/e/st:0x0c00; >> msc_rsp
X
Xfu_msc:
X set CL=-AS -Oait -Gs -nologo -I.
X $(MAKE) funzip.exe CF="$(LOC)" CC=cl LD=link E=.exe O=.obj\
X FL="/noi/nol/e" FL2=",funzip;" RM=del CP=copy
X
Xsfx_msc:
X set CL=-AS -Oait -Gs -nologo -I.
X $(MAKE) unzipsfx.exe CF="$(LOC)" CC=cl LD=link E=.exe O=.obj M=msdos\
X SL="/noi/nol/e" SL2=",unzipsfx;" RM=del CP=copy
X
X# $(NOD): intended to be used as SET NOD=-link /nod:slibcep to allow the
X# use of default library names (slibce.lib) instead of protected-mode
X# names (slibcep.lib), but it fails: MSC adds its own /nod qualifier,
X# and there seems to be no way to override this. Typical...
X#
X# THIS TARGET RETAINED AS AN EXAMPLE ONLY. USE MAKEFILE.OS2.
X#
X#msc_os2: # 16-bit OS/2 (1.x) with MSC 6.00 (use makefile.os2)
X# $(MAKE) -nologo unzips CC=cl LD=cl E=.exe O=.obj\
X# OBJS="$(OBJS_OS2)" OBJZ="$(OBJZ_OS2)"\
X# CF="-nologo -AC -Ocegit -G2s -DOS2 -DMSC $(LOC)"\
X# LF="-nologo -AC $(LOC) -Lp -F 2000"\
X# LF2="unzip.def -o unzip.exe $(NOD)" CP=copy RM=del\
X# ZL="-nologo -AC $(LOC) -Lp -Fb" ZL2="zipinfo.def -o zipinfo.exe"
X
X# NeXT info.
Xnext:
X @echo
X @echo\
X ' Please pick a specific NeXT target: "make next10" will create a generic'
X @echo\
X ' NeXT executable; "make next2x" will create a smaller executable (for'
X @echo\
X ' NeXTstep 2.0 and higher); "make next3x" will create a small executable'
X @echo\
X ' with significantly better optimization (NeXTstep 3.0 and higher only);'
X @echo\
X ' "make nextfat" will create a fat, multi-architecture (NeXT plus Intel)'
X @echo\
X ' executable (NeXTstep 3.1 and higher only).'
X @echo
X
X# 68030 BSD 4.3+Mach. NeXT 2.x: make the executable smaller.
Xnext2x: unix_make
X $(MAKE) unzips LF2="-object -s"
X
X# NeXT 3.x: as above, plus better optimization.
Xnext3x: unix_make
X $(MAKE) unzips CF="-O2 -I. $(LOC)" LF2="-object -s"
X
X# NeXT 3.1+: make the executable fat (multi-architecture binary [MAB],
X# for "black" [NeXT] and "white" [x86] hardware, so far).
Xnextfat: unix_make
X $(MAKE) unzips CF="-O2 -I. $(LOC) -arch i386 -arch m68k" \
X LF2="-arch i386 -arch m68k -object -s"
X
X# Sequent Symmetry running Dynix/ptx (sort of SysV.3): needs to link
X# with libseq to get symlink().
Xptx: unix_make
X $(MAKE) unzips CF="$(CF) -DSYSV -DTERMIO -DPTX" LF2="$(LF2) -lseq"
X
X# Pyramid 90X (probably all) under >= OSx4.1, either universe. (This is an
X# experimental target! If it fails, use either pyr_ucb or pyr_att instead.)
X# The make in the BSD half is too stupid to understand $(MAKE), sigh...
Xpyramid: unix_make
X -make pyr_`universe`
X
X# REGULUS: 68040-based, "real-time" SysV.3 mutant; uses gcc, with "REGULUS"
X# predefined.
Xregulus: unix_make
X $(MAKE) unzips CF="$(CF) -traditional -DSYSV -DNO_MKDIR"
X
X# IBM RS/6000 under AIX 3.2
Xrs6000: unix_make
X $(MAKE) unzips CF="$(CF) -DBSD -D_BSD -DUNIX" LF2="-lbsd"
X
X# SCO cross compile from Unix to DOS. Tested with Xenix/386 and OpenDeskTop.
X# Should work with Xenix/286 as well. (davidsen) Note that you *must* remove
X# the Unix objects and executable before doing this! (Piet Plomp: gcc won't
X# recognize the -M0 flag which forces 8086 code.) (GRR: may need to reduce
X# stack to 0c00h if using 286/small-model code...?)
Xsco_dos: unix_make
X $(MAKE) unzips CF="-O -I. $(LOC) -dos -M0" M=msdos\
X LF="-dos -F 2000" LF2="-o unzip.exe"\
X FL="-dos" FL2="-o funzip.exe" SL="-dos" SL2="-o unzipsfx.exe"
X
X# SCO UNIX with shared libraries and no international support. If you are
X# not using a USA-style keyboard and display, you may want to remove -nointl
X# to get support. It adds quite a bit to the size of the executable.
Xsco_sl: unix_make
X $(MAKE) unzips LF="$(LF) -nointl" LF2="$(LF2) -lc_s"\
X SL="$(SL) -nointl" FL="$(FL) -nointl"
X
X# SCO Xenix/286 2.3.3 with 2.2.1 development system
Xsco_x286: unix_make
X $(MAKE) unzips CF="$(CF) -Mel2 -LARGE -DTERMIO" LF="$(LF) -Mel2 -LARGE"
X
X# Sequent Symmetry with Dynix. (386, but needs -DZMEM)
X# This should also work on Balance but I can't test it just yet.
Xsequent: unix_make
X $(MAKE) unzips CF="$(CF) -DBSD -DZMEM"
X
X# Generic System V + GNU C
Xsysv_gcc: unix_make
X $(MAKE) unzips CC=gcc LD=gcc CF="-O2 -I. -DSYSV $(LOC)" LF2=""
X $(STRIP) $(UNZIPS)
X
X# AT&T 6300+, System V.2 Unix: run-time out-of-memory error if don't use -Ml;
X# also compile-time error if work arrays dimensioned at HSIZE+2 (>32K)
Xsysv6300: unix_make
X $(MAKE) unzips CF="$(CF) -Ml -DSYSV" LF="$(LF) -Ml"\
X SL="$(SL) -Ml" FL="$(FL) -Ml"
X
X# Wombat 68000 (or whatever).
X# I didn't do this. I swear. No, really.
Xwombat: unix_make
X @echo
X @echo ' Ha ha! Just kidding.'
X @echo
END_OF_FILE
if test 27036 -ne `wc -c <'unzip-5.12/unix/Makefile'`; then
echo shar: \"'unzip-5.12/unix/Makefile'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/Makefile'
fi
if test -f 'unzip-5.12/vms/makesfx.com' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/makesfx.com'\"
else
echo shar: Extracting \"'unzip-5.12/vms/makesfx.com'\" \(1126 characters\)
sed "s/^X//" >'unzip-5.12/vms/makesfx.com' <<'END_OF_FILE'
X$!
X$! MAKESFX.COM: command-procedure to create self-extracting ZIP archives
X$! usage: @MAKESFX foo (foo.zip -> foo.exe)
X$!
X$! Martin P.J. Zinser 940804
X$!
X$!
X$! For this to work a symbol unzipsfx has to be defined which contains the
X$! location of the unzip stub (e.g., unzipsfx:== device:[dir]unzipsfx.exe)
X$!
X$! The zipfile given in p1 will be concatenated with unzipsfx and given a
X$! filename extension of .exe. The default file extension for p1 is .zip
X$!
X$! Use at your own risk, there is no guarantee here. If it doesn't work,
X$! blame me (m.zi...@gsi.de), not the people from Info-ZIP.
X$!
X$!
X$ inf = "''p1'"
X$ usfx = f$parse("''unzipsfx'") - ";"
X$ file = f$parse("''inf'",,,"DEVICE") + f$parse("''inf'",,,"DIRECTORY") + -
X f$parse("''inf'",,,"NAME")
X$ finf = "''file'" +f$parse("''inf'",".ZIP",,"TYPE") + -
X f$parse("''inf'",,,"VERSION")
X$!
X$! [GRR 940810: what is the point of 'name'? example? commented out...]
X$! $ name = f$extract(12,2,f$time()) + f$extract(15,2,f$time()) + -
X$! f$extract(18,2,f$time()) + f$extract(21,1,f$time())
X$!
X$ copy 'usfx','finf' 'file'.exe
X$ exit
END_OF_FILE
if test 1126 -ne `wc -c <'unzip-5.12/vms/makesfx.com'`; then
echo shar: \"'unzip-5.12/vms/makesfx.com'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/makesfx.com'
fi
echo shar: End of archive 13 \(of 20\).
cp /dev/null ark13isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:27 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 79
Archive-name: unzip/part14

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/INSTALL unzip-5.12/human68k/human68k.c
# unzip-5.12/mac/macstat.c unzip-5.12/unix/zipinfo.1
# Wrapped by kent@sparky on Sat Sep 17 23:33:43 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 14 (of 20)."'
if test -f 'unzip-5.12/INSTALL' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/INSTALL'\"
else
echo shar: Extracting \"'unzip-5.12/INSTALL'\" \(20087 characters\)
sed "s/^X//" >'unzip-5.12/INSTALL' <<'END_OF_FILE'
X__________________________________________________________________________
X
X This is the Info-ZIP file INSTALL (for UnZip), last updated 23 Aug 94.
X__________________________________________________________________________
X
X Yes, this is a rather long file, but don't be intimidated: much of its
X length is due to coverage of multiple operating systems and of optional
X customization features, large portions of which may be skipped. --GRR
X__________________________________________________________________________
X
X
X
XTo compile UnZip, UnZipSFX and/or fUnZip:
X=========================================
X
X(1) Unpack *.c and *.h (the actual source files), preserving the directory
X structure (e.g., ./unix/unix.c). The sole exception is TOPS-20, where
X tops20/* should be unpacked into the current directory, but TOPS-20
X is no longer fully supported in this version.
X
X If you wish to compile with decryption enabled, you must get the zcrypt
X package (see "Where"). Unpack crypt.c and crypt.h from the zcrypt ar-
X chive, overwriting the dummy versions supplied with UnZip. If you don't
X have any sort of unzipper available, you'll have to compile the non-
X crypt version first and use that to unpack the full crypt sources, then
X recompile. (The included zipcloak.c file is for use only with the Zip
X 2.0.x sources, so don't bother unpacking it.)
X
X
X(2) Choose the appropriate makefile based on the description in the Con-
X tents file for your OS (that is, there's only one for Unix or OS/2, but
X MS-DOS and several other OSes have several, depending on the compiler).
X Copy it into the current directory and rename if necessary or desired.
X (Some makefiles can be invoked in place; see (5) below.)
X
X Special point of confusion: some MS-DOS targets are in non-MSDOS
X makefiles. In particular, for DOS emx+gcc use the gccdos target of
X the OS/2 makefile (os2/makefile.os2), and for djgpp use the gcc_dos
X target of the Unix makefile (unix/Makefile). In addition, OS/2 users
X of MSC can cross-compile to MS-DOS with makefile.os2's mscdos target.
X
X
X(3) If you want a non-standard version of UnZip, define one or more of the
X following optional macros, either by adding them to the LOCAL_UNZIP
X environment variable or by editing your makefile as appropriate. The
X syntax differs from compiler to compiler, but macros are often defined
X via "-DMACRO_NAME" or similar (for one called MACRO_NAME). Note that
X some of these may not be fully supported in future releases (or even
X in the current release). Note also that very short command lines in
X MS-DOS (128 characters) may place severe limits on how many of these
X can be used; if need be, the definitions can be placed at the top of
X unzip.h instead (it is included in all source files).
X
X CHECK_EOF (recommended!)
X Corrupt zipfiles and zipfiles stored on damaged media (e.g., bad
X floppies) may cause UnZip to go into an infinite loop and either
X fill the disk(!) or, in some cases (notably under MS-DOS), hang the
X system. (This only applies to testing or extraction of *damaged*
X archives, however.) Defining CHECK_EOF enables special code which
X corrects the problem on most systems; DEC Ultrix may be one excep-
X tion. The only reason this option is not defined by default is that
X it was introduced too late in the testing process.
X
X DOSWILD (MS-DOS only)
X Treat trailing "*.*" like Unix "*" (i.e., matches anything); treat
X trailing "*." as match for files without a dot (i.e., matches any-
X thing, as long as no dots in name). Special treatment only occurs
X if patterns are at end of arguments; i.e., "a*.*" matches all files
X starting with "a", but "*.*c" matches all files ending in "c" *only*
X if they have a dot somewhere before the "c". Thus "*.*.*" could be
X used (albeit awkwardly) to specify all filenames with at least one
X dot in them, and "*." matches all filenames with no dots in them.
X [The default method of specifying these would be "*.*" and "* -x *.*",
X respectively, where the second example makes use of UnZip's exclude-
X files option.] All other regular expressions (including "?" and
X "[range_of_chars]") retain their Unix-like behavior.
X
X VMSWILD (VMS only)
X Use parentheses rather than brackets to delimit sets (ranges), and
X use '%' instead of '?' as the single-character wildcard for internal
X filename matching. (External matching of zipfile names always uses
X the standard VMS wildcard facilities; character sets are disallowed.)
X
X VMSCLI (VMS only)
X Use VMS-style "slash options" (/FOOBAR) instead of the default Unix-
X style hyphenated options (-f). This capability was added quite late
X in the beta cycle and isn't fully tested, so some features may not
X work as expected. Also, it doesn't affect options stored in environ-
X ment variables (UNZIP_OPTS or ZIPINFO_OPTS); those use the Unix style
X regardless.
X
X CHECK_VERSIONS (VMS only)
X UnZip "extra fields" are used to store VMS (RMS) filesystem info,
X and the format of this information may differ in various versions
X of VMS. Defining this option will enable UnZip warnings when the
X stored extra-field VMS version(s) do(es) not match the version of
X VMS currently being used. This is a common occurrence in zipfiles
X received from other sites, but since the format of the filesystem
X does not seem to have changed in years (including on Alpha and Open-
X VMS systems), the warnings are not enabled by default.
X
X RETURN_SEVERITY (VMS only)
X Return a VMS-style value in the range 0x7fff0001 to 0x7fff0332 for
X warnings or errors, or 1 for successful completion. See unzip.doc
X for an explanation of the encoding of the normal UnZip return value.
X This option was added late in the beta cycle and hasn't been tested
X much yet, but it will likely become the default in future versions
X (assuming no collisions with official VMS error codes).
X
X RETURN_CODES (VMS only)
X VMS interprets return codes according to a rigid set of guidelines,
X which means it misinterprets normal UnZip return codes as all sorts
X of really nasty errors. Therefore by default VMS UnZip always returns
X zero regardless of whether any warnings or errors occurred (but see
X RETURN_SEVERITY above). Define RETURN_CODES for a human-readable ex-
X planation of UnZip's return codes. Note that this is often annoying.
X
X ASM_CRC (Amiga/Aztec C only, for now)
X Use an assembler routine to calculate the CRC for each file (speed).
X
X ASM_INFLATECODES (Amiga/Aztec C only, for now)
X Use an assembler version of inflate_codes() for speed.
X
X OLD_EXDIR (not VMS or TOPS-20)
X Use old behavior regarding the directory to which to extract: the
X argument immediately after the zipfile name is the extraction dir;
X if the directory doesn't exist, create it if it was specified as
X "dir/" (i.e., with trailing path separator), else treat it as a
X stored file; if -d is used, treat the argument as a stored file re-
X gardless of trailing '/'. For example:
X unzip foo bar if bar is a dir, extract everything into it;
X otherwise extract bar as stored file
X unzip foo bar/ extract everything into bar, creating if nec.
X unzip -d foo bar/ treat bar/ as a stored directory and extract it
X
X SFX_EXDIR
X Enable the "-d <extract_dir>" option for UnZipSFX. By default it is
X disabled so as to generate the smallest possible executable stub, but
X for use with automated installation scripts and the like it may be
X useful to enable -d. Be sure to read unzipsfx.doc for restrictions
X on the use of this option and of -x; these restrictions should be
X lifted in a later release.
X
X NO_ZIPINFO
X Compile without zipinfo mode (-Z) enabled; makes a smaller executable
X because many text strings are left out. Automatically enabled for
X some small-model compiles under MS-DOS and OS/2, so ordinarily there
X is no need to specify this explicitly. (Note that even with this
X defined, the resulting executable may still be too big to extract
X some zipfiles correctly.)
X
X DEBUG
X Used for debugging purposes; enables Trace() statements. Generally
X it's best to compile only one or two modules this way.
X
X DEBUG_TIME
X Used for debugging the timezone code in file_io.c; enables TTrace()
X statements. This code is only used for the freshen/update options
X (-f and -u), and non-Unix compilers often get it wrong.
X
X
X(4) If you regularly compile new versions of UnZip and always want the same
X non-standard option(s), you may wish to add it (them) to the LOCAL_UNZIP
X environment variable (assuming it's supported in your makefile). Under
X MS-DOS, for example, add this to AUTOEXEC.BAT:
X
X set LOCAL_UNZIP -DDOSWILD -DOLD_EXDIR
X
X You can also use the variable to hold special compiler options (e.g.,
X -FPi87 for Microsoft C, if the x87 libraries are the only ones on your
X disk and they follow Microsoft's default naming conventions; MSC also
X supports the CL environment variable, however).
X
X
X(5) Run the make utility on your chosen makefile:
X
X Unix
X For most systems it's possible to invoke the makefile in place, at
X the possible cost of an ignorable warning; do "make -f unix/Makefile
X list" to get a list of possible system targets, and then "make -f
X unix/Makefile target" for your chosen target. The "generic" target
X works for most systems, but if it fails with a message about ftime()
X unresolved or timezone redefined, do "make clean", "make help", and
X then either "make generic2" or "make generic3" as instructed. If all
X else fails, read the makefile itself; it contains numerous comments.
X
X VMS
X For a one-time build of the default UnZip, simply run the supplied
X command file MAKE.COM. To use either DEC C on an Alpha or VAX C on
X a VAX, type "@make" (after copying make.com into the current direc-
X tory; otherwise do "@[.vms]make" to invoke it in place). To use GNU
X C (gcc) on either platform, do "@make gcc".
X
X For repeated makes or other hacker-like tinkering with the sources,
X or to create a custom version of UnZip (especially with VMSCLI), use
X the included "MMS" makefile, DESCRIP.MMS. Copy it into the current
X directory, read the comments at the top of it and run MadGoat's free
X MMS clone "MMK" on it. DEC's MMS is no longer supported due to the
X use of MMK-specific extensions in DESCRIP.MMS.
X
X MS-DOS
X See the msdos\Contents file for notes regarding which makefile(s) to
X use with which compiler. In summary: pick one of msdos\makefile.*
X as appropriate, or (as noted above) use the OS/2 gccdos target for
X emx+gcc or the Unix gcc_dos target for djgpp. There is also an
X mscdos cross-compilation target in os2\makefile.os2, an sco_dos
X cross-compilation target in unix\Makefile and bcc_dos and msc_dos
X targets in unix\Makefile as well. The latter may disappear soon.
X For Watcom 16-bit or 32-bit versions, see the comments in the OS/2
X section below.
X
X After choosing the appropriate makefile and editing as necessary or
X desired, invoke the corresponding make utility. Microsoft's NMAKE
X and the free dmake and GNU make utilities are generally the most
X versatile. Unfortunately, all current ports of GNU make 3.71 (djgpp,
X emx and gnuish flavors) have bugs which prevent their use with the
X Unix makefile; the older djgpp port of make 3.69 still works and for
X now is distributed with the MS-DOS executables on the primary Info-
X ZIP mirror site (see the Where file). The makefiles in the msdos dir-
X ectory can be invoked in place (e.g., "nmake -f msdos\makefile.msc"),
X but the MS-DOS targets in the Unix makefile (gcc_dos, bcc_dos and
X msc_dos) cannot.
X
X OS/2
X Either GNU make, nmake or dmake may be used with the OS/2 makefile;
X all are freely available on the net. Do "nmake -f os2\makefile.os2",
X for example, to get a list of supported targets. For Watcom C/386 it
X is necessary to edit makefile.os2 and change the os2$(OBJ) target so
X it uses backslashes (i.e., "os2/os2.c" -> "os2\os2.c"). For Watcom
X 16-bit OS/2 versions or any Watcom DOS version (cross-compilation),
X or for Metaware High C++ (OS/2 32-bit), it is necessary to apply the
X patch in os2\wat_met.dif. (This patch arrived too late to be fully
X tested.)
X
X More generally, read the comments at the top of the makefile for an
X explanation of the differences between some of the same-compiler tar-
X gets.
X
X NT (also applies to Chicago/Windows 4)
X You will need the Windows NT SDK or Visual C++ for NT, both from
X Microsoft; or DEC C/C++ for DECpc AXP and NT. Use the command line
X to compile. For the DEC compiler edit out the "cdebug" line in
X nt\makefile as noted in the comments at the top of the makefile.
X From the main source directory do "nmake -F nt\makefile".
X
X If you are using VC++ you will get warnings about CL386 invoking CL,
X etc. Don't worry, this is for compatibility with the SDK. Microsoft
X should have changed the definition of $(cc) in ntwin32.mak for VC++.
X
X If you have VC++ 1.5 (16-bit) installed together with VC++ 1.0 (32-
X bit), make sure that you don't run the 16-bit compiler when you run
X nmake.
X
X At least with MSC 8.x (VC++ 1.x), it is possible to make a dual-mode
X self-extractor (DOS and NT/Chicago). This is not built by default,
X but for those who don't care too much about the size, here's how:
X
X From: Steve Salisbury <ste...@microsoft.com>
X Date: Fri, 22 Jul 94 17:18:06 PDT
X
X Did y'all know that you can build a dual mode (MS-DOS and Win32
X (NT + Chicago)) unzipsfx.exe by just making a 16-bit unzipsfx.exe
X and then specifying that as the 16-bit stub for the 32-bit unzip-
X sfx.exe? You also have to specify the /Knoweas flag to the 16-bit
X linker. I suspect that this won't work with C 6.0 and earlier,
X maybe not even with MS C/C++ 7.0. Anyway, I use C 8.0 (a.k.a.
X Visual C 1.X), which has been shipping for 15+ months now.
X
X Make a little change to MSDOS\MAKEFILE.MSC to add the /KNOWEAS
X flag:
X
X LDFLAGS = /KNOWEAS /nologo/noi/e/st:0x0c00
X
X rename the output file
X
X ren UNZIPSFX.EXE UNZIPSFX.E16
X
X and then make a little change to NT\MAKEFILE to add the -STUB
X directive:
X
X .obj.exe:
X $(link) $(ldebug) $(conflags) $(conflibs) $** \
X -out:$@ -STUB:$*.e16
X
X This is pretty useful. It's nice to have dual-mode self-extracting
X files.
X
X I do notice that they are pretty huge files (41K for 16-bit
X unzipsfx.exe, 69k for the 32-bit version, 110k for the dual). Oh
X well.
X
X AmigaDOS
X SAS/Lattice C and Manx Aztec C are supported. For SAS C 6.x do "lmk
X -f amiga/SMakeFile all"; for Aztec C do "make -f amiga/makefile.azt
X all". The Aztec C version supports assembly-language versions of two
X routines; these are enabled by default.
X
X Atari TOS
X Turbo C is no longer supported; use gcc (tested with 2.4.5 and 2.5.8)
X and the MiNT libraries, and do "make". Note that all versions of gcc
X prior to 2.5.8 have a bug affecting 68000-based machines (optimizer
X adds 68020 instructions). See atari\README for comments on using
X other compilers.
X
X Macintosh
X Think C is the only currently supported compiler, although the Mac
X Programmer's Workbench (MPW) was supported at one time and still has
X hooks in unzip.h. For Think C, un-BinHex the Think C project file
X and UnZip resource file (using BinHex 4.0 or later), then click on
X something or other... :-) (I'm just making this up, since I haven't
X the faintest idea how Mac programming works.)
X
X Human68K
X [This is a Japanese machine and OS.] It appears that GNU make and
X gcc are required; presumably just do "gmake -f human68k/Makefile.gcc"
X to build everything.
X
X TOPS-20
X [No longer fully supported due to new, unported features, although
X patches always accepted.] Unpack all files into the current directory
X only (including those in the zipfile's tops20 directory), then use
X make.mic and "do make".
X
X Running the appropriate make utility should produce three executables on
X most systems, one for UnZip/ZipInfo, one for UnZipSFX, and one for fUnZip.
X (VMS is one prominent exception: fUnZip makes no sense on it.) Read any
X OS-specific README files for notes on setting things up for normal use
X (especially for VMS) and for warnings about known quirks and bugs in var-
X ious compilers (especially for MS-DOS).
X
X Also note that many OSes require a timezone variable to be set correctly
X (often "TZ"); Unix and VMS generally do so by default, but PC-based OSes
X generally do not. See the discussion of the -f and -u options in the
X unzip man page (or unzip.doc).
X
X Then test your new UnZip on a few archives and let us know if there are
X problems (but *please* first make certain that the archives aren't actu-
X ally corrupted and that you didn't make one of the silly mistakes dis-
X cussed in the documentation). If possible, test with PKUNZIP or with a
X previous version of UnZip, if you have one.
X
X
X
XTo install:
X===========
X
XUnix
X The default prefix for the installation location is /usr/local (things
X go into the bin and man/man1 subdirectories beneath the prefix), and
X the default man-page extension is "1" (corresponding to man/man1, above).
X To install as per the defaults, do "make install"; otherwise do "make
X prefix=/your/path manext=your_extension install". For example, to install
X in your home directory with "l" as the man-page extension (for "local"),
X do "make prefix=$HOME manext=l install". Permissions will be 755 for the
X executables and 644 for the man pages. In general root must perform in-
X stallation into a public directory. Do "rehash" if your shell requires
X it in order to find the new executables.
X
XVMS
X Install UnZip as foreign symbol by adding this to login.com:
X
X $ unzip == "$disk:[dir]unzip.exe"
X $ zipinfo == "$disk:[dir]unzip.exe ""-Z"""
X
X where "disk" and "dir" are the location of the UnZip executable; the "$"
X before the disk name is important, as are the double-double-quotes around
X the -Z. Some people, including the author, prefer a short alias such as
X "ii" instead of "zipinfo"; edit to taste. Optionally also install unzipsfx
X for use with the MAKESFX.COM command file. See vms/README (or [.VMS]README.)
X for details on this and for notes/warnings about zipfiles and UnZip under
X VMS.
X
XOS/2, MS-DOS, NT, Atari, Amiga
X Move or copy unzip.exe (or unzip.ttp, or UnZip, or whatever) to a direc-
X tory in your path; also possibly copy the UnZip executable to zipinfo.exe
X (or ii.exe), or else create an alias or a batch or command file for zipinfo
X ("@unzip -Z %1 %2 %3 %4 %5 %6 %7 %8 %9" under MS-DOS). The latter is only
X relevant if NO_ZIPINFO was not defined, obviously...
X
XMacintosh, Human68K, TOPS-20
X Dunno...
END_OF_FILE
if test 20087 -ne `wc -c <'unzip-5.12/INSTALL'`; then
echo shar: \"'unzip-5.12/INSTALL'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/INSTALL'
fi
if test -f 'unzip-5.12/human68k/human68k.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/human68k/human68k.c'\"
else
echo shar: Extracting \"'unzip-5.12/human68k/human68k.c'\" \(20529 characters\)
sed "s/^X//" >'unzip-5.12/human68k/human68k.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X human68k.c
X
X Human68K-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X Contains: do_wild()


X mapattr()
X mapname()
X checkdir()

X close_outfile()
X version()
X TwentyOne()
X normalize_name()


X
X ---------------------------------------------------------------------------*/
X
X

X#include <dirent.h>
X#include <sys/dos.h>
X#include <sys/xunistd.h>
X#include <jstring.h>
X#include "unzip.h"
X
X
Xstatic void normalize_name(char *);


X
Xstatic int created_dir; /* used in mapname(), checkdir() */
Xstatic int renamed_fullpath; /* ditto */
X
X/**********************/
X/* Function do_wild() */

X if (match(file->d_name, wildname, 0)) { /* 0 == don't ignore case */
X if (have_dirname) {
X /* strcpy(matchname, dirname); */
X strcpy(matchname+dirnamelen, file->d_name);
X } else
X strcpy(matchname, file->d_name);
X return matchname;
X }
X
X closedir(dir); /* have read at least one dir entry; nothing left */
X dir = NULL;
X firstcall = TRUE; /* reset for new wildspec */
X if (have_dirname)
X free(dirname);
X return (char *)NULL;
X

X} /* end function do_wild() */


X
X
X
X
X

X/**********************/
X/* Function mapattr() */
X/**********************/
X
Xint mapattr()
X{
X ulg tmp = crec.external_file_attributes;
X

X if (pInfo->hostnum == UNIX_ || pInfo->hostnum == VMS_)
X pInfo->file_attr = _mode2dos(tmp >> 16);
X else
X /* set archive bit (file is not backed up): */
X pInfo->file_attr = (unsigned)(crec.external_file_attributes|32) & 0xff;
X return 0;
X
X} /* end function mapattr() */


X
X
X
X
X

X/**********************/
X/* Function mapname() */
X/**********************/

X if (iskanji(workch)) {
X *pp++ = (char)workch;
X quote = TRUE;
X } else if (quote) { /* if character quoted, */


X *pp++ = (char)workch; /* include it literally */
X quote = FALSE;
X } else
X switch (workch) {
X case '/': /* can assume -j flag not given */
X *pp = '\0';
X if ((error = checkdir(pathcomp, APPEND_DIR)) > 1)
X return error;
X pp = pathcomp; /* reset conversion buffer for next piece */
X lastsemi = NULL; /* leave directory semi-colons alone */
X break;
X
X case ';': /* VMS version (or DEC-20 attrib?) */
X lastsemi = pp; /* keep for now; remove VMS ";##" */
X *pp++ = (char)workch; /* later, if requested */
X break;
X
X case '\026': /* control-V quote for special chars */
X quote = TRUE; /* set flag for next character */
X break;
X

X case ' ': /* change spaces to underscore under */
X *pp++ = '_'; /* MTS; leave as spaces under Unix */
X break;

X
X default:
X /* allow European characters in filenames: */
X if (isprint(workch) || (128 <= workch && workch <= 254))
X *pp++ = (char)workch;
X } /* end switch */
X
X } /* end while loop */
X

X *pp = '\0'; /* done with pathcomp: terminate it */
X

X} /* end function mapname() */


X
X
X
X
X

X char *old_end = end;

X
X Trace((stderr, "appending dir segment [%s]\n", pathcomp));
X while ((*end = *pathcomp++) != '\0')
X ++end;

X normalize_name(old_end);


X
X /* GRR: could do better check, see if overrunning buffer as we go:
X * check end-buildpath after each append, set warning variable if
X * within 20 of FILNAMSIZ; then if var set, do careful check when
X * appending. Clear variable when begin new path. */
X
X if ((end-buildpath) > FILNAMSIZ-3) /* need '/', one-char name, '\0' */
X too_long = TRUE; /* check if extracting directory? */
X if (stat(buildpath, &statbuf)) { /* path doesn't exist */
X if (!create_dirs) { /* told not to create (freshening) */
X free(buildpath);
X return 2; /* path doesn't exist: nothing to do */
X }
X if (too_long) {
X fprintf(stderr, "checkdir error: path too long: %s\n",
X buildpath);
X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }

X if (mkdir(buildpath, 0666) == -1) { /* create the directory */


X fprintf(stderr, "checkdir error: can't create %s\n\
X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path didn't exist, tried to create, failed */
X }
X created_dir = TRUE;
X } else if (!S_ISDIR(statbuf.st_mode)) {
X fprintf(stderr, "checkdir error: %s exists but is not directory\n\
X unable to process %s.\n", buildpath, filename);
X fflush(stderr);
X free(buildpath);
X return 3; /* path existed but wasn't dir */
X }
X if (too_long) {
X fprintf(stderr, "checkdir error: path too long: %s\n", buildpath);
X fflush(stderr);
X free(buildpath);
X return 4; /* no room for filenames: fatal */
X }
X *end++ = '/';
X *end = '\0';
X Trace((stderr, "buildpath now = [%s]\n", buildpath));

X return 0;
X


X } /* end if (FUNCTION == APPEND_DIR) */
X
X/*---------------------------------------------------------------------------
X GETPATH: copy full path to the string pointed at by pathcomp, and free
X buildpath.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == GETPATH) {
X strcpy(pathcomp, buildpath);
X Trace((stderr, "getting and freeing path [%s]\n", pathcomp));
X free(buildpath);
X buildpath = end = NULL;

X return 0;
X }
X

X/*---------------------------------------------------------------------------
X APPEND_NAME: assume the path component is the filename; append it and
X return without checking for existence.
X ---------------------------------------------------------------------------*/
X
X if (FUNCTION == APPEND_NAME) {

X char *old_end = end;

X
X Trace((stderr, "appending filename [%s]\n", pathcomp));
X while ((*end = *pathcomp++) != '\0') {
X ++end;

X normalize_name(old_end);

X return 0;
X }
X

X/*---------------------------------------------------------------------------
X ROOT: if appropriate, store the path in rootpath and create it if neces-
X sary; else assume it's a zipfile member and return. This path segment
X gets used in extracting all members from every zipfile specified on the
X command line.
X ---------------------------------------------------------------------------*/
X
X#if (!defined(SFX) || defined(SFX_EXDIR))
X if (FUNCTION == ROOT) {
X Trace((stderr, "initializing root path to [%s]\n", pathcomp));
X if (pathcomp == NULL) {
X rootlen = 0;

X return 0;
X }

X return 0;
X }
X

X return 99; /* should never reach */
X

X} /* end function checkdir() */


X
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()
X{

X if (cflag) {


X fclose(outfile);
X return;
X }
X

X _dos_filedate(fileno(outfile),
X (ulg)lrec.last_mod_file_date << 16 | lrec.last_mod_file_time);
X fclose(outfile);
X _dos_chmod(filename, pInfo->file_attr);
X
X} /* end function close_outfile() */
X
X
X
X


X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{
X extern char Far CompiledWith[];
X#if 0


X char buf[40];
X#endif
X
X printf(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else
X# if 0
X "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
X# else

X "unknown compiler", "",
X# endif
X#endif
X

X "Human68k", " (X68000)",


X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""
X#endif
X );
X
X} /* end function version() */
X

X#endif /* !SFX */


X
X
X
X
X

X/* Human68K-specific routines */
X
X#define VALID_CHAR "&#()@_^{}!"
X
Xextern ulg TwentyOneOptions(void);
X
Xstatic int multi_period = 0;
Xstatic int special_char = 0;
X
Xvoid
XInitTwentyOne(void)
X{
X ulg stat;
X
X stat = TwentyOneOptions();
X if (stat == 0 || stat == (unsigned long) -1) {
X special_char = 0;
X multi_period = 0;
X return;
X }
X if (stat & (1UL << 29))
X special_char = 1;
X if (stat & (1UL << 28))
X multi_period = 1;
X}
X
Xstatic void
Xnormalize_name(char *name)
X{
X char *dot;
X char *p;
X
X if (strlen(name) > 18) { /* too long */
X char base[18 + 1];
X char ext[4 + 1];
X
X if ((dot = jstrrchr(name, '.')) != NULL)
X *dot = '\0';
X strncpy(base, name, 18);
X base[18] = '\0';
X if (dot) {
X *dot = '.';
X strncpy(ext, dot, 4);
X ext[4] = '\0';
X } else
X *ext = '\0';
X strcpy(name, base);
X strcat(name, ext);
X }
X dot = NULL;
X for (p = name; *p; p++) {
X if (iskanji((unsigned char)*p) && p[1] != '\0')
X p++;
X else if (*p == '.') {
X if (!multi_period) {
X dot = p;
X *p = '_';
X }
X } else if (!special_char && !isalnum (*p)
X && strchr(VALID_CHAR, *p) == NULL)
X *p = '_';
X }
X if (dot != NULL) {
X *dot = '.';
X if (strlen(dot) > 4)
X dot[4] = '\0';
X }
X}
END_OF_FILE
if test 20529 -ne `wc -c <'unzip-5.12/human68k/human68k.c'`; then
echo shar: \"'unzip-5.12/human68k/human68k.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/human68k/human68k.c'
fi
if test -f 'unzip-5.12/mac/macstat.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macstat.c'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macstat.c'\" \(5803 characters\)
sed "s/^X//" >'unzip-5.12/mac/macstat.c' <<'END_OF_FILE'
X#ifdef THINK_C
X#define MACOS
X#include <pascal.h>
X#endif
X#ifdef MPW
X#define MACOS
X#include <Files.h>
X#include <Errors.h>
X#define FSFCBLen (*(short *)0x3F6)
X#endif
X
X#ifdef MACOS
X#include <string.h>
X#include "macstat.h"
Xint macstat(char *path, struct stat *buf, short nVRefNum, long lDirID );
X
X#define unixTime(t) ((t) = ((t) < (time_t)0x7c25b080) ? 0 : (t) - (time_t)0x7c25b080)
X
X/* assume that the path will contain a Mac-type pathname, i.e. ':'s, etc. */
Xint macstat(char *path, struct stat *buf, short nVRefNum, long lDirID )
X{
X char temp[256];
X short nVRefNumT;
X long lDirIDT;
X short fIsHFS = false;
X OSErr err;
X short fUseDefault = ((nVRefNum == 0) && (lDirID == 0));
X
X if (buf == (struct stat *)0L || path == (char *)0L) {
X SysBeep(1);


X return -1;
X }
X

X if (path[0] == '\0' || strlen(path)>255) {


X return -1;
X }
X

X if ( fUseDefault )
X {
X if (GetVol((StringPtr)&temp[0], &nVRefNumT) != noErr) {
X SysBeep(1);


X return -1;
X }
X }
X

X /* get info about the specified volume */

X if (FSFCBLen > 0) /* HFS Disk? */
X {
X HParamBlockRec hpbr;
X
X if ( fUseDefault )
X {
X WDPBRec wdpb;
X
X wdpb.ioCompletion = 0;
X wdpb.ioNamePtr = (StringPtr)temp;
X err = PBHGetVol(&wdpb, 0);
X nVRefNumT = wdpb.ioWDVRefNum;
X lDirIDT = wdpb.ioWDDirID;
X }
X else
X {
X nVRefNumT = nVRefNum;
X lDirIDT = lDirID;


X err = noErr;
X }
X if (err == noErr)

X {
X hpbr.volumeParam.ioCompletion = 0;
X hpbr.volumeParam.ioNamePtr = (StringPtr)temp;
X hpbr.volumeParam.ioVRefNum = nVRefNumT;
X hpbr.volumeParam.ioVolIndex = 0;
X err = PBHGetVInfo(&hpbr, 0);
X
X if (err == noErr && hpbr.volumeParam.ioVFSID == 0


X && hpbr.volumeParam.ioVSigWord == 0x4244) {

X fIsHFS = true;


X }
X }
X }
X
X

X /* number of links, at least in System 6.0x, 0 */
X buf->st_nlink = 0;
X /* user id */
X buf->st_uid = 0;
X /* group id */
X buf->st_gid = 0;
X
X if (fIsHFS == true) /* HFS? */
X {
X CInfoPBRec cPB;
X HParamBlockRec hPB;
X
X /* get information about file */
X cPB.hFileInfo.ioCompletion = (ProcPtr)0L;
X c2pstr(path);
X strncpy(temp,path, path[0]+1);
X p2cstr(path);
X cPB.hFileInfo.ioNamePtr = (StringPtr)temp;
X cPB.hFileInfo.ioVRefNum = nVRefNumT;
X cPB.hFileInfo.ioDirID = lDirIDT;
X cPB.hFileInfo.ioFDirIndex = 0;
X
X err = PBGetCatInfo(&cPB, false);
X
X if (err != noErr) {
X if ((err != fnfErr) && (err != dirNFErr)) {
X SysBeep(1);
X }


X return -1;
X }
X

X /* Type of file: directory or regular file + access */
X buf->st_mode = (cPB.hFileInfo.ioFlAttrib & ioDirMask) ? S_IFDIR : S_IFREG |
X (cPB.hFileInfo.ioFlAttrib & 0x01) ? S_IREAD : (S_IREAD | S_IWRITE);
X
X /* last access time, modification time and creation time(?) */
X buf->st_atime = buf->st_mtime = cPB.hFileInfo.ioFlMdDat;
X buf->st_ctime = cPB.hFileInfo.ioFlCrDat;
X /* dev number */
X buf->st_dev = (long)cPB.hFileInfo.ioVRefNum;
X /* inode number */
X buf->st_ino = cPB.hFileInfo.ioDirID;
X /* size of file - use only the data fork */
X buf->st_size = cPB.hFileInfo.ioFlLgLen;
X
X /* size of disk block */
X hPB.volumeParam.ioCompletion = (ProcPtr)0L;
X hPB.volumeParam.ioNamePtr = (StringPtr)temp;
X hPB.volumeParam.ioVRefNum = nVRefNumT;
X hPB.volumeParam.ioVolIndex = 0;
X
X err = PBHGetVInfo(&hPB, false);
X
X if (err != noErr) {
X SysBeep(1);


X return -1;
X }
X

X buf->st_blksize = cPB.hFileInfo.ioFlPyLen / hPB.volumeParam.ioVAlBlkSiz;
X }
X else /* MFS? */
X {
X ParamBlockRec pPB;
X ParamBlockRec hPB;
X
X c2pstr(path);
X strncpy(temp, path, path[0]+1);
X p2cstr(path);
X pPB.fileParam.ioCompletion = (ProcPtr)0;
X pPB.fileParam.ioNamePtr = (StringPtr)temp;
X pPB.fileParam.ioVRefNum = nVRefNumT;
X pPB.fileParam.ioFVersNum = 0;
X pPB.fileParam.ioFDirIndex = 0;
X
X err = PBGetFInfo(&pPB, false);
X
X if (err != noErr) {
X SysBeep(1);


X return -1;
X }
X

X /* Type of file: either directory or regular file + access */
X buf->st_mode = (pPB.fileParam.ioFlAttrib & ioDirMask) ? S_IFDIR : S_IFREG;
X (pPB.fileParam.ioFlAttrib & 0x01) ? S_IREAD : (S_IREAD | S_IWRITE);
X
X /* last access time, modification time and creation time(?) */
X buf->st_atime = buf->st_mtime = pPB.fileParam.ioFlMdDat;
X buf->st_ctime = pPB.fileParam.ioFlCrDat;
X /* dev number */
X buf->st_dev = (long)pPB.fileParam.ioVRefNum;
X /* inode number */
X buf->st_ino = pPB.fileParam.ioFlNum;
X /* size of file - use only the data fork */
X buf->st_size = pPB.fileParam.ioFlLgLen;
X
X /* size of disk block */
X hPB.volumeParam.ioCompletion = (ProcPtr)0;
X hPB.volumeParam.ioNamePtr = (StringPtr)temp;
X hPB.volumeParam.ioVRefNum = nVRefNumT;
X hPB.volumeParam.ioVolIndex = 0;
X
X err = PBGetVInfo(&hPB, false);
X
X if (err != noErr) {
X SysBeep(1);


X return -1;
X }
X

X buf->st_blksize = pPB.fileParam.ioFlPyLen / hPB.volumeParam.ioVAlBlkSiz;
X }
X
X /* Convert from Macintosh time format to Unix time format. */
X
X unixTime(buf->st_atime);
X unixTime(buf->st_mtime);
X unixTime(buf->st_ctime);


X
X return 0;
X}

X#else
X#error 1
X#endif
END_OF_FILE
if test 5803 -ne `wc -c <'unzip-5.12/mac/macstat.c'`; then
echo shar: \"'unzip-5.12/mac/macstat.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macstat.c'
fi
if test -f 'unzip-5.12/unix/zipinfo.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/zipinfo.1'\"
else
echo shar: Extracting \"'unzip-5.12/unix/zipinfo.1'\" \(20438 characters\)
sed "s/^X//" >'unzip-5.12/unix/zipinfo.1' <<'END_OF_FILE'


X.\" Info-ZIP grants permission to any individual or institution to use, copy,
X.\" or redistribute this software, so long as: (1) all of the original files
X.\" are included; (2) it is not sold for profit; and (3) this notice is re-
X.\" tained.
X.\"

X.\" zipinfo.1 by Greg Roelofs and others.
X.\"
X.\" =========================================================================
X.\" define .X macro (for long-line ZipInfo output examples; small Courier):
X.de X
X.ft CW
X.nf
X.ie n .ti -5
X.el \{ .ti +2m
X.ps -1 \}
X\&\\$1
X.ie n .ti +5
X.el \{ .ti -2m
X.ps +1 \}
X.ft
X.fi
X..


X.\" define .Y macro (for user-command examples; normal Courier font):
X.de Y
X.ft CW
X.in +4n
X.nf
X\&\\$1
X.ft
X.in
X.fi
X..
X.\" =========================================================================

X.TH ZIPINFO 1L "28 Aug 94 (v2.02)"
X.SH NAME
Xzipinfo \- list detailed information about a ZIP archive


X.PD
X.\" =========================================================================
X.SH SYNOPSIS

X\fBzipinfo\fP [\fB\-12smlvhtTz\fP] \fIfile\fP[\fI.zip\fP]
X[\fIfile(s)\fP\ .\|.\|.] [\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.]
X.LP
X\fBunzip\fP \fB\-Z\fP [\fB\-12smlvhtTz\fP] \fIfile\fP[\fI.zip\fP]
X[\fIfile(s)\fP\ .\|.\|.] [\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.]


X.PD
X.\" =========================================================================
X.SH DESCRIPTION

X\fIzipinfo\fP lists technical information about files in a ZIP archive, most
Xcommonly found on MS-DOS systems. Such information includes file access
Xpermissions, encryption status, type of compression, version and operating
Xsystem or file system of compressing program, and the like. The default


Xbehavior (with no options) is

Xto list single-line entries for each file in the archive, with header and
Xtrailer lines providing summary information for the entire archive. The
Xformat is a cross between Unix ``\fCls \-l\fR'' and ``\fCunzip \-v\fR''
Xoutput. See
X.B DETAILED DESCRIPTION
Xbelow. Note that \fIzipinfo\fP is the same program as \fIunzip\fP (under
XUnix, a link to it); on some systems, however, \fIzipinfo\fP support may
Xhave been omitted when \fIunzip\fP was compiled.

Xself-extracting ZIP files are supported; just specify the \fC.exe\fP suffix
X(if any) explicitly.
X.IP [\fIfile(s)\fP]
XAn optional list of archive members to be processed.


XRegular expressions (wildcards) may be used to match multiple members; see
Xabove. Again, be sure to quote expressions that would otherwise be expanded
Xor modified by the operating system.
X.IP [\fB\-x\fP\ \fIxfile(s)\fP]
XAn optional list of archive members to be excluded from processing.

X.\" =========================================================================
X.SH OPTIONS
X.TP
X.B \-1
Xlist filenames only, one per line. This option excludes all others; headers,
Xtrailers and zipfile comments are never printed. It is intended for use in
XUnix shell scripts.
X.TP
X.B \-2
Xlist filenames only, one per line, but allow headers (\fB\-h\fP), trailers
X(\fB\-t\fP) and zipfile comments (\fB\-z\fP), as well. This option may be
Xuseful in cases where the stored filenames are particularly long.
X.TP
X.B \-s
Xlist zipfile info in short Unix ``\fCls \-l\fR'' format. This is the default
Xbehavior; see below.
X.TP
X.B \-m
Xlist zipfile info in medium Unix ``\fCls \-l\fR'' format. Identical to the
X\fB\-s\fP output, except that the compression factor, expressed as a
Xpercentage, is also listed.
X.TP
X.B \-l
Xlist zipfile info in long Unix ``\fCls \-l\fR'' format. As with \fB\-m\fP
Xexcept that the compressed size (in bytes) is printed instead of the
Xcompression ratio.
X.TP
X.B \-v
Xlist zipfile information in verbose, multi-page format.
X.TP
X.B \-h
Xlist header line. The archive name, actual size (in bytes) and total number
Xof files is printed.
X.TP
X.B \-t
Xlist totals for files listed or for all files. The number of files listed,
Xtheir uncompressed and compressed total sizes, and their overall compression
Xfactor is printed; or, if only the totals line is being printed, the values
Xfor the entire archive are given. Note that the total compressed (data)
Xsize will never match the actual zipfile size, since the latter includes all
Xof the internal zipfile headers in addition to the compressed data.
X.TP
X.B \-T
Xprint the file dates and times in a sortable decimal format (yymmdd.hhmmss).
XThe default date format is a more standard, human-readable version with
Xabbreviated month names (see examples below).
X.TP
X.B \-z
Xinclude the archive comment (if any) in the listing.
X.PD
X.\" =========================================================================
X.SH DETAILED DESCRIPTION
X.I zipinfo
Xhas a number of modes, and its behavior can be rather difficult to fathom
Xif one isn't familiar with Unix \fIls\fP(1) (or even if one is). The default
Xbehavior is to list files in the following format:
X.LP
X.X "-rw-rws--- 1.9 unx 2802 t- defX 11-Aug-91 13:48 perms.2660"
X.LP
XThe last three fields are the modification date and time of
Xthe file, and its name. The case of the filename is respected; thus
Xfiles which come from MS-DOS PKZIP are always capitalized. If the file
Xwas zipped with a stored directory name, that is also displayed as part
Xof the filename.
X.LP
XThe second and third fields indicate that the file was zipped under
XUnix with version 1.9 of \fIzip\fP. Since it comes from Unix, the file
Xpermissions at the beginning of the line are printed in Unix format.
XThe uncompressed file-size (2802 in this example) is the fourth field.
X.LP
XThe fifth field consists of two characters, either of which may take
Xon several values. The first character may be either `t' or `b', indicating
Xthat \fIzip\fP believes the file to be text or binary, respectively;
Xbut if the file is encrypted, \fIzipinfo\fP
Xnotes this fact by capitalizing the character (`T' or `B'). The second
Xcharacter may also take on four values, depending on whether there is
Xan extended local header and/or an ``extra field'' associated with the
Xfile (fully explained in PKWare's APPNOTE.TXT, but basically analogous to
Xpragmas in ANSI C--i.e., they provide a standard way to include non-standard
Xinformation in the archive). If neither exists, the character
Xwill be a hyphen (`\-'); if there is an extended local header but no extra
Xfield, `l'; if the reverse, `x'; and if both exist, `X'. Thus the
Xfile in this example is (probably) a text file, is not encrypted, and
Xhas neither an extra field nor an extended local header associated with it.
XThe example below, on the other hand, is an encrypted binary file with an
Xextra field:
X.LP
X.X "RWD,R,R 0.9 vms 168 Bx shrk 9-Aug-91 19:15 perms.0644"
X.LP
XExtra fields are used for various purposes (see discussion of the \fB\-v\fP
Xoption below) including the storage of VMS file attributes, which is
Xpresumably the case here. Note that the file attributes are listed in
XVMS format. Some other possibilities for the host operating system (which
Xis actually a misnomer--host file system is more correct) include
XOS/2 or NT with High Performance File System (HPFS), MS-DOS, OS/2 or NT
Xwith File Allocation Table (FAT) file system, and Macintosh. These are
Xdenoted as follows:
X.LP
X.X "-rw-a-- 1.0 hpf 5358 Tl i4:3 4-Dec-91 11:33 longfilename.hpfs"
X.X "-r--ahs 1.1 fat 4096 b- i4:2 14-Jul-91 12:58 EA DATA. SF"
X.X "--w------- 1.0 mac 17357 bx i8:2 4-May-92 04:02 unzip.macr"
X.LP
XFile attributes in the first two cases are indicated in a Unix-like format,
Xwhere the seven subfields indicate whether the file: (1) is a directory,
X(2) is readable (always true), (3) is writable, (4) is executable (guessed
Xon the basis of the extension--\fI.exe\fP, \fI.com\fP, \fI.bat\fP, \fI.cmd\fP
Xand \fI.btm\fP files are assumed to be so), (5) has its archive bit set,
X(6) is hidden, and (7) is a system file. Interpretation of Macintosh file
Xattributes is unreliable because some Macintosh archivers don't store any
Xattributes in the archive.
X.LP
XFinally, the sixth field indicates
Xthe compression method and possible sub-method used. There are six methods
Xknown at present: storing (no compression), reducing, shrinking, imploding,
Xtokenizing (never publicly released), and deflating. In addition, there are
Xfour levels of reducing (1 through 4); four types of imploding (4K or 8K
Xsliding dictionary, and 2 or 3 Shannon-Fano trees); and four levels of
Xdeflating (superfast, fast, normal, maximum compression). \fIzipinfo\fP
Xrepresents these methods and their sub-methods as follows: \fIstor\fP;
X\fIre:1\fP, \fIre:2\fP, etc.; \fIshrk\fP; \fIi4:2\fP, \fIi8:3\fP, etc.;
X\fItokn\fP; and \fIdefS\fP, \fIdefF\fP, \fIdefN\fP, and \fIdefX\fP.
X.LP
XThe medium and long listings are almost identical to the short format except
Xthat they add information on the file's compression. The medium format lists
Xthe file's compression factor as a percentage indicating the amount of space
Xwhich has been ``removed'':
X.LP
X.X "-rw-rws--- 1.5 unx 2802 t- 81% defX 11-Aug-91 13:48 perms.2660"
X.LP
XIn this example, the file has been compressed by more than a factor of
Xfive; the compressed data are only 19% of the original size. The long
Xformat gives the compressed file's size in bytes, instead:
X.LP
X.X "-rw-rws--- 1.5 unx 2802 t- 538 defX 11-Aug-91 13:48 perms.2660"
X.LP
XAdding the \fB\-T\fP option changes the file date and time to decimal
Xformat:
X.LP
X.X "-rw-rws--- 1.5 unx 2802 t- 538 defX 910811.134804 perms.2660"
X.LP
XNote that because of limitations in the MS-DOS format used to store file
Xtimes, the seconds field is always rounded to the nearest even second.
XFor Unix files this is expected to change in the next major releases of
X\fIzip\fP(1L) and \fIunzip\fP.
X.LP
XIn addition to individual file information, a default zipfile listing
Xalso includes header and trailer lines:
X.LP
X.X "Archive: OS2.zip 5453 bytes 5 files"
X.X ",,rw, 1.0 hpf 730 b- i4:3 26-Jun-92 23:40 Contents"
X.X ",,rw, 1.0 hpf 3710 b- i4:3 26-Jun-92 23:33 makefile.os2"
X.X ",,rw, 1.0 hpf 8753 b- i8:3 26-Jun-92 15:29 os2unzip.c"
X.X ",,rw, 1.0 hpf 98 b- stor 21-Aug-91 15:34 unzip.def"
X.X ",,rw, 1.0 hpf 95 b- stor 21-Aug-91 17:51 zipinfo.def"
X.X "5 files, 13386 bytes uncompressed, 4951 bytes compressed: 63.0%"
X.LP
XThe header line gives the name of the archive, its total size, and the
Xtotal number of files; the trailer gives the number of files listed,
Xtheir total uncompressed size, and their total compressed size (not
Xincluding any of \fIzip\fP's internal overhead). If, however, one or
Xmore \fIfile(s)\fP are provided, the header and trailer lines are
Xnot listed. This behavior is also similar to that of Unix's ``\fCls \-l\fR'';
Xit may be overridden by specifying the \fB\-h\fP and \fB\-t\fP options
Xexplicitly.
XIn such a case the listing format must also be specified explicitly,
Xsince \fB\-h\fP or \fB\-t\fP (or both) in the absence of other options implies
Xthat ONLY the header or trailer line (or both) is listed. See the
X\fBEXAMPLES\fP section below for a semi-intelligible translation of this
Xnonsense.
X.LP
XThe verbose listing is mostly self-explanatory. It also lists file
Xcomments and the zipfile comment, if any, and the type and number of bytes
Xin any stored extra fields. Currently known types of extra fields include
XPKWARE's authentication (``AV'') info; OS/2 extended attributes; VMS
Xfilesystem info, both PKWARE and Info-ZIP versions; Macintosh resource
Xforks; Acorn/Archimedes SparkFS info; and so on. (Note
Xthat in the case of OS/2 extended attributes--perhaps the most common
Xuse of zipfile extra fields--the size of the stored EAs as reported by
X\fIzipinfo\fP may not match the number given by OS/2's \fIdir\fP command:
XOS/2 always reports the number of bytes required in 16-bit format, whereas
X\fIzipinfo\fP always reports the 32-bit storage.)


X.PD
X.\" =========================================================================
X.SH ENVIRONMENT OPTIONS

XModifying \fIzipinfo\fP's default behavior via options placed in
Xan environment variable can be a bit complicated to explain, due to
X\fIzipinfo\fP's attempts to handle various defaults in an intuitive,
Xyet Unix-like, manner. (Try not to laugh.) Nevertheless, there is some
Xunderlying logic. In brief,
Xthere are three ``priority levels'' of options: the default options;
Xenvironment options, which can override or add to the defaults; and
Xexplicit options given by the user, which can override or add to
Xeither of the above.
X.LP
XThe default listing format, as noted above, corresponds roughly
Xto the "\fCzipinfo \-hst\fP" command (except when individual zipfile members
Xare specified).
XA user who prefers the long-listing format (\fB\-l\fP) can make use of the
X\fIzipinfo\fP's environment variable to change this default:


X.LP
X.DT
X.ft CW
X.in +4n

X.ta \w'ZIPINFO=\-l; export ZIPINFO'u+4n
X.in
X.ft
X.PD 0
X.Y "ZIPINFO=\-l; export ZIPINFO\t\fRUnix Bourne shell"
X.Y "setenv ZIPINFO \-l\t\fRUnix C shell"
X.Y "set ZIPINFO=\-l\t\fROS/2 or MS-DOS"
X.Y "define ZIPINFO_OPTS ""\-l""\t\fRVMS (quotes for \fIlowercase\fP)"
X.PD
X.LP
XIf, in addition, the user dislikes the trailer line, \fIzipinfo\fP's
Xconcept of ``negative options'' may be used to override the default
Xinclusion of the line. This is accomplished by preceding the undesired
Xoption with one or more minuses: e.g., ``\fC\-l\-t\fR'' or ``\fC\-\-tl\fR'',
Xin this example. The first hyphen is the regular switch character, but the
Xone before the `t' is a minus sign. The dual use of hyphens may seem a
Xlittle awkward, but it's reasonably intuitive nonetheless: simply ignore
Xthe first hyphen and go from there. It is also consistent with the behavior
Xof the Unix command \fInice\fP(1).
X.LP
XAs suggested above, the default variable names are ZIPINFO_OPTS for VMS
X(where the symbol used to install \fIzipinfo\fP as a foreign command
Xwould otherwise be confused with the environment variable), and ZIPINFO


Xfor all other operating systems. For compatibility with \fIzip\fP(1L),

XZIPINFOOPT is also accepted (don't ask). If both ZIPINFO and ZIPINFOOPT
Xare defined, however, ZIPINFO takes precedence. \fIunzip\fP's diagnostic


Xoption (\fB\-v\fP with no zipfile name) can be used to check the values
Xof all four possible \fIunzip\fP and \fIzipinfo\fP environment variables.

X.PD
X.\" =========================================================================
X.SH EXAMPLES

XTo get a basic, short-format listing of the complete contents of a ZIP
Xarchive \fIstorage.zip\fP, with both header and totals lines, use only
Xthe archive name as an argument to zipinfo:
X.LP
X.Y "zipinfo storage"
X.LP
XTo produce a basic, long-format listing (not verbose), including header and
Xtotals lines, use \fB\-l\fP:
X.LP
X.Y "zipinfo \-l storage"
X.LP
XTo list the complete contents of the archive without header and totals
Xlines, either negate the \fB\-h\fP and \fB\-t\fP options or else specify the
Xcontents explicitly:
X.LP
X.PD 0
X.Y "zipinfo \-\-h\-t storage"
X.Y "zipinfo storage \e*"
X.PD
X.LP
X(where the backslash is required only if the shell would otherwise expand
Xthe `*' wildcard, as in Unix when globbing is turned on--double quotes around
Xthe asterisk would have worked as well). To turn off the totals line by
Xdefault, use the environment variable (C shell is assumed here):
X.LP
X.PD 0
X.Y "setenv ZIPINFO \-\-t"
X.Y "zipinfo storage"
X.PD
X.LP
XTo get the full, short-format listing of the first example again, given
Xthat the environment variable is set as in the previous example, it is
Xnecessary to specify the \fB\-s\fP option explicitly, since the \fB\-t\fP
Xoption by itself implies that ONLY the footer line is to be printed:
X.LP
X.PD 0
X.Y "setenv ZIPINFO \-\-t"
X.Y "zipinfo \-t storage\t\fR[only totals line]"
X.Y "zipinfo \-st storage\t\fR[full listing]"
X.PD
X.LP
XThe \fB\-s\fP option, like \fB\-m\fP and \fB\-l\fP, includes headers and
Xfooters by default, unless otherwise specified. Since the environment
Xvariable specified no footers and that has a higher precedence than the
Xdefault behavior of \fB\-s\fP, an explicit \fB\-t\fP option was necessary
Xto produce the full listing. Nothing was indicated about the header,
Xhowever, so the \fB\-s\fP option was sufficient. Note that both the
X\fB\-h\fP and \fB\-t\fP options, when used by themselves or with
Xeach other, override any default listing of member files; only the header
Xand/or footer are printed. This behavior is useful when \fIzipinfo\fP is
Xused with a wildcard zipfile specification; the contents of all zipfiles
Xare then summarized with a single command.
X.LP
XTo list information on a single file within the archive, in medium format,
Xspecify the filename explicitly:
X.LP
X.Y "zipinfo \-m storage unshrink.c"
X.LP
XThe specification of any member file, as in this example, will override
Xthe default header and totals lines; only the single line of information
Xabout the requested file will be printed. This is intuitively what one
Xwould expect when requesting information about a single file. For multiple
Xfiles, it is often useful to know the total compressed and uncompressed
Xsize; in such cases \fB\-t\fP may be specified explicitly:
X.LP
X.Y "zipinfo \-mt storage ""*.[ch]"" Mak\e*"
X.LP
XTo get maximal information about the ZIP archive, use the verbose
Xoption. It is usually wise to pipe the output into a filter such as
XUnix \fImore\fP(1) if the operating system allows it:
X.LP
X.Y "zipinfo \-v storage | more"
X.LP
XFinally, to see the most recently modified files in the archive, use
Xthe \fB\-T\fP option in conjunction with an external sorting utility
Xsuch as Unix \fIsort\fP(1) (and \fItail\fP(1) as well, in this example):
X.LP
X.Y "zipinfo \-T storage | sort -n +6 | tail -15"
X.LP
XThe \fB\-n\fP option to \fIsort\fP(1) tells it to sort numerically
Xrather than in ASCII order, and the \fB\+6\fP option tells it to sort
Xon the sixth field after the first one (i.e., the seventh field). This
Xassumes the default short-listing format; if \fB\-m\fP or \fB\-l\fP is
Xused, the proper \fIsort\fP(1) option would be \fB\+7\fP. The \fItail\fP(1)
Xcommand filters out all but the last 15 lines of the listing. Future
Xreleases of \fIzipinfo\fP may incorporate date/time and filename sorting
Xas built-in options.


X.PD
X.\" =========================================================================
X.SH TIPS

XThe author finds it convenient to define an alias \fIii\fP for \fIzipinfo\fP
Xon systems which allow aliases (or, on other systems, copy/rename the
Xexecutable, create a link or create a command file with the name \fIii\fP).
XThe \fIii\fP usage parallels the common \fIll\fP alias for long listings in
XUnix, and the similarity between the outputs of the two commands was
Xintentional.


X.PD
X.\" =========================================================================
X.SH BUGS

XNone known at this time, but we're always delighted to find a good one.
X.LP


X.\" =========================================================================
X.SH SEE ALSO

X\fIls\fP(1), \fIfunzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L),
X\fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)


X.PD
X.\" =========================================================================
X.SH AUTHOR

XGreg Roelofs (a.k.a.\ Cave Newt). ZipInfo contains pattern-matching code
Xby Mark Adler and fixes/improvements by many others. Please refer to the
XCONTRIBS file in the UnZip source distribution for a more complete list.
END_OF_FILE
if test 20438 -ne `wc -c <'unzip-5.12/unix/zipinfo.1'`; then
echo shar: \"'unzip-5.12/unix/zipinfo.1'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/zipinfo.1'
fi
echo shar: End of archive 14 \(of 20\).
cp /dev/null ark14isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:35 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 80
Archive-name: unzip/part15

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/ZipPorts unzip-5.12/human68k/options.s.UU
# unzip-5.12/os2/wat_met.dif unzip-5.12/unix/unzipsfx.1
# unzip-5.12/unshrink.c
# Wrapped by kent@sparky on Sat Sep 17 23:33:45 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 15 (of 20)."'
if test -f 'unzip-5.12/ZipPorts' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/ZipPorts'\"
else
echo shar: Extracting \"'unzip-5.12/ZipPorts'\" \(13591 characters\)
sed "s/^X//" >'unzip-5.12/ZipPorts' <<'END_OF_FILE'
X__________________________________________________________________________
X
X This is the Info-ZIP file ZipPorts, last updated on 15 August 1994.
X__________________________________________________________________________
X
X
XThis document defines a set of rules and guidelines for those who wish to
Xcontribute patches to Zip and UnZip (or even entire ports to new operating
Xsystems). The list below is something between a style sheet and a "Miss
XManners" etiquette guide. While Info-ZIP encourages contributions and
Xfixes from anyone who finds something worth changing, we are also aware
Xof the fact that no two programmers have the programming style and that
Xunrestrained changes by a few dozen contributors would result in hideously
Xugly (and unmaintainable) Frankenstein code. So consider the following an
Xattempt by the maintainers to maintain sanity as well as useful code.
X
X(The first version of this document was called either "ZipRules" or the
X"No Feelthy ..." file and was compiled by David Kirschbaum in consulta-
Xtion with Mark Adler, Cave McNewt and others. The current incarnation
Xexpands upon the original with insights gained from a few more years of
Xhappy hacking...)
X
X
XSummary:
X
X (0) The Platinum Rule: DON'T BREAK EXISTING PORTS
X(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE
X(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE
X(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS
X
X (1) NO FEELTHY TABS
X (2) NO FEELTHY CARRIAGE RETURNS
X (3) NO FEELTHY 8-BIT CHARS
X (4) NO FEELTHY LEFT-JUSTIFIED DASHES
X (5) NO FEELTHY FANCY_FILENAMES
X (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS
X (7) NO FEELTHY E-MAIL BINARIES
X
X
XExplanations:
X
X (0) The Platinum Rule: DON'T BREAK EXISTING PORTS
X
X No doubt about it, this is the one which really pisses us off and
X pretty much guarantees that your port or patch will be ignored and/
X or laughed at. Examples range from the *really* severe cases which
X "port" by ripping out all of the existing multi-OS code, to more
X subtle oopers like relying on a local capability which doesn't exist
X on other OSes or in older compilers (e.g., the use of ANSI "#elif"
X constructs, C++ comments, GNU extensions, etc.). As to the former,
X use #ifdefs for your new code (see rule 0.3). And as to the latter,
X trust us--there are few things we'd like better than to be able to
X use some of the elegant "new" features out there (many of which have
X been around for a decade or more). But our code still compiles on
X machines dating back even longer, at least in spirit--e.g., the AT&T
X 3B1 family and Dynix/ptx. Until we say otherwise, dinosaurs are
X supported.
X
X
X(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE
X
X In other words, try to fit into the local style of programming--no
X matter how painful it may be. This includes cosmetic aspects like
X indenting the same amount (both in the main C code and in the in-
X clude files), using braces and comments similarly, NO TABS (see rule
X #1), etc.; but also more substantive things like (for UnZip) putting
X character strings into static (far) variables and using the LoadFar-
X String macros to avoid overflowing limited MS-DOS data segments, and
X using the PRINTF/FPRINTF/PUTC macros instead of the corresponding
X functions so that dynamic-link-library ports are simpler.
X
X Note that not only do Zip and UnZip differ in these respects, so do
X individual parts of each program. While it would be nice to have
X global consistency, cosmetic changes are not a high priority; for
X now we'll settle for local consistency--i.e., don't make things any
X worse than they already are.
X
X Exception (BIG exception): single-letter variable names. Despite
X the prevailing practice in much of Zip and parts of UnZip, and de-
X spite the fact that one-letter variables allow you to pack really
X cool, compact and complicated expressions onto one line, they also
X make the code very difficult to maintain and are therefore *strongly*
X discouraged. Don't ask us who is responsible in the first place;
X while this sort of brain damage is not uncommon among former BASIC
X programmers, it is nevertheless a lifelong embarrassment, and we do
X try to pity the poor sod (that is, when we're not chasing bugs and
X cursing him). :-)
X
X
X(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE
X
X Few things are as annoying as receiving a large patch which obviously
X represents a lot of time and careful work but which is relative to
X an old version of Info-ZIP code. As wonderful as Larry Wall's patch
X program is at applying context diffs to modified code, we regularly
X make near-global changes and/or reorganize big chunks of the sources
X (particularly in UnZip), and "patch" can't work miracles--big changes
X invariably break any patch which is relative to an old version of the
X code.
X
X Bottom line: contact the Info-ZIP core team FIRST (via the zip-bugs
X e-mail address) and get up to date with the latest code before begin-
X ning a big new port.
X
X
X(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS
X
X UnZip is currently ported to something like 10 operating systems
X (a few more or less depending on how one counts), and each of these
X has a unique macro identifying it: AMIGA, ATARI_ST, __human68k__,
X MACOS, MSDOS, OS2, NT (or WIN32), TOPS20, UNIX, VMS. Zip is moving
X in the same direction. New ports should NOT piggyback one of the
X existing ports unless they are substantially similar--for example,
X Minix and Coherent are basically Unix and therefore are included in
X the UNIX macro, but DOS djgpp ports and OS/2 emx ports (both of which
X use the Unix-originated GNU C compiler and often have "unix" defined
X by default) are obviously *not* Unix. [The existing MTS port is a
X special exception; basically only one person knows what MTS really
X is, and he's not telling. Presumably it's not very close to Unix,
X but it's not worth arguing about it now.] Along the same lines,
X neither OS/2 nor Human68K is the same as (or even close to) MS-DOS.
X
X Bottom line: when adding a new port (e.g., MVS), create a new macro
X for it ("MVS"), a new subdirectory ("mvs") and a new source file for
X OS-specific code ("mvs/mvs.c"). Use #ifdefs to fit any OS-specific
X changes into the existing code (e.g., unzip.h). If it's close enough
X to an existing port that piggybacking is a temptation, define a new
X "combination macro" (e.g., "MVS_UNIX") and replace the old macros as
X required. (This last applies to UnZip, at least; Jean-loup prefers
X fewer macros and long #ifdef lines, so talk to him about Zip.) See
X also rule 0.1.
X
X (Note that, for UnZip, new ports need not attempt to deal with all
X features. Among other things, the wildcard-zipfile code in do_wild()
X may be replaced with a supplied dummy version, since opendir/readdir/
X closedir() or the equivalent can be difficult to implement.)
X
X
X (1) NO FEELTHY TABS
X
X Some editors and e-mail systems either have no capability to use
X and/or display tab characters (ASCII 9) correctly, or they use non-
X standard or variable-width tab columns, or other horrors. Some edi-
X tors auto-convert spaces to tabs, after which the blind use of "diff
X -c" results in a huge and mostly useless patch. Yes, *we* know about
X diff's "-b" option, but not everyone does. And yes, we also know this
X makes the source files bigger, even after compression; so be it.
X
X Bottom line: use spaces, not tabs.
X
X Exception: some of the makefiles (the Unix one in particular), for
X which tabs are required as part of the syntax.
X
X Related utility programs:
X Unix, OS/2 and MS-DOS: expand, unexpand.
X MS-DOS: Buerg's TABS; Toad Hall's TOADSOFT.
X And some editors have the conversion built-in.
X
X
X (2) NO FEELTHY CARRIAGE RETURNS
X
X All source, documentation and other text files shall have Unix style
X line endings (LF only, a.k.a. ctrl-J), not the DOS/OS2/NT CR+LF or Mac
X CR-only line endings.
X
X Reason: "real programmers" in any environment can convert back and
X forth between Unix and DOS/Mac style. All PC compilers but a few old
X Borland versions can use either Unix or MS-DOS end-of-lines. Buerg's
X LIST (file-display utility) for MS-DOS can use Unix or MS-DOS EOLs.
X Both Zip and UnZip can convert line-endings as appropriate. But Unix
X utilities like diff and patch die a horrible death (or produce horrible
X output) if the target files have CRs.
X
X Related utilities: flip for Unix, OS/2 and MS-DOS; Unix "tr".
X
X Exceptions: documentation in pre-compiled binary distributions should
X be in the local (target) format.
X
X
X (3) NO FEELTHY 8-BIT CHARS
X
X Do all your editing in a plain-text ASCII editor. No WordPerfect, MS
X Word, WordStar document mode, or other word processor files, thenkyew.
X No desktop publishing. *Especially* no EBCDIC. No TIFFs, no GIFs, no
X embedded pictures or dancing ladies (too bad, Cave Newt). [Sigh... -CN]
X
X Reason: compatibility with different consoles. My old XT clone is
X the most limited!
X
X Exceptions: some Macintosh makefiles apparently require some 8-bit
X characters; the Human68k port uses 8-bit characters to Kanji or Kana
X comments (I think); etc.
X
X Related utilities: vi, emacs, EDLIN, Turbo C editor, other programmers'
X editors, various word processor -> text conversion utilities.
X
X
X (4) NO FEELTHY LEFT-JUSTIFIED DASHES
X
X Always precede repeated dashes (------) with one or more leading non-
X dash characters: spaces, tabs, pound signs (#), comments (/*), what-
X ever.
X
X Reason: sooner or later your source file will be e-mailed through an
X undigestifier utility, most of which treat leading dashes as end-of-
X message separators. We'd rather not have your code broken up into a
X dozen separate untitled messages, thank you.
X
X
X (5) NO FEELTHY FANCY_FILENAMES
X
X Assume the worst: that someone on a brain-damaged DOS system has to
X work with everything your magic fingers produced. Keep the filenames
X unimaginative and within MS-DOS limits (i.e., ordinary A..Z, 1..9,
X "-$_!"-type characters, in the 8.3 "filename.ext" format). Mac and
X Unix users, giggle all you want, but no spaces or multiple dots.
X
X Reason: compatibility with different file systems. MS-DOS FAT is the
X most limited, with the exception of CompuServe (6.3, argh).
X
X Exceptions: slightly longer names are occasionally acceptable within
X OS-specific subdirectories, but don't do that unless there's a good
X reason for it.
X
X
X (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS
X
X Beta testers and developers are in general expected to have both
X ftp capability and the ability to deal with zipfiles. Those without
X should either find a friend who does or else learn about ftp-mailers.
X
X Reason: the core development team barely has time to work on the
X code, much less prepare oddball formats and/or mail betas out (and
X the situation is getting worse, sigh).
X
X Exceptions: anyone seriously proposing to do a new port will be
X given special treatment, particularly with respect to UnZip; we
X obviously realize that bootstrapping a completely new port can be
X quite difficult and have no desire to make it even harder due to
X lack of access to the latest code (rule 0.2).
X
X Public releases of UnZip, on the other hand, will be available in
X the following formats: .tar.Z (16-bit compress'd tar), .zoo (ver-
X sion 2.10, available for Unix, OS/2, MS-DOS, VMS, etc.), and .zip
X (either "plain" or self-extracting). Zip sources and executables
X will generally only be distributed in .zip format, since Zip is
X pretty much useless without UnZip.
X
X
X (7) NO FEELTHY E-MAIL BINARIES
X
X Binary files (e.g., executables, test zipfiles, etc.) should NEVER
X be mailed raw. Where possible, they should be uploaded via ftp in
X BINARY mode; if that's impossible, Mark's "ship" ASCII-encoder should
X be used; and if that's unavailable, uuencode or xxencode should be
X used. Weirdo NeXTmail, mailtool and MIME formats are also Right Out.
X
X Files larger than 50KB may need to be broken into pieces for mailing
X (be sure to label them in order!), unless "ship" is used (it can
X auto-split, label and mail files if told to do so). If Down Under
X is involved, files must be broken into under-20KB chunks.
X
X Reasons: to prevent sounds of gagging mailers from resounding through-
X out the land. To be relatively efficient in the binary->ASCII conver-
X sion. (Yeah, yeah, I know, there's better conversions out there. But
X not as widely known, and they often break on BITNET gateways.)
X
X Related utilities: ship, uuencode, uudecode, uuxfer20, quux, others.
X Just make sure they don't leave embedded or trailing spaces (that is,
X they should use the "`" character in place of ASCII 32). Otherwise
X mailers are prone to truncate or whatever.
X
X
XGreg Roelofs (a.k.a. Cave Newt)
XInfo-ZIP UnZip guy
X
XDavid Kirschbaum
Xformer Info-ZIP Coordinator
END_OF_FILE
if test 13591 -ne `wc -c <'unzip-5.12/ZipPorts'`; then
echo shar: \"'unzip-5.12/ZipPorts'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/ZipPorts'
fi
if test -f 'unzip-5.12/human68k/options.s.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/human68k/options.s.UU'\"
else
echo shar: Extracting \"'unzip-5.12/human68k/options.s.UU'\" \(3262 characters\)
sed "s/^X//" >'unzip-5.12/human68k/options.s.UU' <<'END_OF_FILE'
Xbegin 644 unzip-5.12/human68k/options.s
XM*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BH**@D)
XM"0D)*@HJ"51W96YT>4]N92YX((%U@L:"HX*E@LF"H8+M@O&!=@DJ"BH)<&%T
XM8V@@9F]R(&AU;6%N(%9E<B R+C R+#(N,#,)*@HJ"0D)"0DJ"BHJ*BHJ*BHJ
XM*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ"BH**@EF:6QE(&YA
XM;64Z"6]P=&EO;G,N<PHJ"6%U=&AO<CH)"8)D@IB"E" H5"Y+87=A;6]T;RD*
XM*@EL87-T(&UO9&EF>3H).3(O,R\Q"BH)"0DY,B\S+S$W('1H86YK<R!9554H
XM2$%254M!*0HJ"F)L<&5E:SH);6%C<F\*"6UO=F5Q+FP)(R0X-"QD, H)=')A
XM< DC,34*"65N9&T**@IG971P9&(Z"6UA8W)O"@ED8RYW"21F9C4Q"@EE;F1M
XM"BH*"2YX9&5F"5]4=V5N='E/;F5/<'1I;VYS"BH*"2YT97AT"BH*7U1W96YT
XM>4]N94]P=&EO;G,Z"@EM;W9E;2YL"6$P+6$R+"TH<W I"@EB<W()<V5A<F-H
XM7VUE;6]R>5]B;&EN9&QY"@ET<W0N; ED, H)8FYE"7)E='5R;@H)8G-R"7-E
XM87)C:%]D979I8V5?8FQI;F1L>0IR971U<FXZ"@EM;W9E;2YL"2AS<"DK+&$P
XM+6$R"@ER=',**@IS96%R8VA?9&5V:6-E7V)L:6YD;'DZ"@EL96$))# P,# V
XM.# P+&$Q"G-E87)C:%].54Q?9&5V:6-E7VQO;W Z"@EC;7 N; DC)# P,#(P
XM,# P+&$Q"@EB8V,)<V1?;F]T7V9O=6YD"@EB;'!E96L*"6-M<"YL"2,G3E5,
XM("<L9# *"6)E<0EF;W5N9%].54Q?9&5V:6-E"BH);&5A"30H83$I+&$Q"0D)
XM*B"(R(FZ@LR7=I?,@N:"Z H)"0D)"0DJ((*Q@K&"Q8-#@Y.#3H.*@X&#DX-G
XM@K>"Z95+EW:"S0H)"0D)"0DJ((*@@NB"W(*Y@O$),3DY,BXP,RXQ-R!9554H
XM2$%254M!*2X*"6-M<"YW"2,G3E4G+&0P"@EB;F4)<V5A<F-H7TY53%]D979I
XM8V5?;&]O< H);&5A"2TR*&$Q*2QA,0H)8G)A"7-E87)C:%].54Q?9&5V:6-E
XM7VQO;W **@IF;W5N9%].54Q?9&5V:6-E.@HJ"6QE80DM,30H83$I+&$Q"0D)
XM*B"!J2""L8*Q@JJ"J(*I@K6"H@H);&5A"2TQ."AA,2DL83$)"0DJ($E/0U,@
XM0E],4$5%2R""S);?@NB2;"!A,0H)"0D)"0DJ((+-(&0P((+,DFR"\([FD[Z"
XMM8*]@T&#:(.,@U@@*R T"@D)"0D)"2H@@LB"S(+%CI^"S(-F@V^#0X-8@M:"
XMS(-!@VB#C(-8@LT*"0D)"0D)*B M,3@H83$I((+&@LB"Z(+<@K<),3DY,BXP
XM,RXQ-R!9554N"G-E87)C:%]D979I8V4Z"@EB;'!E96L*<V1?;&]O<#H*"6UO
XM=F4N; ED,"QA, H);&5A"20P,#!%*&$P*2QA,@H)8G-R"6-H96-K7U17"@ET
XM<W0N; ED, H)8FYE"7-D7V5N9 H);&5A+FP)*&$P*2QA,0H)8FQP965K"@EC
XM;7 N; DC)&9F9F9F9F9F+&0P"@EB;F4)<V1?;&]O< IS9%]N;W1?9F]U;F0Z
XM"@EM;W9E<2YL"2,P+&0P"G-D7V5N9#H*"7)T<PHJ"G-E87)C:%]M96UO<GE?
XM8FQI;F1L>3H*"6=E='!D8@H);6]V92YL"60P+&$Q"@EL96$)+3$V*&$Q*2QA
XM,0IS96%R8VA?=&]P7VQO;W Z"@EL96$)-"AA,2DL83$*"6)L<&5E:PH)='-T
XM+FP)9# *"6)E<0EF;W5N9%]T;W *"6UO=F4N; ED,"QA,0H)8G)A"7-E87)C
XM:%]T;W!?;&]O< HJ"F9O=6YD7W1O<#H*"6QE80DM."AA,2DL83$)"0DJ((+(
XM@KJ"J8*Q@LR-<X*J@U*#@8.3@V>-<X+)@LB"P8+$@J*"W(*U@KT**@EL96$)
XM."AA,2DL83$)"0DJ()&]E:J"L8+!@K^"JH-2@X&#DX-GC7."OH+&CG:"HH+<
XM@K<*"0D)"0D)*B Q.3DR+C S+C$W(%E552A(05)52T$I+@IS96%R8VA?;65M
XM;W)Y.@H);&5A"3$R*&$Q*2QA,0H)8FQP965K"G-M7VQO;W Z"@EM;W9E+FP)
XM9# L83 *"6QE80DD,#$P12AA,"DL83(*"6)S<@EC:&5C:U]45PH)='-T+FP)
XM9# *"6)N90ES;5]E;F0*"6QE80DD,# P0RAA,"DL83$*"6)L<&5E:PH)='-T
XM+FP)9# *"6)N90ES;5]L;V]P"@EM;W9E<2YL"2,P+&0P"G-M7V5N9#H*"7)T
XM<PHJ"F-H96-K7U17.@H);&5A"2AA,BDL83$*"6)L<&5E:PH)8VUP+FP)(R<_
XM5'=E)RQD, H)8F5Q"6-H96-K7VYE=PH)8VUP+FP)(R<J5'=E)RQD, H)8FYE
XM"6-H96-K7V5R<F]R"F-H96-K7V]L9#H*"6QE80DD,# P-"AA,BDL83$*"6)L
XM<&5E:PH)8VUP+FP)(R=N='DJ)RQD, H)8FYE"6-H96-K7V5R<F]R"@EM;W9E
XM<2YL"2,M,2QD, H)<G1S"BH*8VAE8VM?;F5W.@H);&5A"20P,# T*&$R*2QA
XM,0H)8FQP965K"@EC;7 N; DC)VYT>3\G+&0P"@EB97$)8VAE8VM?;F5W7T4*
XM"6-M<"YL"2,G;G1Y12<L9# *"6)N90EC:&5C:U]E<G)O<@IC:&5C:U]N97=?
XM13H*"6QE80DD,# P."AA,BDL83$*"6)L<&5E:PH)<G1S"BH*8VAE8VM?97)R
XM;W(Z"@EM;W9E<2YL"2,P+&0P"@ER=',**@H)9&,N8@DG5'=E;G1Y3VYE($]P
XM=&EO;B!#:&5C:V5R(%9E<B Q+C P("<*"61C+F())T-O<'ER:6=H=" Q.3DQ
XE+#DR(()D@IB"E" H@G,N@FIA=V%M;W1O*2<L, HJ"@DN96YD"F=H
X
Xend
END_OF_FILE
if test 3262 -ne `wc -c <'unzip-5.12/human68k/options.s.UU'`; then
echo shar: \"'unzip-5.12/human68k/options.s.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'unzip-5.12/human68k/options.s'\" \(2332 characters\)
cat unzip-5.12/human68k/options.s.UU | uudecode
if test 2332 -ne `wc -c <'unzip-5.12/human68k/options.s'`; then
echo shar: \"'unzip-5.12/human68k/options.s'\" uudecoded with wrong size!
else
rm unzip-5.12/human68k/options.s.UU
fi
fi
# end of 'unzip-5.12/human68k/options.s.UU'
fi
if test -f 'unzip-5.12/os2/wat_met.dif' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/wat_met.dif'\"
else
echo shar: Extracting \"'unzip-5.12/os2/wat_met.dif'\" \(19538 characters\)
sed "s/^X//" >'unzip-5.12/os2/wat_met.dif' <<'END_OF_FILE'
XDate: Wed, 3 Aug 1994 19:34:23 +0200
XFrom: Kai Uwe Rommel <rom...@ars.muc.de>
X
XEnclosed I send the revised set of patches. That does now also include
Xsome changes required for MetaWare High C++ for OS/2.
X
X
Xdiff -cbr unzip/envargs.c unzip-2/envargs.c
X*** unzip/envargs.c Thu Apr 21 10:02:16 1994
X--- unzip-2/envargs.c Tue Aug 02 11:48:46 1994
X***************
X*** 180,186 ****
X--- 180,188 ----
X char ***argvp;
X {
X #ifndef MSC /* declared differently in MSC 7.0 headers, at least */
X+ #ifndef __WATCOMC__
X extern char **environ; /* environment */
X+ #endif
X #endif
X char **envp; /* pointer into environment */
X char **newargv; /* new argument list */
Xdiff -cbr unzip/extract.c unzip-2/extract.c
X*** unzip/extract.c Fri Jul 22 13:03:48 1994
X--- unzip-2/extract.c Tue Aug 02 11:48:46 1994
X***************
X*** 863,869 ****
X--- 863,873 ----
X if (cflag) {
X outfile = stdout;
X #ifdef DOS_NT_OS2
X+ #ifdef __HIGHC__
X+ setmode(outfile, _BINARY);
X+ #else
X setmode(fileno(outfile), O_BINARY);
X+ #endif
X # define NEWLINE "\r\n"
X #else
X # define NEWLINE "\n"
Xdiff -cbr unzip/funzip.c unzip-2/funzip.c
X*** unzip/funzip.c Sun Jul 31 20:28:52 1994
X--- unzip-2/funzip.c Tue Aug 02 11:48:48 1994
X***************
X*** 238,250 ****
X--- 238,258 ----
X else
X {
X #ifdef DOS_NT_OS2
X+ #ifdef __HIGHC__
X+ setmode(stdin, _BINARY);
X+ #else


X setmode(0, O_BINARY); /* some buggy C libraries require BOTH setmode() */

X+ #endif
X #endif /* call AND the fdopen() in binary mode :-( */


X if ((in = fdopen(0, FOPR)) == (FILE *)NULL)
X err(2, "cannot find stdin");
X }
X #ifdef DOS_NT_OS2

X+ #ifdef __HIGHC__
X+ setmode(stdout, _BINARY);
X+ #else
X setmode(1, O_BINARY);
X+ #endif
X #endif


X if ((out = fdopen(1, FOPW)) == (FILE *)NULL)
X err(2, "cannot write to stdout");

Xdiff -cbr unzip/msdos/msdos.c unzip-2/msdos/msdos.c
X*** unzip/msdos/msdos.c Wed Jul 27 22:20:06 1994
X--- unzip-2/msdos/msdos.c Tue Aug 02 11:48:52 1994
X***************
X*** 37,45 ****
X static int renamed_fullpath; /* ditto */
X static unsigned nLabelDrive; /* ditto, plus volumelabel() */
X
X! #if (defined(__GO32__) || defined(__EMX__))
X! # define MKDIR(path,mode) mkdir(path,mode)
X # include <dirent.h> /* use readdir() */


X # define direct dirent
X # define Opendir opendir
X # define Readdir readdir

X--- 37,57 ----
X static int renamed_fullpath; /* ditto */
X static unsigned nLabelDrive; /* ditto, plus volumelabel() */
X
X! #if (defined(__WATCOMC__) && defined(__386__))
X! # define WREGS(v,r) (v##.w.##r)
X! # define int86x int386x
X! #else
X! # define WREGS(v,r) (v##.x.##r)
X! #endif
X!
X! #if (defined(__GO32__) || defined(__EMX__) || defined(__WATCOMC__))
X! # ifdef __WATCOMC__
X! # include <direct.h>
X! # define MKDIR(path,mode) mkdir(path)
X! # else
X # include <dirent.h> /* use readdir() */
X+ # define MKDIR(path,mode) mkdir(path,mode)
X+ # endif
X # define direct dirent
X # define Opendir opendir
X # define Readdir readdir
X***************
X*** 774,791 ****
X regs.h.bl = (uch)nDrive;
X #ifdef __EMX__
X _int86(0x21, &regs, &regs);
X! if (regs.x.flags & 1)
X #else
X intdos(&regs, &regs);
X! if (regs.x.cflag) /* error: do default a/b check instead */


X #endif
X {
X Trace((stderr,
X "error in DOS function 0x44 (AX = 0x%04x): guessing instead...\n",

X! regs.x.ax));


X return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;
X } else

X! return regs.x.ax? FALSE : TRUE;
X }
X
X
X--- 786,803 ----
X regs.h.bl = (uch)nDrive;
X #ifdef __EMX__
X _int86(0x21, &regs, &regs);
X! if (WREGS(regs,flags) & 1)
X #else
X intdos(&regs, &regs);
X! if (WREGS(regs,cflag)) /* error: do default a/b check instead */


X #endif
X {
X Trace((stderr,
X "error in DOS function 0x44 (AX = 0x%04x): guessing instead...\n",

X! WREGS(regs,ax)));


X return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;
X } else

X! return WREGS(regs,ax)? FALSE : TRUE;
X }
X
X
X***************
X*** 854,874 ****
X

X /* set the disk transfer address for subsequent FCB calls */
X sregs.ds = FP_SEG(pdta);

X! regs.x.dx = FP_OFF(pdta);
X! Trace((stderr, "segment:offset of pdta = %x:%x\n", sregs.ds, regs.x.dx));


X Trace((stderr, "&dta = %lx, pdta = %lx\n", (ulg)&dta, (ulg)pdta));
X regs.h.ah = 0x1a;
X intdosx(&regs, &regs, &sregs);
X
X /* fill in the FCB */
X sregs.ds = FP_SEG(pfcb);

X! regs.x.dx = FP_OFF(pfcb);


X pfcb->flag = 0xff; /* extended FCB */
X pfcb->vattr = 0x08; /* attribute: disk volume label */
X pfcb->drive = (uch)nLabelDrive;
X
X #ifdef DEBUG

X! Trace((stderr, "segment:offset of pfcb = %x:%x\n", sregs.ds, regs.x.dx));


X Trace((stderr, "&fcb = %lx, pfcb = %lx\n", (ulg)&fcb, (ulg)pfcb));
X Trace((stderr, "(2nd check: labelling drive %c:)\n", pfcb->drive-1+'A'));
X if (pfcb->flag != fcb.flag)

X--- 866,886 ----
X

X /* set the disk transfer address for subsequent FCB calls */
X sregs.ds = FP_SEG(pdta);

X! WREGS(regs,dx) = FP_OFF(pdta);
X! Trace((stderr, "segment:offset of pdta = %x:%x\n", sregs.ds, WREGS(regs,dx)));


X Trace((stderr, "&dta = %lx, pdta = %lx\n", (ulg)&dta, (ulg)pdta));
X regs.h.ah = 0x1a;
X intdosx(&regs, &regs, &sregs);
X
X /* fill in the FCB */
X sregs.ds = FP_SEG(pfcb);

X! WREGS(regs,dx) = FP_OFF(pfcb);


X pfcb->flag = 0xff; /* extended FCB */
X pfcb->vattr = 0x08; /* attribute: disk volume label */
X pfcb->drive = (uch)nLabelDrive;
X
X #ifdef DEBUG

X! Trace((stderr, "segment:offset of pfcb = %x:%x\n", sregs.ds, WREGS(regs,dx)));


X Trace((stderr, "&fcb = %lx, pfcb = %lx\n", (ulg)&fcb, (ulg)pfcb));
X Trace((stderr, "(2nd check: labelling drive %c:)\n", pfcb->drive-1+'A'));
X if (pfcb->flag != fcb.flag)

X***************
X*** 894,900 ****


X strncpy((char *)fcb.vn, "???????????", 11); /* i.e., "*.*" */
X Trace((stderr, "fcb.vn = %lx\n", (ulg)fcb.vn));
X Trace((stderr, "regs.h.ah = %x, regs.x.dx = %04x, sregs.ds = %04x\n",

X! regs.h.ah, regs.x.dx, sregs.ds));


X Trace((stderr, "flag = %x, drive = %d, vattr = %x, vn = %s = %s.\n",
X fcb.flag, fcb.drive, fcb.vattr, fcb.vn, pfcb->vn));
X intdosx(&regs, &regs, &sregs);

X--- 906,912 ----


X strncpy((char *)fcb.vn, "???????????", 11); /* i.e., "*.*" */
X Trace((stderr, "fcb.vn = %lx\n", (ulg)fcb.vn));
X Trace((stderr, "regs.h.ah = %x, regs.x.dx = %04x, sregs.ds = %04x\n",

X! regs.h.ah, WREGS(regs,dx), sregs.ds));


X Trace((stderr, "flag = %x, drive = %d, vattr = %x, vn = %s = %s.\n",
X fcb.flag, fcb.drive, fcb.vattr, fcb.vn, pfcb->vn));
X intdosx(&regs, &regs, &sregs);

X***************
X*** 1058,1065 ****


X union REGS regs;
X
X sregs.ds = FP_SEG(CountryInfo);

X! regs.x.dx = FP_OFF(CountryInfo);
X! regs.x.ax = 0x3800;


X int86x(0x21, &regs, &regs, &sregs);
X
X #else /* __GO32__ || __EMX__ */

X--- 1070,1077 ----


X union REGS regs;
X
X sregs.ds = FP_SEG(CountryInfo);

X! WREGS(regs,dx) = FP_OFF(CountryInfo);
X! WREGS(regs,ax) = 0x3800;


X int86x(0x21, &regs, &regs, &sregs);
X
X #else /* __GO32__ || __EMX__ */

Xdiff -cbr unzip/os2/makefile.os2 unzip-2/os2/makefile.os2
X*** unzip/os2/makefile.os2 Sat Jul 23 13:42:04 1994
X--- unzip-2/os2/makefile.os2 Tue Aug 02 11:53:42 1994
X***************
X*** 32,43 ****
X # For Watcom C/386, edit the os2$(OBJ) target so that os2/os2.c reads
X # os2\os2.c instead. Watcom can't handle forward slashes; gcc can't
X # handle backslashes. We'll see about making this a macro next time...
X
X default:
X @echo "Enter `$(MAKE) -f makefile.os2 target' with makefile.os2 copied"
X @echo "to the main UnZip directory and where target is one of:"
X @echo " msc mscdos ibm ibmdyn ibmdebug ibmprof"
X! @echo " watcom borland gcc gccdyn gccdebug gccdos"
X
X # MS C 6.00 for OS/2, 16-bit (should figure out way to split unzip/funzip
X # compiles so former is always large model and latter always small model...)
X--- 32,45 ----
X # For Watcom C/386, edit the os2$(OBJ) target so that os2/os2.c reads
X # os2\os2.c instead. Watcom can't handle forward slashes; gcc can't
X # handle backslashes. We'll see about making this a macro next time...
X+ # Same for msdos/msdos.c ...
X
X default:
X @echo "Enter `$(MAKE) -f makefile.os2 target' with makefile.os2 copied"
X @echo "to the main UnZip directory and where target is one of:"
X @echo " msc mscdos ibm ibmdyn ibmdebug ibmprof"
X! @echo " metaware borland gcc gccdyn gccdebug gccdos"
X! @echo " watcom watcom16 watcomdos watcom16dos"
X
X # MS C 6.00 for OS/2, 16-bit (should figure out way to split unzip/funzip
X # compiles so former is always large model and latter always small model...)
X***************
X*** 52,57 ****
X--- 54,71 ----
X OBJ=".obj" \
X DEF="os2\unzip16.def"
X
X+ # MS C 6.00 for OS/2, debug version
X+ mscdebug:
X+ $(MAKE) -f makefile.os2 all \
X+ CC="cl -nologo -AL -Zi -Od -I. $(FP)" \
X+ CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC" \
X+ NFLAGS="" \
X+ LDFLAGS="-Lp -Fe" \
X+ LDFLAGS2="-link /noe" \
X+ OUT="-Fo" \
X+ OBJ=".obj" \
X+ DEF="os2\unzip16.def"
X+
X # cross-compilation for MS-DOS with MS C 6.00 (same comment as above...formerly;
X # now unzip is small model again, with [almost] all strings in far memory)
X mscdos:
X***************
X*** 59,65 ****
X CC="cl -nologo -AS -Oaict -Gs -I. $(FP)" \
X CFLAGS="-Zp1 -W3 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X! LDFLAGS="-F 0c00 -Lr -Fe" \
X LDFLAGS2="-link /noe /exe" \
X OUT="-Fo" \
X OBJ=".obj" \
X--- 73,79 ----
X CC="cl -nologo -AS -Oaict -Gs -I. $(FP)" \
X CFLAGS="-Zp1 -W3 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X! LDFLAGS="-F 0C00 -Lr -Fe" \
X LDFLAGS2="-link /noe /exe" \
X OUT="-Fo" \
X OBJ=".obj" \
X***************
X*** 114,131 ****
X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X! # Watcom C/386 9.0
X watcom:
X $(MAKE) -f makefile.os2 all \
X CC="wcl386 -zq -Ox -s -I." \
X CFLAGS="-Zp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X! LDFLAGS="-k0x40000 -x -Fe=" \
X LDFLAGS2="" \
X OUT="-Fo" \
X OBJ=".obj" \
X DEF=""
X
X # Borland C++
X borland:
X $(MAKE) -f makefile.os2 all \
X--- 128,194 ----
X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X! # Watcom C/386 9.0 or higher
X watcom:
X $(MAKE) -f makefile.os2 all \
X CC="wcl386 -zq -Ox -s -I." \
X CFLAGS="-Zp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X! LDFLAGS="-k0x40000 -x -l=os2v2 -Fe=" \
X LDFLAGS2="" \
X OUT="-Fo" \
X OBJ=".obj" \
X DEF=""
X
X+ # Watcom C/286 9.0 or higher
X+ watcom16:
X+ $(MAKE) -f makefile.os2 all \
X+ CC="wcl -zq -ml -Ox -s -I." \
X+ CFLAGS="-Zp1 -DOS2" \
X+ NFLAGS="" \
X+ LDFLAGS="-k0x2000 -x -l=os2 -Fe=" \
X+ LDFLAGS2="" \
X+ OUT="-Fo" \
X+ OBJ=".obj"
X+
X+ # Watcom C/386 9.0 or higher, crosscompilation for DOS
X+ watcomdos:
X+ $(MAKE) -f makefile.os2 all \
X+ CC="wcl386 -zq -Ox -s -I." \
X+ CFLAGS="-Zp1 -DMSDOS" \
X+ NFLAGS="" \
X+ LDFLAGS="-k0x40000 -x -l=dos4g -Fe=" \
X+ LDFLAGS2="" \
X+ OUT="-Fo" \
X+ OBJ=".obj" \
X+ OBJU2="msdos.obj" \
X+ OBJX2="msdos_.obj"
X+
X+ # Watcom C/286 9.0 or higher, crosscompilation for DOS
X+ watcom16dos:
X+ $(MAKE) -f makefile.os2 all \
X+ CC="wcl -zq -mm -Ox -s -I." \
X+ CFLAGS="-Zp1 -DMSDOS" \
X+ NFLAGS="" \
X+ LDFLAGS="-k0xC00 -x -l=dos -Fe=" \
X+ LDFLAGS2="" \
X+ OUT="-Fo" \
X+ OBJ=".obj" \
X+ OBJU2="msdos.obj" \
X+ OBJX2="msdos_.obj"
X+
X+ # MetaWare High C/C++ 3.2
X+ metaware:
X+ $(MAKE) -f makefile.os2 all \
X+ CC="hc -O2 -I." \
X+ CFLAGS="-D__32BIT__ -DOS2" \
X+ NFLAGS="" \
X+ LDFLAGS="-o " \
X+ LDFLAGS2="" \
X+ OUT="-o ./" \
X+ OBJ=".obj" \
X+ DEF="-Hdef=os2\unzip.def"
X+
X # Borland C++
X borland:
X $(MAKE) -f makefile.os2 all \
X***************
X*** 192,198 ****
X extract$(OBJ) file_io$(OBJ) inflate$(OBJ) match$(OBJ) \
X unreduce$(OBJ) unshrink$(OBJ) zipinfo$(OBJ)
X OBJU2 = os2$(OBJ)
X! OBJX = unzip_$(OBJ) crypt$(OBJ) extract_$(OBJ) file_io$(OBJ) \
X inflate$(OBJ) match$(OBJ)
X OBJX2 = os2_$(OBJ)
X OBJF = funzip$(OBJ) crypt_$(OBJ) inflate_$(OBJ)
X--- 255,261 ----
X extract$(OBJ) file_io$(OBJ) inflate$(OBJ) match$(OBJ) \
X unreduce$(OBJ) unshrink$(OBJ) zipinfo$(OBJ)
X OBJU2 = os2$(OBJ)
X! OBJX = unzipsfx$(OBJ) crypt$(OBJ) extract_$(OBJ) file_io$(OBJ) \
X inflate$(OBJ) match$(OBJ)
X OBJX2 = os2_$(OBJ)
X OBJF = funzip$(OBJ) crypt_$(OBJ) inflate_$(OBJ)
X***************
X*** 252,256 ****
X inflate_$(OBJ): inflate.c inflate.h unzip.h crypt.h # funzip only
X $(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ inflate.c
X
X! unzip_$(OBJ): unzip.c unzip.h crypt.h version.h # unzipsfx only
X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ unzip.c
X--- 315,319 ----
X inflate_$(OBJ): inflate.c inflate.h unzip.h crypt.h # funzip only
X $(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ inflate.c
X
X! unzipsfx$(OBJ): unzip.c unzip.h crypt.h version.h # unzipsfx only
X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ unzip.c
Xdiff -cbr unzip/os2/os2.c unzip-2/os2/os2.c
X*** unzip/os2/os2.c Wed Jul 27 22:23:02 1994
X--- unzip-2/os2/os2.c Tue Aug 02 11:48:54 1994
X***************
X*** 73,78 ****
X--- 73,79 ----
X #define INCL_DOSDEVICES
X #define INCL_DOSDEVIOCTL
X #define INCL_DOSERRORS
X+ #define INCL_DOSMISC
X #include <os2.h>
X
X #ifdef __32BIT__
X***************
X*** 229,238 ****
X #endif
X
X
X- #ifdef __WATCOMC__
X- unsigned char __near _osmode = OS2_MODE;
X- #endif
X-
X #ifndef SFX


X static char *getdirent(char *);
X static void free_dircontents(struct _dircontents *);

X--- 230,235 ----
X***************
X*** 387,394 ****


X if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL )
X return;
X

X! if ( memextract((char *) pFEA2list, pEAblock -> lSize,
X! (char *) (pEAblock + 1),

X pEAblock -> nSize - sizeof(pEAblock -> lSize)) )
X {
X free(pFEA2list);

X--- 384,391 ----


X if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL )
X return;
X

X! if ( memextract((uch *) pFEA2list, pEAblock -> lSize,
X! (uch *) (pEAblock + 1),

X pEAblock -> nSize - sizeof(pEAblock -> lSize)) )
X {
X free(pFEA2list);

X***************
X*** 450,474 ****
X char *GetLoadPath(void)
X {
X #ifdef __32BIT__ /* generic for 32-bit API */
X-

X PTIB pptib;
X PPIB pppib;
X char *szPath;
X
X DosGetInfoBlocks(&pptib, &pppib);
X szPath = pppib -> pib_pchenv;
X
X while (*szPath) /* find end of process environment */
X szPath = strchr(szPath, 0) + 1;
X
X return szPath + 1; /* .exe file name follows environment */
X

X- #else /* 16-bit, specific for MS C 6.00, note: requires large data model */
X-
X- extern char _far *_pgmptr;
X- return _pgmptr;
X-
X- #endif


X } /* end function GetLoadPath() */
X
X

X--- 447,472 ----
X char *GetLoadPath(void)
X {
X #ifdef __32BIT__ /* generic for 32-bit API */


X PTIB pptib;
X PPIB pppib;
X char *szPath;
X
X DosGetInfoBlocks(&pptib, &pppib);
X szPath = pppib -> pib_pchenv;

X+ #else /* 16-bit, note: requires large data model */
X+ SEL selEnv;
X+ USHORT offCmd;
X+ char *szPath;
X+
X+ DosGetEnv(&selEnv, &offCmd);
X+ szPath = MAKEP(selEnv, 0);
X+ #endif


X
X while (*szPath) /* find end of process environment */
X szPath = strchr(szPath, 0) + 1;
X

X return szPath + 1; /* .exe file name follows environment */
X
X } /* end function GetLoadPath() */
X
X
X***************
X*** 680,686 ****
X {
X static USHORT nLastDrive=(USHORT)(-1), nResult;
X ULONG lMap;
X! BYTE bData[64], bName[3];
X #ifdef __32BIT__


X ULONG nDrive, cbData;
X PFSQBUFFER2 pData = (PFSQBUFFER2) bData;

X--- 678,685 ----
X {
X static USHORT nLastDrive=(USHORT)(-1), nResult;
X ULONG lMap;
X! BYTE bData[64];
X! char bName[3];
X #ifdef __32BIT__


X ULONG nDrive, cbData;
X PFSQBUFFER2 pData = (PFSQBUFFER2) bData;

X***************
X*** 689,698 ****


X PFSQBUFFER pData = (PFSQBUFFER) bData;
X #endif
X

X- if ( _osmode == DOS_MODE )
X- return TRUE;
X- else
X- {


X /* We separate FAT and HPFS+other file systems here.
X at the moment I consider other systems to be similar to HPFS,
X i.e. support long file names and case sensitive */

X--- 688,693 ----
X***************
X*** 713,725 ****


X cbData = sizeof(bData);
X
X if ( !DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData) )

X! nResult = !strcmp(pData -> szFSDName + pData -> cbName, "FAT");
X else
X nResult = FALSE;
X

X /* End of this ugly code */
X return nResult;

X- }


X } /* end function IsFileSystemFAT() */
X
X

X--- 708,719 ----


X cbData = sizeof(bData);
X
X if ( !DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData) )

X! nResult = !strcmp((char *) (pData -> szFSDName) + pData -> cbName, "FAT");
X else
X nResult = FALSE;
X

X /* End of this ugly code */
X return nResult;

X } /* end function IsFileSystemFAT() */
X
X
X***************
X*** 1398,1404 ****
X ULONG action;
X #else
X USHORT rc;
X! UINT action;
X #endif
X
X
X--- 1392,1398 ----
X ULONG action;
X #else
X USHORT rc;
X! USHORT action;
X #endif
X
X
X***************
X*** 1579,1597 ****


X eaop.fpGEAList = NULL;
X eaop.oError = 0;
X

X! strcpy(fealst.szName, ".LONGNAME");
X! strcpy(fealst.szValue, longname);
X
X! fealst.cbList = sizeof(fealst) - CCHMAXPATH + strlen(fealst.szValue);
X! fealst.cbName = (BYTE) strlen(fealst.szName);
X! fealst.cbValue = sizeof(USHORT) * 2 + strlen(fealst.szValue);
X
X #ifdef __32BIT__


X fealst.oNext = 0;
X #endif
X fealst.fEA = 0;
X fealst.eaType = 0xFFFD;

X! fealst.eaSize = strlen(fealst.szValue);


X
X return DosSetPathInfo(name, FIL_QUERYEASIZE,
X (PBYTE) &eaop, sizeof(eaop), 0);

X--- 1573,1591 ----


X eaop.fpGEAList = NULL;
X eaop.oError = 0;
X

X! strcpy((char *) fealst.szName, ".LONGNAME");
X! strcpy((char *) fealst.szValue, longname);
X
X! fealst.cbList = sizeof(fealst) - CCHMAXPATH + strlen((char *) fealst.szValue);
X! fealst.cbName = (BYTE) strlen((char *) fealst.szName);
X! fealst.cbValue = sizeof(USHORT) * 2 + strlen((char *) fealst.szValue);
X
X #ifdef __32BIT__


X fealst.oNext = 0;
X #endif
X fealst.fEA = 0;
X fealst.eaType = 0xFFFD;

X! fealst.eaSize = strlen((char *) fealst.szValue);


X
X return DosSetPathInfo(name, FIL_QUERYEASIZE,
X (PBYTE) &eaop, sizeof(eaop), 0);

X***************
X*** 1880,1886 ****


X
X if (!bInitialized)
X InitNLS();

X! for ( szPtr = szArg; *szPtr; szPtr++ )


X *szPtr = cLowerCase[*szPtr];
X return szArg;
X }

X--- 1874,1880 ----


X
X if (!bInitialized)
X InitNLS();

X! for ( szPtr = (unsigned char *) szArg; *szPtr; szPtr++ )


X *szPtr = cLowerCase[*szPtr];
X return szArg;
X }

Xdiff -cbr unzip/unzip.h unzip-2/unzip.h
X*** unzip/unzip.h Sun Jul 31 20:09:44 1994
X--- unzip-2/unzip.h Tue Aug 02 11:48:56 1994
X***************
X*** 437,447 ****
X--- 437,449 ----
X #endif
X
X #ifdef __WATCOMC__
X+ # ifdef __386__
X # define __32BIT__
X # undef far
X # define far
X # undef near
X # define near
X+ # endif
X # define PIPE_ERROR (errno == -1)
X #endif
X
X***************
X*** 770,776 ****
X #endif
X
X /* GRR: NT defines MSDOS?? */
X! #if (!defined(MSDOS) && !defined(__IBMC__)) || defined(NT)
X # define near
X # define far
X #endif
X--- 772,778 ----
X #endif
X
X /* GRR: NT defines MSDOS?? */
X! #if (!defined(MSDOS) && !defined(__IBMC__) && defined(__32BIT__)) || defined(NT)
X # define near
X # define far
X #endif
END_OF_FILE
if test 19538 -ne `wc -c <'unzip-5.12/os2/wat_met.dif'`; then
echo shar: \"'unzip-5.12/os2/wat_met.dif'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/wat_met.dif'
fi
if test -f 'unzip-5.12/unix/unzipsfx.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/unzipsfx.1'\"
else
echo shar: Extracting \"'unzip-5.12/unix/unzipsfx.1'\" \(12523 characters\)
sed "s/^X//" >'unzip-5.12/unix/unzipsfx.1' <<'END_OF_FILE'


X.\" Info-ZIP grants permission to any individual or institution to use, copy,
X.\" or redistribute this software, so long as: (1) all of the original files
X.\" are included; (2) it is not sold for profit; and (3) this notice is re-
X.\" tained.
X.\"

X.\" unzipsfx.1 by Greg Roelofs
X.\"
X.\" =========================================================================


X.\" define .Y macro (for user-command examples; normal Courier font):
X.de Y
X.ft CW
X.in +4n
X.nf
X\&\\$1
X.ft
X.in
X.fi
X..
X.\" =========================================================================

X.TH UNZIPSFX 1L "28 Aug 94 (v5.12)"
X.SH NAME
Xunzipsfx \- self-extracting stub for prepending to ZIP archives


X.PD
X.\" =========================================================================
X.SH SYNOPSIS

X\fB<name of unzipsfx+archive combo>\fP [\fB\-cfptuz\fP[\fBajnoqsCLV$\fP]]


X[\fIfile(s)\fP\ .\|.\|. [\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.]]
X.PD
X.\" =========================================================================
X.SH DESCRIPTION

X\fIunzipsfx\fP is a modified version of \fIunzip\fP(1L) designed to be prepended
Xto existing ZIP archives in order to form self-extracting archives. Instead
Xof taking its first non-flag argument to be the zipfile(s) to be extracted,
X\fIunzipsfx\fP seeks itself under the name by which it was invoked
Xand tests or extracts the contents of the appended archive. Because the
Xexecutable stub adds bulk to the archive (the whole purpose of which is to
Xbe as small as possible), a number of the regular version's less-vital
Xcapabilities have been removed. Among these are the usage (or help) screen,
Xthe listing and diagnostic functions (\fB\-l\fP and \fB\-v\fP), the ability
Xto decompress older compression formats (the ``reduce,'' ``shrink'' and
X``implode'' methods), and the ability to extract to a directory other than
Xthe current one. Decryption is supported as a compile-time option but
Xshould be avoided unless the attached archive contains encrypted files.
X.LP
X\fBNote that
Xself-extracting archives made with\fP \fIunzipsfx\fP \fBare no more (or less)
Xportable across different operating systems than is
Xthe\fP \fIunzip\fP \fBexecutable itself.\fP In general a self-extracting
Xarchive made on
Xa particular Unix system, for example, will only self-extract under the same
Xflavor of Unix. Regular \fIunzip\fP may still be used to extract the
Xembedded archive as with any normal zipfile, although it will generate
Xa harmless warning about extra bytes at the beginning of the zipfile.


X.PD
X.\" =========================================================================
X.SH ARGUMENTS

X.IP [\fIfile(s)\fP]
XAn optional list of archive members to be processed.

XRegular expressions (wildcards) similar to those in Unix \fIegrep\fP(1)
Xmay be used to match multiple members. These wildcards may contain:


X.RS
X.IP *
Xmatches a sequence of 0 or more characters
X.IP ?
Xmatches exactly 1 character
X.IP [.\|.\|.]
Xmatches any single character found inside the brackets; ranges are specified
Xby a beginning character, a hyphen, and an ending character. If an exclamation
Xpoint or a caret (`!' or `^') follows the left bracket, then the range of
Xcharacters within the brackets is complemented (that is, anything \fIexcept\fP
Xthe characters inside the brackets is considered a match).
X.RE
X.IP
X(Be sure to quote any character which might otherwise be interpreted or
Xmodified by the operating system, particularly under Unix and VMS.)

X.IP [\fB\-x\fP\ \fIxfile(s)\fP]
XAn optional list of archive members to be excluded from processing.

XSince wildcard characters match directory separators (`/'), this option
Xmay be used to exclude any files which are in subdirectories. For

Xexample, ``\fCfoosfx *.[ch] -x */*\fR'' would extract all C source files


Xin the main directory, but none in any subdirectories. Without the \fB\-x\fP
Xoption, all C source files in all directories within the zipfile would be
Xextracted.

XUnlike in \fIunzip\fP(1L), the \fB\-x\fP option may only be used if one or
Xmore \fIfiles\fP are given. This is because there is no zipfile separating
Xthe normal options from the \fB\-x\fP option, so \fIunzipsfx\fP sees it as
Xanother normal option. For historical reasons, the ``normal'' \fB\-x\fP is
Xsilently ignored. See the \fBEXAMPLES\fP section below.
X.LP
XIf \fIunzipsfx\fP is compiled with SFX_EXDIR defined, the following option
Xis also enabled:


X.IP [\fB\-d\fP\ \fIexdir\fP]
XAn optional directory to which to extract files. By default, all files
Xand subdirectories are recreated in the current directory; the \fB\-d\fP
Xoption allows extraction in an arbitrary directory (always assuming one

Xhas permission to write to the directory). The option and directory may


Xbe concatenated without any white space between them, but note that this
Xmay cause normal shell behavior to be suppressed. In particular,
X``\fC\-d\ ~\fR'' (tilde) is expanded by Unix C shells into the name
Xof the user's home directory, but ``\fC\-d~\fR'' is treated as a

Xliteral subdirectory ``\fB~\fP'' of the current directory. As with
X\fB\-x\fP, the \fB\-d\fP option may only be used if one or more \fIfiles\fP
Xare given.
X.PD
X.\" =========================================================================
X.SH OPTIONS
X\fIunzipsfx\fP supports the following \fIunzip\fP(1L) options: \fB\-c\fP
Xand \fB\-p\fP (extract to standard output/screen), \fB\-f\fP and \fB\-u\fP
X(freshen and update existing files upon extraction), \fB\-t\fP (test
Xarchive) and \fB\-z\fP (print archive comment). All normal listing options
X(\fB\-l\fP, \fB\-v\fP and \fB\-Z\fP) have been removed, but the testing
Xoption (\fB\-t\fP) may be used as a ``poor man's'' listing. Alternatively,
Xthose creating self-extracting archives may wish to include a short listing
Xin the zipfile comment.
X.LP
XSee \fIunzip\fP(1L) for a more complete description of these options.
X.PD
X.\" =========================================================================
X.SH MODIFIERS
X\fIunzipsfx\fP currently supports all \fIunzip\fP(1L) modifiers: \fB\-a\fP
X(convert text files), \fB\-n\fP (never overwrite), \fB\-o\fP (overwrite
Xwithout prompting), \fB\-q\fP (operate quietly), \fB\-C\fP (match names
Xcase-insenstively), \fB\-L\fP (convert uppercase-OS names to lowercase),
X\fB\-j\fP (junk paths) and \fB\-V\fP (retain version numbers); plus the
Xfollowing operating-system specific options: \fB\-X\fP (restore VMS
Xowner/protection info), \fB\-s\fP (convert spaces in filenames to underscores
X[DOS, OS/2, NT]) and \fB\-$\fP (restore volume label [DOS, OS/2, NT, Amiga]).
X.LP
X(Support for regular ASCII text-conversion may be removed in future versions,
Xsince it is simple enough for the archive's creator to ensure that text
Xfiles have the appropriate format for the local OS. EBCDIC conversion will
Xof course continue to be supported since the zipfile format implies ASCII
Xstorage of text files.)
X.LP
XSee \fIunzip\fP(1L) for a more complete description of these modifiers.


X.PD
X.\" =========================================================================
X.SH ENVIRONMENT OPTIONS

X\fIunzipsfx\fP uses the same environment variables as \fIunzip\fP(1L) does,
Xalthough this is likely to be an issue only for the person creating and
Xtesting the self-extracting archive. See \fIunzip\fP(1L) for details.


X.PD
X.\" =========================================================================
X.SH DECRYPTION

XDecryption is supported exactly as in \fIunzip\fP(1L); that is, interactively
Xwith a non-echoing prompt for the password(s). See \fIunzip\fP(1L) for
Xdetails. Once again, note that if the archive has no encrypted files there
Xis no reason to use a version of \fIunzipsfx\fP with decryption support;
Xthat only adds to the size of the archive.


X.PD
X.\" =========================================================================
X.SH EXAMPLES

XTo create a self-extracting archive \fIletters\fP from a regular zipfile
X\fIletters.zip\fP and change the new archive's permissions to be
Xworld-executable under Unix:
X.LP
X.PD 0
X.Y "cat unzipsfx letters.zip > letters"
X.Y "chmod 755 letters"
X.PD
X.LP
XTo create the same archive under MS-DOS, OS/2 or NT (note the use of the
X\fB/b\fP [binary] option to the \fIcopy\fP command):
X.LP
X.Y "copy /b unzipsfx.exe+letters.zip letters.exe"
X.LP
XUnder VMS:
X.LP
X.Y "copy unzipsfx.exe,letters.zip letters.exe"
X.Y "letters == ""$currentdisk:[currentdir]letters.exe"""
X.LP
X(The VMS \fIappend\fP command may also be used. The second command installs
Xthe new program as a ``foreign command'' capable of taking arguments.)
XTo test (or list) the newly created self-extracting archive:
X.LP
X.Y "letters \-t"
X.LP
XTo test \fIletters\fP quietly, printing only a summary message indicating


Xwhether the archive is OK or not:
X.LP

X.Y "letters \-tq"
X.LP
XTo extract the complete contents into the current directory, recreating all
Xfiles and subdirectories as necessary:
X.LP
X.Y "letters"
X.LP
XTo extract all \fC*.txt\fP files (in Unix quote the `*'):
X.LP
X.Y "letters *.txt"
X.LP
XTo extract everything \fIexcept\fP the \fC*.txt\fP files:
X.LP
X.Y "letters * -x *.txt"
X.LP
X(Note that with regular \fIunzip\fP(1L) it would not be necessary to use
Xthe first `*'; ``\fCunzip letters -x *.txt\fP'' would work equally well.
XWith \fIunzipsfx\fP the \fB\-x\fP option would be silently ignored and
Xthe effect would be the same as in the previous example, i.e., the opposite
Xof what was intended.)
XTo extract only the README file to standard output (the screen):
X.LP
X.Y "letters -c README"
X.LP
XTo print only the zipfile comment:
X.LP
X.Y "letters \-z"
X.PD
X.\" =========================================================================
X.SH LIMITATIONS
XThe principle and fundamental limitation of \fIunzipsfx\fP is that it is
Xnot portable across architectures or operating systems, and therefore
Xneither are the resulting archives. For some architectures there is
Xlimited portability, however (e.g., between some flavors of Intel-based Unix).
X.LP
X\fIunzipsfx\fP has no knowledge of the user's PATH, so in general an archive
Xmust either be in the current directory when it is invoked, or else a full
Xor relative path must be given. If a user attempts to extract the archive
Xfrom a directory in the PATH other than the current one, \fIunzipsfx\fP will
Xprint a warning to the effect, ``can't find myself.'' This is always true
Xunder Unix and may be true in some cases under MS-DOS, depending on the
Xcompiler used (Microsoft C fully qualifies the program name, but other
Xcompilers may not). Under OS/2 and NT there are operating-system calls
Xavailable which provide the full path name, so the archive may be invoked
Xfrom anywhere in the user's path. The situation is not known for Atari TOS,
XMacOS, etc.
X.LP
XAs noted above, a number of the normal \fIunzip\fP(1L) functions have
Xbeen removed in order to make \fIunzipsfx\fP smaller: usage and diagnostic
Xinfo, listing functions and extraction to other directories. Also, only
Xstored and deflated files are supported. The latter limitation is mainly
Xrelevant to those who create SFX archives, however.
X.LP
XVMS users must know how to set up self-extracting archives as foreign
Xcommands in order to use any of \fIunzipsfx\fP's options. This is not
Xnecessary for simple extraction, but the command to do so then becomes,
Xe.g., ``\fCrun letters\fR'' (to continue the examples given above).
X.LP
X\fIunzipsfx\fP is not supported on the Amiga because of the way the loader
Xworks; the entire archive contents would be loaded into memory by default.
XIt may be possible to work around this by defining the attached archive to
Xbe a ``debug hunk,'' but compatibility problems between the ROM levels of
Xolder Amigas and newer ones are likely to cause problems regardless.
X.LP
XAll current bugs in \fIunzip\fP(1L) exist in \fIunzipsfx\fP as well.


X.PD
X.\" =========================================================================
X.SH DIAGNOSTICS

X\fIunzipsfx\fP's exit status (error level) is identical to that of
X\fIunzip\fP(1L); see the corresponding man page.
X.PD


X.\" =========================================================================
X.SH SEE ALSO

X\fIfunzip\fP(1L), \fIunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L),
X\fIzipgrep\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
X.PD
X.\" =========================================================================
X.SH AUTHORS
XGreg Roelofs was responsible for the basic modifications to UnZip necessary
Xto create UnZipSFX. See \fIunzip\fP(1L) for the current list of zip-bugs
Xauthors, or the file CONTRIBS in the UnZip source distribution for the
Xfull list of Info-ZIP contributors.
X.PD
END_OF_FILE
if test 12523 -ne `wc -c <'unzip-5.12/unix/unzipsfx.1'`; then
echo shar: \"'unzip-5.12/unix/unzipsfx.1'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/unzipsfx.1'
fi
if test -f 'unzip-5.12/unshrink.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unshrink.c'\"
else
echo shar: Extracting \"'unzip-5.12/unshrink.c'\" \(17522 characters\)
sed "s/^X//" >'unzip-5.12/unshrink.c' <<'END_OF_FILE'
X#include "unzip.h"
X
X#ifdef NEW_UNSHRINK
X
X/*---------------------------------------------------------------------------
X
X unshrink.c version 0.94 26 Apr 94
X
X Shrinking is basically a dynamic LZW algorithm with allowed code sizes of
X up to 13 bits; in addition, there is provision for partial clearing of
X leaf nodes. PKWARE uses the special code 256 (decimal) to indicate a
X change in code size or a partial clear of the code tree: 256,1 for the
X former and 256,2 for the latter. See the notes in the code below about
X orphaned nodes after partial clearing.
X
X This replacement version of unshrink.c was written from scratch. It is
X based only on the algorithms described in Mark Nelson's _The Data Compres-
X sion Book_ and in Terry Welch's original paper in the June 1984 issue of
X IEEE _Computer_; no existing source code, including any in Nelson's book,
X was used.
X
X Memory requirements are fairly large. While the NODE struct could be mod-
X ified to fit in a single 64KB segment (as a "far" data structure), for now
X it is assumed that a flat, 32-bit address space is available. outbuf2 is
X always malloc'd, and flush() is always called with unshrink == FALSE.
X
X Copyright (C) 1994 Greg Roelofs. See the accompanying file "COPYING" in
X the UnZip 5.11 (or later) source distribution.


X
X ---------------------------------------------------------------------------*/
X
X

X/* #include "unzip.h" */
X
X#ifdef DEBUG
X# define OUTDBG(c) if ((c)=='\n') {PUTC('^',stderr); PUTC('J',stderr);}\
X else PUTC((c),stderr);
X#else
X# define OUTDBG(c)
X#endif
X
Xtypedef struct leaf {
X struct leaf *parent;
X struct leaf *next_sibling;
X struct leaf *first_child;
X uch value;
X} NODE;
X
Xstatic void partial_clear __((NODE *cursib));
X
Xstatic NODE *node, *bogusnode, *lastfreenode;
X
X
Xint unshrink()
X{
X#ifdef MACOS
X static uch *stacktop = NULL;
X#else
X static uch *stacktop = stack + 8192 - 1;
X#endif
X register uch *newstr;
X int codesize=9, code, oldcode=0, len, KwKwK;
X unsigned int outbufsiz;
X NODE *freenode, *curnode, *lastnode=node, *oldnode;
X
X
X/*---------------------------------------------------------------------------
X Initialize various variables.


X ---------------------------------------------------------------------------*/
X
X#ifdef MACOS

X if (stacktop == NULL) stacktop = stack + 8192 - 1;
X#endif
X
X if ((node = (NODE *)malloc(8192*sizeof(NODE))) == (NODE *)NULL)
X return PK_MEM3;
X bogusnode = node + 256;
X lastfreenode = node + 256;
X
X#ifndef SMALL_MEM /* always true, at least for now */
X /* non-memory-limited machines: allocate second (large) buffer for
X * textmode conversion in flush(), but only if needed */
X if (pInfo->textmode && !outbuf2 &&
X (outbuf2 = (uch *)malloc(TRANSBUFSIZ)) == (uch *)NULL)
X {
X free(node);
X return PK_MEM3;
X }
X#endif
X
X /* this stuff was an attempt to debug compiler errors(?) when had
X * node[8192] in union work area...no clues what was wrong (SGI worked)
X Trace((stderr, "\nsizeof(NODE) = %d\n", sizeof(NODE)));
X Trace((stderr, "sizeof(node) = %d\n", sizeof(node)));
X Trace((stderr, "sizeof(area) = %d\n", sizeof(area)));
X Trace((stderr, "address of node[0] = %d\n", (int)&node[0]));
X Trace((stderr, "address of node[6945] = %d\n", (int)&node[6945]));
X */
X
X for (code = 0; code < 256; ++code) {
X node[code].value = code;
X node[code].parent = bogusnode;
X node[code].next_sibling = &node[code+1];
X node[code].first_child = (NODE *)NULL;
X }
X node[255].next_sibling = (NODE *)NULL;
X for (code = 257; code < 8192; ++code)
X node[code].parent = node[code].next_sibling = (NODE *)NULL;
X
X outptr = outbuf;
X outcnt = 0L;
X if (pInfo->textmode)
X outbufsiz = RAWBUFSIZ;
X else
X outbufsiz = OUTBUFSIZ;
X
X/*---------------------------------------------------------------------------
X Get and output first code, then loop over remaining ones.
X ---------------------------------------------------------------------------*/
X
X READBITS(codesize, oldcode)
X if (!zipeof) {
X *outptr++ = (uch)oldcode;
X OUTDBG((uch)oldcode)
X if (++outcnt == outbufsiz) {
X flush(outbuf, outcnt, FALSE);
X outptr = outbuf;


X outcnt = 0L;
X }
X }
X

X do {
X READBITS(codesize, code)
X if (zipeof)
X break;
X if (code == 256) { /* GRR: possible to have consecutive escapes? */
X READBITS(codesize, code)
X if (code == 1) {
X ++codesize;
X Trace((stderr, " (codesize now %d bits)\n", codesize));
X } else if (code == 2) {
X Trace((stderr, " (partial clear code)\n"));
X#ifdef DEBUG
X fprintf(stderr, " should clear:\n");
X for (curnode = node+257; curnode < node+8192; ++curnode)
X if (!curnode->first_child)
X fprintf(stderr, "%d\n", curnode-node);
X fprintf(stderr, " did clear:\n");
X#endif
X partial_clear(node); /* recursive clear of leafs */
X lastfreenode = bogusnode; /* reset start of free-node search */
X }
X continue;
X }
X
X /*-----------------------------------------------------------------------
X Translate code: traverse tree from leaf back to root.
X -----------------------------------------------------------------------*/
X
X curnode = &node[code];
X newstr = stacktop;
X
X if (curnode->parent)
X KwKwK = FALSE;
X else {
X KwKwK = TRUE;
X Trace((stderr, " (found a KwKwK code %d; oldcode = %d)\n", code,
X oldcode));
X --newstr; /* last character will be same as first character */
X curnode = &node[oldcode];
X }
X
X do {
X *newstr-- = curnode->value;
X curnode = curnode->parent;
X } while (curnode != bogusnode);
X
X len = stacktop - newstr++;
X if (KwKwK)
X *stacktop = *newstr;
X
X /*-----------------------------------------------------------------------
X Write expanded string in reverse order to output buffer.
X -----------------------------------------------------------------------*/
X
X Trace((stderr, "code %4d; oldcode %4d; char %3d (%c); string [", code,
X oldcode, (int)(*newstr), *newstr));
X {
X register uch *p;
X
X for (p = newstr; p < newstr+len; ++p) {
X *outptr++ = *p;
X OUTDBG(*p)
X if (++outcnt == outbufsiz) {
X flush(outbuf, outcnt, FALSE);
X outptr = outbuf;
X outcnt = 0L;
X }
X }
X }
X
X /*-----------------------------------------------------------------------
X Add new leaf (first character of newstr) to tree as child of oldcode.
X -----------------------------------------------------------------------*/
X
X /* search for freenode */
X freenode = lastfreenode + 1;
X while (freenode->parent) /* add if-test before loop for speed? */
X ++freenode;
X lastfreenode = freenode;
X Trace((stderr, "]; newcode %d\n", freenode-node));
X
X oldnode = &node[oldcode];
X if (!oldnode->first_child) { /* no children yet: add first one */
X if (!oldnode->parent) {
X /*
X * oldnode is itself a free node: the only way this can happen
X * is if a partial clear occurred immediately after oldcode was
X * received and therefore immediately before this step (adding
X * freenode). This is subtle: even though the parent no longer
X * exists, it is treated as if it does, and pointers are set as
X * usual. Thus freenode is an orphan, *but only until the tree
X * fills up to the point where oldnode is reused*. At that
X * point the reborn oldnode "adopts" the orphaned node. Such
X * wacky guys at PKWARE...
X *
X * To mark this, we set oldnode->next_sibling to point at the
X * bogus node (256) and then check for this in the freenode sec-
X * tion just below.
X */
X Trace((stderr, " [%d's parent (%d) was just cleared]\n",
X freenode-node, oldcode));
X oldnode->next_sibling = bogusnode;
X }
X oldnode->first_child = freenode;
X } else {
X curnode = oldnode->first_child;
X while (curnode) { /* find last child in sibling chain */
X lastnode = curnode;
X curnode = curnode->next_sibling;
X }
X lastnode->next_sibling = freenode;
X }
X freenode->value = *newstr;
X freenode->parent = oldnode;
X if (freenode->next_sibling != bogusnode) /* no adoptions today... */
X freenode->first_child = (NODE *)NULL;
X freenode->next_sibling = (NODE *)NULL;
X
X oldcode = code;
X } while (!zipeof);
X
X/*---------------------------------------------------------------------------
X Flush any remaining data, free malloc'd space and return to sender...
X ---------------------------------------------------------------------------*/
X
X if (outcnt > 0L)
X flush(outbuf, outcnt, FALSE);
X
X free(node);
X return PK_OK;
X
X} /* end function unshrink() */


X
X
X
X
X

Xstatic void partial_clear(cursib) /* like, totally recursive, eh? */
X NODE *cursib;
X{
X NODE *lastsib=(NODE *)NULL;
X
X /* Loop over siblings, removing any without children; recurse on those
X * which do have children. This hits even the orphans because they're
X * always adopted (parent node is reused) before tree becomes full and
X * needs clearing.
X */
X do {
X if (cursib->first_child) {
X partial_clear(cursib->first_child);
X lastsib = cursib;
X } else if ((cursib - node) > 256) { /* no children (leaf): clear it */
X Trace((stderr, "%d\n", cursib-node));
X if (!lastsib)
X cursib->parent->first_child = cursib->next_sibling;
X else
X lastsib->next_sibling = cursib->next_sibling;
X cursib->parent = (NODE *)NULL;
X }
X cursib = cursib->next_sibling;
X } while (cursib);


X return;
X}
X
X

X
X#else /* !NEW_UNSHRINK */


X
X
X
X/*---------------------------------------------------------------------------
X

X unshrink.c
X
X Shrinking is a dynamic Lempel-Ziv-Welch compression algorithm with partial
X clearing. Sadly, it uses more memory than any of the other algorithms (at
X a minimum, 8K+8K+16K, assuming 16-bit short ints), and this does not even
X include the output buffer (the other algorithms leave the uncompressed data
X in the work area, typically called slide[]). For machines with a 64KB data
X space, this is a problem, particularly when text conversion is required and
X line endings have more than one character. UnZip's solution is to use two
X roughly equal halves of outbuf for the ASCII conversion in such a case; the
X "unshrink" argument to flush() signals that this is the case.
X
X For large-memory machines, a second outbuf is allocated for translations,
X but only if unshrinking and only if translations are required.
X
X | binary mode | text mode
X ---------------------------------------------------
X big mem | big outbuf | big outbuf + big outbuf2 <- malloc'd here
X small mem | small outbuf | half + half small outbuf
X
X This version contains code which is copyright (C) 1989 Samuel H. Smith.
X See the accompanying file "COPYING" in the UnZip 5.11 (or later) source
X distribution.


X
X ---------------------------------------------------------------------------*/
X
X

X/* #include "unzip.h" */
X
X/* MAX_BITS 13 (in unzip.h; defines size of global work area) */
X#define INIT_BITS 9
X#define FIRST_ENT 257
X#define CLEAR 256
X
X#define OUTB(c) {\
X *outptr++=(uch)(c);\
X if (++outcnt==outbufsiz) {\
X flush(outbuf,outcnt,TRUE);\
X outcnt=0L;\
X outptr=outbuf;\
X }\
X}
X
Xstatic void partial_clear __((void));
X
Xint codesize, maxcode, maxcodemax, free_ent;


X
X
X
X
X/*************************/

X/* Function unshrink() */
X/*************************/
X
Xint unshrink() /* return PK-type error code */
X{
X register int code;
X register int stackp;
X int finchar;
X int oldcode;
X int incode;
X unsigned int outbufsiz;
X
X
X /* non-memory-limited machines: allocate second (large) buffer for
X * textmode conversion in flush(), but only if needed */
X#ifndef SMALL_MEM
X if (pInfo->textmode && !outbuf2 &&
X (outbuf2 = (uch *)malloc(TRANSBUFSIZ)) == (uch *)NULL)
X return PK_MEM3;
X#endif
X
X outptr = outbuf;
X outcnt = 0L;
X if (pInfo->textmode)
X outbufsiz = RAWBUFSIZ;
X else
X outbufsiz = OUTBUFSIZ;
X
X /* decompress the file */
X codesize = INIT_BITS;
X maxcode = (1 << codesize) - 1;
X maxcodemax = HSIZE; /* (1 << MAX_BITS) */
X free_ent = FIRST_ENT;
X
X code = maxcodemax;
X/*
X OvdL: -Ox with SCO's 3.2.0 cc gives
X a. warning: overflow in constant multiplication
X b. segmentation fault (core dumped) when using the executable
X for (code = maxcodemax; code > 255; code--)
X prefix_of[code] = -1;
X */
X do {
X prefix_of[code] = -1;
X } while (--code > 255);
X
X for (code = 255; code >= 0; code--) {
X prefix_of[code] = 0;
X suffix_of[code] = (uch)code;
X }
X
X READBITS(codesize,oldcode) /* ; */
X if (zipeof)
X return PK_COOL;
X finchar = oldcode;
X
X OUTB(finchar)
X
X stackp = HSIZE;
X
X while (!zipeof) {
X READBITS(codesize,code) /* ; */
X if (zipeof) {
X if (outcnt > 0L)
X flush(outbuf, outcnt, TRUE); /* flush last, partial buffer */


X return PK_COOL;
X }
X

X while (code == CLEAR) {
X READBITS(codesize,code) /* ; */
X switch (code) {
X case 1:
X codesize++;
X if (codesize == MAX_BITS)
X maxcode = maxcodemax;
X else
X maxcode = (1 << codesize) - 1;
X break;
X
X case 2:
X partial_clear();
X break;
X }
X
X READBITS(codesize,code) /* ; */
X if (zipeof) {
X if (outcnt > 0L)
X flush(outbuf, outcnt, TRUE); /* partial buffer */
X return PK_COOL;
X }
X }
X
X
X /* special case for KwKwK string */
X incode = code;
X if (prefix_of[code] == -1) {
X stack[--stackp] = (uch)finchar;
X code = oldcode;
X }
X /* generate output characters in reverse order */
X while (code >= FIRST_ENT) {
X if (prefix_of[code] == -1) {
X stack[--stackp] = (uch)finchar;
X code = oldcode;
X } else {
X stack[--stackp] = suffix_of[code];
X code = prefix_of[code];
X }
X }
X
X finchar = suffix_of[code];
X stack[--stackp] = (uch)finchar;
X
X
X /* and put them out in forward order, block copy */
X if ((HSIZE - stackp + outcnt) < outbufsiz) {
X /* GRR: this is not necessarily particularly efficient:
X * typically output only 2-5 bytes per loop (more
X * than a dozen rather rare?) */
X memcpy(outptr, &stack[stackp], HSIZE - stackp);
X outptr += HSIZE - stackp;
X outcnt += HSIZE - stackp;
X stackp = HSIZE;
X }
X /* output byte by byte if we can't go by blocks */
X else
X while (stackp < HSIZE)
X OUTB(stack[stackp++])
X
X
X /* generate new entry */
X code = free_ent;
X if (code < maxcodemax) {
X prefix_of[code] = oldcode;
X suffix_of[code] = (uch)finchar;
X
X do
X code++;
X while ((code < maxcodemax) && (prefix_of[code] != -1));
X
X free_ent = code;
X }
X /* remember previous code */
X oldcode = incode;
X }
X
X /* never reached? */
X /* flush last, partial buffer */
X if (outcnt > 0L)
X flush(outbuf, outcnt, TRUE);
X
X return PK_OK;
X
X} /* end function unshrink() */
X
X
X
X/******************************/
X/* Function partial_clear() */
X/******************************/
X
Xstatic void partial_clear()
X{
X register int pr;
X register int cd;
X
X /* mark all nodes as potentially unused */
X for (cd = FIRST_ENT; cd < free_ent; cd++)
X prefix_of[cd] |= 0x8000;
X
X /* unmark those that are used by other nodes */
X for (cd = FIRST_ENT; cd < free_ent; cd++) {
X pr = prefix_of[cd] & 0x7fff; /* reference to another node? */
X if (pr >= FIRST_ENT) /* flag node as referenced */
X prefix_of[pr] &= 0x7fff;
X }
X
X /* clear the ones that are still marked */
X for (cd = FIRST_ENT; cd < free_ent; cd++)
X if ((prefix_of[cd] & 0x8000) != 0)
X prefix_of[cd] = -1;
X
X /* find first cleared node as next free_ent */
X cd = FIRST_ENT;
X while ((cd < maxcodemax) && (prefix_of[cd] != -1))
X cd++;
X free_ent = cd;
X}
X
X
X#endif /* ?NEW_UNSHRINK */
END_OF_FILE
if test 17522 -ne `wc -c <'unzip-5.12/unshrink.c'`; then
echo shar: \"'unzip-5.12/unshrink.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unshrink.c'
fi
echo shar: End of archive 15 \(of 20\).
cp /dev/null ark15isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:50 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 81
Archive-name: unzip/part16

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/README unzip-5.12/amiga/flate.a
# unzip-5.12/atari/Makefile unzip-5.12/mac/macunzip.c
# unzip-5.12/unzipsfx.doc unzip-5.12/vms/unzipsfx.hlp
# unzip-5.12/vms/vms.h
# Wrapped by kent@sparky on Sat Sep 17 23:33:46 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 16 (of 20)."'
if test -f 'unzip-5.12/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/README'\"
else
echo shar: Extracting \"'unzip-5.12/README'\" \(9076 characters\)
sed "s/^X//" >'unzip-5.12/README' <<'END_OF_FILE'
XThis is the README file for the 28 August 1994 public release of the
XInfo-ZIP group's portable UnZip zipfile-extraction program (and related
Xutilities).
X
Xunzip512.zip portable UnZip, version 5.12, source code distribution
Xunzip512.tar.Z same as above, but compress'd tar format
X
X__________________________________________________________________________
X
XBEFORE YOU ASK: UnZip, its companion utility Zip, and related utilities
Xand support files can be found in many places; read the file "Where" for
Xfurther details. To contact the authors with suggestions, bug reports,
Xor fixes, continue reading this file (README) and, if this is part of a
Xsource distribution, the file "ZipPorts". Also in source distributions:
Xread "BUGS" for a list of known bugs, non-bugs and possible future bugs;
XINSTALL for instructions on how to build UnZip; and "Contents" for a com-
Xmented listing of all the distributed files.
X
XALSO NOTE: Info-ZIP's mailing addresses changed between UnZip 5.0p1 and
X5.1 releases (and since Zip 2.0.1)! The old BITNET address doesn't even
Xexist anymore. See below.
X__________________________________________________________________________
X
X
XGENERAL INFO
X------------
XUnZip is an extraction utility for archives compressed in .zip format (also
Xcalled "zipfiles"). Although highly compatible both with PKWARE's PKZIP
Xand PKUNZIP utilities for MS-DOS and with Info-ZIP's own Zip program, our
Xprimary objectives have been portability and non-MSDOS functionality.
X
XThis version of UnZip has been ported to a wide array of hardware--from
Xmicros to supercomputers--and operating systems: Unix (many flavors),
XVMS, OS/2, MSDOS (+ Windows), NT, TOPS-20 (partly), AmigaDOS, Atari TOS,
XMacintosh and Human68k. UnZip features not found in PKUNZIP include source
Xcode; default extraction of directory trees (with a switch to defeat this,
Xrather than the reverse); VMS, Macintosh and OS/2 extended file attributes;
Xand, of course, the ability to run under most of your favorite operating
Xsystems. Plus, it's free. :-)
X
XFor source distributions, see the main Contents file for a list of what's
Xincluded, and read INSTALL for instructions on compiling (including OS-
Xspecific comments). The individual operating systems' Contents files (for
Xexample, vms/Contents) may list important compilation info in addition to
Xexplaining what files are what, so be sure to read them. Some of the ports
Xhave their own, special README files, so be sure to look for those, too.
X
XSee unzip.1 or unzip.doc for usage (or the corresponding UnZipSFX, ZipInfo
Xand fUnZip docs). For VMS, unzip_def.rnh or unzip_cli.help may be compiled
Xinto unzip.hlp and installed as a normal VMS help entry; see vms/descrip.mms.
X
X
XCHANGES AND NEW FEATURES
X------------------------
XThe 5.12 release mainly fixes some bugs in 5.11, including a silly pointer
Xerror in unzipsfx. The only new features are fairly minor:
X
X - ZipInfo check for dead space inside archives (PKZIP/Netware bug)
X - SFX_EXDIR compilation option to allow -d <exdir> with UnZipSFX
X - "unzip -vqqqq" prints just the version number (e.g., "512")
X
XSince neither 5.11 nor 5.1 was posted to Usenet, here's a summary of their
Xnew features. In UnZip 5.11:
X
X - UnZipSFX, a self-extraction stub for prepending to (new-style) zipfiles
X (tested under Unix, VMS, MS-DOS, OS/2, etc.; NOT portable *across* OSes)
X - unshrink() rewritten to avoid copyright problems; 32-bit version only
X - strings moved to far memory in MS-DOS: can use small model again (MSC)
X - numerous customization options (see INSTALL)
X - diagnostic screen with -v option and no zipfile (i.e., "unzip -v")
X - -C option for case-insensitive filename matching (esp. for MS-DOS, OS/2)
X - more bad-zipfile "intelligence" (can sometimes even extract concatenated
X multi-part archives)
X - former -U behavior is now the default; new -L option to provide what was
X the default behavior (auto-conversion of uppercase-OS filenames to lower
X case)
X - ZipInfo -T option to print times in decimal format (yymmdd.hhmmss) for
X piping into sort(1)
X - performance tweaks for listing archive contents
X - improved/expanded documentation, esp. man pages (*.doc files) and INSTALL
X
XIn UnZip 5.1:
X
X - wildcard zipfiles (e.g., "unzip -tq \*.zip")
X - extract to a directory other than the current one (-d <exdir> option)
X - auto-conversion of text files
X - ANSI sequences disabled in comments and filenames (avoid "ANSI bombs")
X - ZipInfo incorporated into UnZip (-Z option)
X - full Amiga, Atari, Mac, NT and Human68K support (partial TOPS-20)
X - performance tuning for 35-70% faster extraction (depends on compression
X method)
X
XNote that, according to one tester, the 32-bit MS-DOS version is now *faster*
Xthan PKUNZIP on most archives! Cool.
X
X
XDISTRIBUTION
X------------
XIf you have a question regarding redistribution of Info-ZIP software,
Xeither as-is, as packaging for a commercial product, or as an integral
Xpart of a commercial product, read the Frequently Asked Questions (FAQ)
Xsection of the included COPYING file.
X
XInsofar as C compilers are rare on some platforms and the authors only
Xhave direct access to Unix, VMS, OS/2, MS-DOS, Mac, Amiga and Atari
Xsystems, others may wish to provide ready-to-run executables for new
Xsystems. In general there is no problem with this; we require only that
Xsuch distributions include this README file, the Where file, the COPYING
Xfile (contains copyright/redistribution information), and the appropriate
Xdocumentation files (unzip.doc and/or unzip.1 for UnZip, etc.). If the
Xlocal system provides a way to make self-extracting archives in which both
Xthe executables and text files may be stored together, that is best (in
Xparticular, use UnZipSFX if at all possible, even if it's a few kilobytes
Xbigger than the alternatives); otherwise we suggest a bare UnZip executable
Xand a separate zipfile containing the remaining text and binary files. If
Xanother archiving method is in common use on the target system (for example,
XZoo or LHa), that may also be used.
X
X
XBUGS AND NEW PORTS: CONTACTING INFO-ZIP
X----------------------------------------
XAll bug reports and patches (context diffs only, please!) should go to
Xzip...@wkuvx1.wku.edu, which is the e-mail address for the Info-ZIP
Xauthors. "Dumb questions" which aren't adequately answered in the docu-
Xmentation should also be directed here rather than to a global forum such
Xas Usenet. (Kindly make certain that your questions *isn't* answered by
Xthe documentation, however--a great deal of effort has gone into making
Xit clear and complete.) Suggestions for new features can be sent to
Xinf...@wkuvx1.wku.edu, a mailing list for the Info-ZIP beta testers,
Xfor discussion (the authors hang out here as well, of course), although
Xwe don't promise to act on all suggestions. If it is something which is
Xmanifestly useful, sending the required patches to zip-bugs directly (as
Xper the instructions in the ZipPorts file) is likely to produce a quicker
Xresponse than asking us to do it--the authors are always somewhat short
Xon time. (Please do NOT send patches or encoded zipfiles to the info-zip
Xaddress.)
X
XIf you are considering a port, not only should you read the ZipPorts file,
Xbut also please check in with zip-bugs BEFORE getting started, since the
Xcode is constantly being updated behind the scenes. For example, an Acorn/
XArchimedes port is already almost complete, as is an OS/2 dynamic link lib-
Xrary (DLL) version; VMOS, VM/CMS, Netware, QDOS and NT DLL ports are claimed
Xto be under construction, although we have yet to see any up-to-date patches.
XWe will arrange to send you the latest sources. The alternative is the pos-
Xsibility that your hard work will be tucked away in a sub-archive and mostly
Xignored, or completely ignored if someone else has already done the port
X(and you'd be surprised how often this has happened). IBM mainframe ports
X(VM/CMS and/or MVS) would be particularly welcome. (It can't be *that* hard,
Xfolks...the VMS filesystem is similar in many ways.)
X
X
XBETA TESTING: JOINING INFO-ZIP
X-------------------------------
XIf you'd like to keep up to date with our UnZip (and companion Zip utility)
Xdevelopment, join the ranks of beta testers, add your own thoughts and con-
Xtributions, etc., send a two-line mail message containing the commands HELP
Xand LIST (on separate lines in the body of the message, not on the subject
Xline) to mxse...@wkuvx1.wku.edu. You'll receive two messages listing the
Xvarious Info-ZIP mailing-list formats which are available (and also various
Xunrelated lists) and instructions on how to subscribe to one or more of them
X(courtesy of Hunter Goatley). As of mid-1994, subscribing to the announce-
Xments list requires a command of the form
X
X SUBSCRIBE Info-ZIP-announce "Joe Isuzu"
X
XThe discussion list is called either Info-ZIP or Info-ZIP-digest, depending
Xon one's preference for delivery.
X
X
X-- Greg Roelofs (Cave Newt), UnZip maintainer/container/explainer and
X developer guy, with inspiration from David Kirschbaum
END_OF_FILE
if test 9076 -ne `wc -c <'unzip-5.12/README'`; then
echo shar: \"'unzip-5.12/README'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/README'
fi
if test -f 'unzip-5.12/amiga/flate.a' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/flate.a'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/flate.a'\" \(8802 characters\)
sed "s/^X//" >'unzip-5.12/amiga/flate.a' <<'END_OF_FILE'
X; Not copyrighted by Paul Kienitz, 20 Jun 94.
X;
X; Assembly language version of inflate_codes(), for Amiga. Prototype:
X;
X; int flate_codes(struct huft *tl, struct huft *td, int bl, int bd,
X; unsigned char *slide);
X;
X; It is called by defining inflate_codes(tl, td, bl, bd) as
X; flate_codes(tl, td, bl, bd, slide).
X;
X; Define the symbol FUNZIP if this is for fUnZip. Define CRYPT if this is
X; for fUnZip with decryption enabled. Define AZTEC to use the Aztec C
X; buffered input macro instead of the library getc() with FUNZIP.
X;
X; => int MUST BE 16 BITS!!! <= => WSIZE MUST BE 32K! <=
X;
X; struct huft is defined as follows:
X;
X; struct huft {


X; uch e; /* number of extra bits or operation */
X; uch b; /* number of bits in this code or subcode */
X; union {
X; ush n; /* literal, length base, or distance base */
X; struct huft *t; /* pointer to next level of table */
X; } v;

X; }; /* sizeof(struct huft) == 6 */
X;
X; so here we define the offsets of the various members of this struct:
X
Xh_e equ 0
Xh_b equ 1
Xh_n equ 2
Xh_t equ 2
XSIZEOF_HUFT equ 6
X
X; There are several global variables we need to access. Their definitions:
X;
X; unsigned long bb;
X; unsigned int bk, wp;
X; unsigned short mask[17];
X; FILE *in;
X; int encrypted; /* FUNZIP CRYPT only */
X;
X; int incnt, mem_mode; /* non-FUNZIP only */
X; long csize; /* non-FUNZIP only */
X; unsigned long outcnt; /* non-FUNZIP only */
X; unsigned char *inptr; /* non-FUNZIP only */
X;
X; bb is the global buffer that holds bits from the huffman code stream, which
X; we cache in the register variable b. bk is the number of valid bits in it,
X; which we cache in k. The macros NEEDBITS(n) and DUMPBITS(n) have side effects
X; on b and k.
X
X xref _bb
X xref _bk
X xref _mask
X xref _wp
X IFD FUNZIP
X IFD CRYPT
X xref _encrypted
X xref _update_keys ; int update_keys(int)
X xref _decrypt_byte ; int decrypt_byte(void)
X ENDC ; CRYPT
X xref _in
X xref _getc ; int getc(FILE *)
X ELSE ; !FUNZIP
X xref _csize
X xref _incnt
X xref _mem_mode
X xref _inptr
X xref _readbyte ; int readbyte(void)
X ENDC
X xref _flush ; if FUNZIP: int flush(unsigned long)
X ; ...if !FUNZIP: int flush(unsigned char *, unsigned long *, int)
X
X; Here are our register variables. Remember that int == short!
X
Xb equr d2 ; unsigned long
Xk equr d3 ; unsigned int <= 32
Xe equr d4 ; unsigned int < 256 for most use
Xw equr d5 ; unsigned int
Xn equr d6 ; unsigned int
Xd equr d7 ; unsigned int
X
X; assert: we always maintain w and d as valid unsigned longs.
X
Xt equr a2 ; struct huft *
Xslide equr a3 ; unsigned char *
Xmask equr a6 ; unsigned short *
X
X; Couple other items we need:
X
Xsavregs reg d2-d7/a2/a3/a6
X
XWSIZE equ $8000 ; 32k... be careful not to treat as negative!
X
X IFD FUNZIP
X; This does getc(in). Aztec version is based on #define getc(fp) in stdio.h
X
X IFD AZTEC
X xref __filbuf
XGETC MACRO
X move.l _in,a0
X move.l (a0),a1 ; in->_bp
X cmp.l 4(a0),a1 ; in->_bend
X blo.s gci\@
X move.l a0,-(sp)
X jsr __filbuf
X addq #4,sp
X bra.s gce\@
Xgci\@: moveq #0,d0 ; must be valid as longword
X move.b (a1)+,d0
X move.l a1,(a0)
Xgce\@:
X ENDM
X ELSE ; !AZTEC
XGETC MACRO
X move.l _in,-(sp)
X jsr _getc
X addq #4,sp
X ENDM
X ENDC ; AZTEC
X ENDC ; FUNZIP
X
X; Input depends on the NEXTBYTE macro. This exists in three different forms.
X; The first two are for fUnZip, with and without decryption. The last is for
X; regular UnZip with or without decryption. The resulting byte is returned
X; in d0 as a longword, and d1, a0, and a1 are clobbered.
X
X IFD FUNZIP
X IFD CRYPT
XNEXTBYTE MACRO
X GETC
X tst.w _encrypted
X beq.s nbe\@
X move.w d0,-(sp) ; save thru next call
X jsr _decrypt_byte
X eor.w d0,(sp) ; becomes arg to update_keys
X jsr _update_keys
X addq #2,sp
Xnbe\@: ext.l d0 ; assert -1 <= d0 <= 255
X ENDM
X ELSE ; !CRYPT
XNEXTBYTE MACRO
X GETC ; nothing else in this case
X ENDM
X ENDC
X ELSE ; !FUNZIP
XNEXTBYTE MACRO
X subq.l #1,_csize
X bge.s nbg\@
X moveq #-1,d0 ; return EOF
X bra.s nbe\@
Xnbg\@: subq.w #1,_incnt
X bge.s nbs\@
X jsr _readbyte
X bra.s nbe\@
Xnbs\@: moveq #0,d0
X move.l _inptr,a0
X move.b (a0)+,d0
X move.l a0,_inptr
Xnbe\@:
X ENDM
X ENDC
X
X; FLUSH has different versions for fUnZip and UnZip. Arg must be a longword.
X
X IFD FUNZIP
XFLUSH MACRO
X move.l \1,-(sp)
X jsr _flush
X addq #4,sp
X ENDM
X ELSE ; !FUNZIP
X xref _mem_mode
X xref _outcnt
XFLUSH MACRO
X tst.w _mem_mode
X bne.s fm\@
X move.w #0,-(sp) ; unshrink flag: always false
X move.l \1,-(sp) ; length
X move.l slide,-(sp) ; buffer to flush
X jsr _flush
X lea 10(sp),sp
X bra.s fe\@
Xfm\@: move.l w,_outcnt
Xfe\@:
X ENDM
X ENDC ; FUNZIP
X
X; Here are the two bit-grabbing macros, defined in their non-CHECK_EOF form:
X;
X; define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}}
X; define DUMPBITS(n) {b>>=(n);k-=(n);}
X;
X; NEEDBITS clobbers d0, d1, a0, and a1, none of which can be used as the arg
X; to the macro specifying the number of bits. The arg can be a shortword memory
X; address, or d2-d7. The result is copied into d1 as a word ready for masking.
X; DUMPBITS has no side effects; the arg must be a d-register (or immediate in the
X; range 1-8?) and only the lower byte is significant.
X
XNEEDBITS MACRO
Xnb\@: cmp.w \1,k ; assert 0 < k <= 32 ... arg may be 0
X bhs.s ne\@
X NEXTBYTE ; returns in d0.l
X lsl.l k,d0
X or.l d0,b
X addq.w #8,k
X bra.s nb\@
Xne\@: move.w b,d1
X ENDM
X
XDUMPBITS MACRO
X lsr.l \1,b ; upper bits of \1 are ignored??
X sub.b \1,k
X ENDM
X
X
X; ******************************************************************************
X; Here we go, finally:
X
X xdef _flate_codes ; (pointer, pointer, int, int, pointer)
X
X_flate_codes:
X link a5,#-4
X movem.l savregs,-(sp)
X; 8(a5) = tl, 12(a5) = td, 16(a5) = bl, 18(a5) = bd, 20(a5) = slide,
X; -2(a5) = ml, -4(a5) = md. Here we cache some globals and args:
X move.l 20(a5),slide
X lea _mask,mask
X move.l _bb,b
X move.w _bk,k
X moveq #0,w ; keep this usable as longword
X move.w _wp,w
X moveq #0,e ; keep this usable as longword too
X move.w 16(a5),d0
X add.w d0,d0
X move.w (mask,d0.w),-2(a5) ; ml = mask[bl]
X move.w 18(a5),d0
X add.w d0,d0
X move.w (mask,d0.w),-4(a5) ; md = mask[bd]
X
Xmain_loop:
X NEEDBITS 16(a5) ; bl
X and.w -2(a5),d1 ; ml
X mulu #SIZEOF_HUFT,d1
X move.l 8(a5),a0 ; tl
X lea (a0,d1.l),t
X move.b h_e(t),e
X cmp.w #16,e
X bls.s topdmp
Xintop: moveq #1,d0
X cmp.w #99,e
X beq return ; error in zipfile
X move.b h_b(t),d0
X DUMPBITS d0
X sub.w #16,e
X NEEDBITS e
X move.w e,d0
X add.w d0,d0
X and.w (mask,d0.w),d1
X mulu #SIZEOF_HUFT,d1
X move.l h_t(t),a0
X lea (a0,d1.l),t
X move.b h_e(t),e
X cmp.w #16,e
X bgt.s intop
Xtopdmp: move.b h_b(t),d0
X DUMPBITS d0
X
X cmp.w #16,e ; is this huffman code a literal?
X bne lenchk ; no
X move.w h_n(t),d0 ; yes
X move.b d0,(slide,w.l) ; stick in the decoded byte
X addq.w #1,w
X cmp.w #WSIZE,w
X blo main_loop
X FLUSH w
X moveq #0,w
X bra main_loop ; do some more
X
Xlenchk: cmp.w #15,e ; is it an end-of-block code?
X beq finish ; if yes, we're done
X NEEDBITS e ; no: we have a duplicate string
X move.w e,d0
X add.w d0,d0
X and.w (mask,d0.w),d1
X move.w h_n(t),n
X add.w d1,n ; length of block to copy
X DUMPBITS e
X NEEDBITS 18(a5) ; bd
X and.w -4(a5),d1 ; md
X mulu #SIZEOF_HUFT,d1
X move.l 12(a5),a0 ; td
X lea (a0,d1.l),t
X move.b h_e(t),e
X cmp.w #16,e
X bls.s middmp
Xinmid: moveq #1,d0
X cmp.w #99,e
X beq return ; error in zipfile
X move.b h_b(t),d0
X DUMPBITS d0
X sub.w #16,e
X NEEDBITS e
X move.w e,d0
X add.w d0,d0
X and.w (mask,d0.w),d1
X mulu #SIZEOF_HUFT,d1
X move.l h_t(t),a0
X lea (a0,d1.l),t
X move.b h_e(t),e
X cmp.w #16,e
X bgt.s inmid
Xmiddmp: move.b h_b(t),d0
X DUMPBITS d0
X NEEDBITS e
X move.w e,d0
X add.w d0,d0
X and.w (mask,d0.w),d1
X move.l w,d
X sub.w h_n(t),d
X sub.w d1,d ; distance back to block to copy
X DUMPBITS e
X
Xindup: move.w #WSIZE,e ; violate the e < 256 rule
X and.w #WSIZE-1,d
X cmp.w d,w
X blo.s ddgw
X sub.w w,e
X bra.s dadw
Xddgw: sub.w d,e
Xdadw: cmp.w n,e
X bls.s delen
X move.w n,e
Xdelen: sub.w e,n ; size of sub-block to copy
X move.l slide,a0
X move.l a0,a1
X add.l w,a0 ; w and d are valid longwords
X add.l d,a1
X move.w e,d0
X subq #1,d0 ; assert >= 0 if sign extended
Xdspin: move.b (a1)+,(a0)+ ; string is probably short, so
X dbra d0,dspin ; don't use any fancier copy method
X add.w e,w
X add.w e,d
X cmp.w #WSIZE,w
X blo.s dnfl
X FLUSH w
X moveq #0,w
Xdnfl: tst.w n ; need to do more sub-blocks?
X bne indup ; yes
X moveq #0,e ; restore zeroness in upper bytes
X bra main_loop ; do some more
X
Xfinish: move.w w,_wp ; restore cached globals
X move.w k,_bk
X move.l b,_bb
X moveq #0,d0 ; return "no error"
Xreturn: movem.l (sp)+,savregs
X unlk a5
X rts
END_OF_FILE
if test 8802 -ne `wc -c <'unzip-5.12/amiga/flate.a'`; then
echo shar: \"'unzip-5.12/amiga/flate.a'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/flate.a'
fi
if test -f 'unzip-5.12/atari/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/atari/Makefile'\"
else
echo shar: Extracting \"'unzip-5.12/atari/Makefile'\" \(4811 characters\)
sed "s/^X//" >'unzip-5.12/atari/Makefile' <<'END_OF_FILE'
X#==============================================================================
X# Makefile for UnZip, UnZipSFX & fUnZip: Atari ST Chris Herborth
X# Version: UnZip 5.11, MiNT, GNU C 14 July 1994
X#==============================================================================
X
X# Based on the original unix Makefile and modified by Chris Herborth
X# (cher...@semprini.waterloo-rdp.on.ca), Nov.13/93.
X#
X# $Id: Makefile 1.7 1993/12/28 18:52:52 root Exp $
X
X# Be sure to test your new UnZip (and UnZipSFX and fUnZip); successful com-
X# pilation does not always imply a working program.


X
X
X#####################
X# MACRO DEFINITIONS #
X#####################
X
X# Defaults most systems use (use LOCAL_UNZIP in environment to add flags,
X# such as -DDOSWILD).
X
X# UnZip flags

X# NOTE: 'cgcc' is my cross-compiler; you'll probably use 'gcc' instead.
XCC = cgcc
XLD = cgcc
XLOC = $(LOCAL_UNZIP) -ansi -D__MINT__ -U__STRICT_ANSI__
X
XCF = -mbaserel -mpcrel -O2 -fomit-frame-pointer -I. $(LOC)
X# CF = -O -I. $(LOC)
X# CF = -mbaserel -O -I. $(LOC)
XLF = -mbaserel -mpcrel -o unzip.ttp
XLF2 = -s -lbiio
X
X# UnZipSFX flags
XXC = -DSFX
XXL = -mbaserel -mpcrel -o unzipsfx.ttp
XXL2 = $(LF2)
X
X# fUnZip flags
XFC = -DFUNZIP
XFL = -mbaserel -mpcrel -o funzip.ttp


XFL2 = $(LF2)
X
X# general-purpose stuff
XCP = cp

XLN = ln -s
XRM = rm -f
XE = .ttp
XO = .o
XM = atari


XSHELL = /bin/sh
X
X# object files
XOBJS1 = unzip$O crypt$O envargs$O explode$O extract$O file_io$O
XOBJS2 = inflate$O match$O unreduce$O unshrink$O zipinfo$O
XOBJS = $(OBJS1) $(OBJS2) $M$O
XLOBJS = $(OBJS)

XOBJX = unzip_$O crypt$O extract_$O file_io$O inflate$O match$O $M_$O


XOBJF = funzip$O crypt_$O inflate_$O

X
X# installation
XINSTALL = cp# probably can change this to 'install' if you have it
X# on some systems, manext=l and MANDIR=/usr/man/man$(manext) may be appropriate
Xmanext = 1

XMANDIR = /usr/local/man/man$(manext)# where to install man pages
XBINDIR = /usr/local/bin# where to install executables
X#
XUNZIPS = unzip$E unzipsfx$E funzip$E zipinfo$E
XMANS = unzip.$(manext) unzipsfx.$(manext) zipinfo.$(manext) funzip.$(manext)


XDOCS = unzip.doc unzipsfx.doc zipinfo.doc funzip.doc

X# this is a little ugly...

XINSTALLED = $(BINDIR)/unzip$E $(BINDIR)/zipinfo$E $(BINDIR)/funzip$E \
X $(BINDIR)/unzipsfx$E $(MANDIR)/unzipsfx.$(manext) \
X $(MANDIR)/unzip.$(manext) $(MANDIR)/zipinfo.$(manext) \
X $(MANDIR)/funzip.$(manext)


X
X###############################################
X# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES #
X###############################################
X

X.c$O:
X $(CC) -c $(CF) $*.c
X
X

Xall: unzips


Xunzips: $(UNZIPS)
Xdocs: $(DOCS)
Xunzipsman: unzips docs
Xunzipsdocs: unzips docs
X
X

Xclean:
X rm -f $(OBJS) $(OBJF) $(OBJX) $(UNZIPS)
X
Xinstall: $(UNZIPS) $(MANS)
X $(INSTALL) $(UNZIPS) $(BINDIR)

X $(LN) $(BINDIR)/unzip$E $(BINDIR)/zipinfo$E
X $(INSTALL) unix/unzip.1 $(MANDIR)/unzip.$(manext)
X $(INSTALL) unix/unzipsfx.1 $(MANDIR)/unzipsfx.$(manext)
X $(INSTALL) unix/zipinfo.1 $(MANDIR)/zipinfo.$(manext)
X $(INSTALL) unix/funzip.1 $(MANDIR)/funzip.$(manext)
X

X# alternatively, could use zip method: -cd $(BINDIR); rm -f $(UNZIPS) [etc.]
Xuninstall:

X rm -f $(INSTALLED)
X
X
Xunzip$E: $(OBJS) # add `&' if parallel makes supported


X $(LD) $(LF) $(LOBJS) $(LF2)
X

Xunzipsfx$E: $(OBJX) # add `&' if parallel makes supported
X $(LD) $(XL) $(OBJX) $(XL2)
X
Xfunzip$E: $(OBJF) # add `&' if parallel makes supported


X $(LD) $(FL) $(OBJF) $(FL2)
X
Xzipinfo$E: unzip$E
X @echo\

X ' This is a Unix-inspired target. If your filesystem does not support'
X @echo\
X ' symbolic links, copy unzip.ttp to zipinfo.ttp rather than linking it,'
X @echo\
X ' or else invoke as "unzip -Z".'


X $(LN) unzip$E zipinfo$E
X
X
Xcrypt$O: crypt.c unzip.h zip.h crypt.h
Xenvargs$O: envargs.c unzip.h
Xexplode$O: explode.c unzip.h
Xextract$O: extract.c unzip.h crypt.h
Xfile_io$O: file_io.c unzip.h crypt.h tables.h
Xfunzip$O: funzip.c unzip.h crypt.h tables.h
Xinflate$O: inflate.c inflate.h unzip.h
Xmatch$O: match.c unzip.h
Xunreduce$O: unreduce.c unzip.h
Xunshrink$O: unshrink.c unzip.h

Xunzip$O: unzip.c unzip.h version.h


Xzipinfo$O: zipinfo.c unzip.h
X
Xcrypt_$O: crypt.c unzip.h zip.h crypt.h # funzip only
X $(CP) crypt.c crypt_.c

X $(CC) -c $(CF) $(FC) crypt_.c
X $(RM) crypt_.c
X


Xinflate_$O: inflate.c inflate.h unzip.h crypt.h # funzip only
X $(CP) inflate.c inflate_.c

X $(CC) -c $(CF) $(FC) inflate_.c
X $(RM) inflate_.c
X
Xunzip_$O: unzip.c unzip.h version.h # unzipsfx only
X $(CP) unzip.c unzip_.c
X $(CC) -c $(CF) $(XC) unzip_.c
X $(RM) unzip_.c


X
Xextract_$O: extract.c unzip.h crypt.h # unzipsfx only
X $(CP) extract.c extract_.c

X $(CC) -c $(CF) $(XC) extract_.c
X $(RM) extract_.c
X
X# atari$O: atari/atari.c unzip.h # Atari only
X# $(CC) -c $(CF) atari/atari.c
X
Xatari$O: atari.c unzip.h
X
Xatari_$O: atari.c unzip.h # unzipsfx only
X $(CP) atari.c atari_.c
X $(CC) -c $(CF) $(XC) atari_.c
X $(RM) atari_.c
END_OF_FILE
if test 4811 -ne `wc -c <'unzip-5.12/atari/Makefile'`; then
echo shar: \"'unzip-5.12/atari/Makefile'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/atari/Makefile'
fi
if test -f 'unzip-5.12/mac/macunzip.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macunzip.c'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macunzip.c'\" \(12079 characters\)
sed "s/^X//" >'unzip-5.12/mac/macunzip.c' <<'END_OF_FILE'
X#include "unzip.h"
X
X#include <Traps.h>
X#include <Values.h>
X
Xextern char UnzipVersion[], ZipinfoVersion[];
X
Xvoid MacFSTest (int);
Xvoid ResolveMacVol (short, short *, long *, StringPtr);
X
X#define aboutAlert 128
X
X#define selectDialog 129
X#define okItem 1
X#define cancelItem 2
X#define editItem 3
X#define staticItem 4
X
X#define unzipMenuBar 128
X
X#define appleMenu 128
X#define aboutItem 1
X
X#define fileMenu 129
X#define extractItem 1
X#define infoItem 2
X#define listItem 3
X#define testItem 4
X#define commentItem 6
X#define freshenItem 8
X#define updateItem 9
X#define quitItem 11
X
X#define editMenu 130
X#define cutItem 1
X#define copyItem 2
X#define pasteItem 3
X
X#define modifierMenu 131
X#define selectItem 1
X#define screenItem 3
X#define pauseItem 4
X#define scrollItem 5
X#define convertItem 7
X#define junkItem 8
X#define lowercaseItem 9
X#define neverItem 10
X#define promptItem 11
X#define quietItem 12
X#define verboseItem 13
X
Xshort modifiers, modifierMask;
X
X#define convertFlag 0x0001
X#define junkFlag 0x0002
X#define lowercaseFlag 0x0004
X#define neverFlag 0x0008
X#define promptFlag 0x0010
X#define quietFlag 0x0020
X#define screenFlag 0x0040
X#define scrollFlag 0x0200
X#define verboseFlag 0x0080
X#define allFlags 0x03FF
X
X#define pauseFlag 0x0100
X#define scrollFlag 0x0200
X
X#define extractMask 0x003F
X#define infoMask 0x0000
X#define listMask 0x0020
X#define testMask 0x0020
X#define commentMask 0x0000
X#define freshenMask 0x003F
X#define updateMask 0x003F
X
XEventRecord myevent;
XMenuHandle appleHandle, modifierHandle;
XHandle menubar, itemHandle;
Xshort itemType;
XRect itemRect;
X
Xchar command, fileList[256];
X
XBoolean stop;
X
XSysEnvRec sysRec;
X
Xchar *macgetenv(s) char *s; {
X if (s == NULL) return(fileList);
X return(NULL);
X}
X
XBoolean TrapAvailable(machineType, trapNumber, trapType)
Xshort machineType;
Xshort trapNumber;
XTrapType trapType;
X{
X if (machineType < 0)
X return (false);
X
X if ((trapType == ToolTrap) &&
X (machineType > envMachUnknown) &&
X (machineType < envMacII)) {
X if ((trapNumber &= 0x03FF) > 0x01FF)
X trapNumber = _Unimplemented;
X }
X return (NGetTrapAddress(trapNumber, trapType) !=
X GetTrapAddress(_Unimplemented));
X}
X
Xvoid domenu(menucommand) long menucommand;
X{
X short check, themenu, theitem;
X DialogPtr thedialog;
X Str255 name;
X
X themenu = HiWord(menucommand);
X theitem = LoWord(menucommand);
X
X switch (themenu) {
X
X case appleMenu:
X if (theitem == aboutItem) {
X ParamText(UnzipVersion, ZipinfoVersion, nil, nil);
X Alert(aboutAlert, nil);
X } else {
X GetItem(appleHandle, theitem, name);
X theitem = OpenDeskAcc(name);
X }
X break;
X
X case fileMenu:
X switch (theitem) {
X case extractItem:
X if (modifiers & screenFlag)
X command = 'c';
X else
X command = 'x';
X modifierMask = extractMask;
X break;
X case infoItem:
X command = 'Z';
X modifierMask = infoMask;
X break;
X case listItem:
X if (modifiers & verboseFlag)
X command = 'v';
X else
X command = 'l';
X modifierMask = listMask;
X break;
X case testItem:
X command = 't';
X modifierMask = testMask;
X break;
X case commentItem:
X command = 'z';
X modifierMask = commentMask;
X break;
X case freshenItem:
X command = 'f';
X modifierMask = freshenMask;
X break;
X case updateItem:
X command = 'u';
X modifierMask = updateMask;
X break;
X case quitItem:
X stop = true;
X break;
X default:
X break;
X }
X break;
X
X case editMenu:
X break;
X
X case modifierMenu:
X switch (theitem) {
X case selectItem:
X thedialog = GetNewDialog(selectDialog, nil, (WindowPtr)(-1));
X SetPort(thedialog);
X do
X ModalDialog(nil, &check);
X while ((check != okItem) && (check != cancelItem));
X if (check == okItem) {
X GetDItem(thedialog, editItem, &itemType, &itemHandle, &itemRect);
X GetIText(itemHandle, &fileList);
X p2cstr(fileList);
X }
X DisposDialog(thedialog);
X check = -1;
X break;
X case screenItem:
X check = (modifiers ^= screenFlag) & screenFlag;
X break;
X case pauseItem:
X check = (modifiers ^= pauseFlag) & pauseFlag;
X screenControl("p", check);
X break;
X case scrollItem:
X check = (modifiers ^= scrollFlag) & scrollFlag;
X screenControl("s", check);
X break;
X case convertItem:
X check = (modifiers ^= convertFlag) & convertFlag;
X break;
X case junkItem:
X check = (modifiers ^= junkFlag) & junkFlag;
X break;
X case lowercaseItem:
X check = (modifiers ^= lowercaseFlag) & lowercaseFlag;
X break;
X case neverItem:
X if (check = (modifiers ^= neverFlag) & neverFlag) {
X if (modifiers & promptFlag) {
X CheckItem(modifierHandle, promptItem, false);
X modifiers &= (allFlags ^ promptFlag);
X }
X } else {
X CheckItem(modifierHandle, promptItem, true);
X modifiers |= promptFlag;
X }
X break;
X case promptItem:
X if (check = (modifiers ^= promptFlag) & promptFlag)
X if (modifiers & neverFlag) {
X CheckItem(modifierHandle, neverItem, false);
X modifiers &= (allFlags ^ neverFlag);
X }
X break;
X case quietItem:
X check = (modifiers ^= quietFlag) & quietFlag;
X break;
X case verboseItem:
X check = (modifiers ^= verboseFlag) & verboseFlag;
X break;
X default:
X break;
X }
X if (check == 0)
X CheckItem(modifierHandle, theitem, false);
X else if (check > 0)
X CheckItem(modifierHandle, theitem, true);


X break;
X
X default:

X break;
X
X }
X

X HiliteMenu(0);
X return;
X}
X
Xvoid dokey(myevent) EventRecord *myevent;
X{
X char code;
X
X code = (char)(myevent->message & charCodeMask);
X
X if (myevent->modifiers & cmdKey) {
X if (myevent->what != autoKey) {
X domenu(MenuKey(code));
X }
X }
X
X return;
X}
X
Xvoid domousedown(myevent) EventRecord *myevent;
X{
X WindowPtr whichwindow;
X long code;
X
X code = FindWindow(myevent->where, &whichwindow);
X
X switch (code) {
X
X case inSysWindow:
X SystemClick(myevent, whichwindow);
X break;
X
X case inMenuBar:
X domenu(MenuSelect(myevent->where));


X break;
X
X }
X

X return;
X}
X
Xint main(argc, argv) int argc; char *argv[];
X{
X Boolean haveEvent, useWNE;
X short markChar;
X FILE *fp;
X
X FlushEvents(everyEvent, 0);
X InitGraf(&qd.thePort);
X InitFonts();
X InitWindows();
X InitMenus();
X TEInit();
X InitDialogs(nil);
X InitCursor();
X
X c2pstr(UnzipVersion);
X c2pstr(ZipinfoVersion);
X
X SysEnvirons(1, &sysRec);
X useWNE = TrapAvailable(sysRec.machineType, _WaitNextEvent, ToolTrap);
X
X SetMenuBar(menubar = GetNewMBar(unzipMenuBar));
X DisposeHandle(menubar);
X AddResMenu(appleHandle = GetMHandle(appleMenu), 'DRVR');
X modifierHandle = GetMHandle(modifierMenu);
X DrawMenuBar();
X
X screenOpen("Unzip");
X
X modifiers = 0;
X
X GetItemMark(modifierHandle, pauseItem, &markChar);
X if (markChar) modifiers ^= pauseFlag;
X screenControl("p", markChar);
X GetItemMark(modifierHandle, scrollItem, &markChar);
X if (markChar) modifiers ^= scrollFlag;
X screenControl("s", markChar);
X
X GetItemMark(modifierHandle, screenItem, &markChar);
X if (markChar) modifiers ^= screenFlag;
X GetItemMark(modifierHandle, convertItem, &markChar);
X if (markChar) modifiers ^= convertFlag;
X GetItemMark(modifierHandle, junkItem, &markChar);
X if (markChar) modifiers ^= junkFlag;
X GetItemMark(modifierHandle, lowercaseItem, &markChar);
X if (markChar) modifiers ^= lowercaseFlag;
X GetItemMark(modifierHandle, neverItem, &markChar);
X if (markChar) modifiers ^= neverFlag;
X GetItemMark(modifierHandle, promptItem, &markChar);
X if (markChar) modifiers ^= promptFlag;
X GetItemMark(modifierHandle, quietItem, &markChar);
X if (markChar) modifiers ^= quietFlag;
X GetItemMark(modifierHandle, verboseItem, &markChar);
X if (markChar) modifiers ^= verboseFlag;
X
X if ((modifiers & (neverFlag | promptFlag)) == (neverFlag | promptFlag)) {
X CheckItem(modifierHandle, promptItem, false);
X modifiers &= (allFlags ^ promptFlag);
X }
X
X command = ' ';
X
X stop = false;
X while (!stop) {
X SetCursor(&qd.arrow);
X
X if (useWNE) {
X haveEvent = WaitNextEvent(everyEvent, &myevent, MAXLONG, NULL);
X } else {
X SystemTask();
X haveEvent = GetNextEvent(everyEvent, &myevent);
X }
X
X if (haveEvent) {
X switch (myevent.what) {
X
X case activateEvt:
X break;
X
X case keyDown:
X case autoKey:
X dokey(&myevent);
X break;
X
X case mouseDown:
X domousedown(&myevent);
X break;
X
X case updateEvt:
X screenUpdate(myevent.message);
X break;
X
X case mouseUp:
X case keyUp:


X break;
X
X default:

X break;
X
X }
X }
X
X if (command != ' ') {
X char *s, **v, modifierString[16];
X SFReply fileRep;
X Point p;
X int m, n;
X
X SetPt(&p, 40, 40);
X
X SFGetFile(p, "\pSpecify ZIP file:", 0L, -1, nil, 0L, &fileRep);
X if (fileRep.good) {
X MacFSTest(fileRep.vRefNum);
X ResolveMacVol(fileRep.vRefNum, &gnVRefNum, &glDirID, NULL);
X
X p2cstr(fileRep.fName);
X
X modifierMask &= modifiers;
X
X s = modifierString;
X
X if ((command != 'Z') || modifierMask) {
X *s++ = '-';
X *s++ = command;
X
X if (modifierMask & convertFlag) *s++ = 'a';
X if (!HFSFlag || (modifierMask & junkFlag)) *s++ = 'j';
X if (!modifierMask & lowercaseFlag) *s++ = 'U';
X if (modifierMask & neverFlag) *s++ = 'n';
X if (!modifierMask & promptFlag) *s++ = 'o';
X if (modifierMask & quietFlag) *s++ = 'q';
X if (modifierMask & verboseFlag) *s++ = 'v';
X }
X
X *s = '\0';
X
X v = (char **)malloc(sizeof(char *));
X *v = "unzip";
X argc = 1;
X
X envargs(&argc, &v, NULL, NULL);
X
X argv = (char **)malloc((argc + 3) * sizeof(char *));
X
X argv[m = 0] = (command == 'Z') ? "zipinfo" : "unzip";
X if (*modifierString) argv[++m] = modifierString;
X argv[++m] = (char *)fileRep.fName;
X for (n = 1; n < argc; n++) argv[n + m] = v[n];
X argv[argc += m] = NULL;
X
X free(v);
X
X for (n = 0; argv[n] != NULL; n++) printf("%s ", argv[n]);
X printf("...\n\n");
X
X unzip(argc, argv);
X
X printf("\nDone\n");
X }
X
X fileList[0] = '\0';
X command = ' ';
X }
X }
X
X screenClose();
X
X ExitToShell();
X}
END_OF_FILE
if test 12079 -ne `wc -c <'unzip-5.12/mac/macunzip.c'`; then
echo shar: \"'unzip-5.12/mac/macunzip.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macunzip.c'
fi
if test -f 'unzip-5.12/unzipsfx.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unzipsfx.doc'\"
else
echo shar: Extracting \"'unzip-5.12/unzipsfx.doc'\" \(12334 characters\)
sed "s/^X//" >'unzip-5.12/unzipsfx.doc' <<'END_OF_FILE'
X
XUNZIPSFX(1L) MISC. REFERENCE MANUAL PAGES UNZIPSFX(1L)
X
XNAME
X unzipsfx - self-extracting stub for prepending to ZIP
X archives
X
XSYNOPSIS
X <name of unzipsfx+archive combo> [-cfptuz[ajnoqsCLV$]]
X [file(s) ... [-x xfile(s) ...]]
X
XDESCRIPTION
X unzipsfx is a modified version of unzip(1L) designed to be
X prepended to existing ZIP archives in order to form self-
X extracting archives. Instead of taking its first non-flag
X argument to be the zipfile(s) to be extracted, unzipsfx
X seeks itself under the name by which it was invoked and
X tests or extracts the contents of the appended archive.
X Because the executable stub adds bulk to the archive (the
X whole purpose of which is to be as small as possible), a
X number of the regular version's less-vital capabilities have
X been removed. Among these are the usage (or help) screen,
X the listing and diagnostic functions (-l and -v), the abil-
X ity to decompress older compression formats (the ``reduce,''
X ``shrink'' and ``implode'' methods), and the ability to
X extract to a directory other than the current one. Decryp-
X tion is supported as a compile-time option but should be
X avoided unless the attached archive contains encrypted
X files.
X
X Note that self-extracting archives made with unzipsfx are no
X more (or less) portable across different operating systems
X than is the unzip executable itself. In general a self-
X extracting archive made on a particular Unix system, for
X example, will only self-extract under the same flavor of
X Unix. Regular unzip may still be used to extract the embed-
X ded archive as with any normal zipfile, although it will
X generate a harmless warning about extra bytes at the begin-
X ning of the zipfile.
X
XARGUMENTS
X [file(s)]
X An optional list of archive members to be processed.
X Regular expressions (wildcards) similar to those in
X Unix egrep(1) may be used to match multiple members.
X These wildcards may contain:


X
X * matches a sequence of 0 or more characters
X
X ? matches exactly 1 character
X
X [...]
X matches any single character found inside the
X brackets; ranges are specified by a beginning

X character, a hyphen, and an ending character. If


X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 1
X

XUNZIPSFX(1L) MISC. REFERENCE MANUAL PAGES UNZIPSFX(1L)
X


X an exclamation point or a caret (`!' or `^') fol-
X lows the left bracket, then the range of charac-
X ters within the brackets is complemented (that is,
X anything except the characters inside the brackets
X is considered a match).
X
X (Be sure to quote any character which might otherwise
X be interpreted or modified by the operating system,

X particularly under Unix and VMS.)


X
X [-x xfile(s)]
X An optional list of archive members to be excluded from
X processing. Since wildcard characters match directory
X separators (`/'), this option may be used to exclude

X any files which are in subdirectories. For example,
X ``foosfx *.[ch] -x */*'' would extract all C source


X files in the main directory, but none in any subdirec-

X tories. Without the -x option, all C source files in
X all directories within the zipfile would be extracted.
X Unlike in unzip(1L), the -x option may only be used if
X one or more files are given. This is because there is
X no zipfile separating the normal options from the -x
X option, so unzipsfx sees it as another normal option.
X For historical reasons, the ``normal'' -x is silently
X ignored. See the EXAMPLES section below.
X
X If unzipsfx is compiled with SFX_EXDIR defined, the follow-
X ing option is also enabled:


X
X [-d exdir]
X An optional directory to which to extract files. By
X default, all files and subdirectories are recreated in
X the current directory; the -d option allows extraction

X in an arbitrary directory (always assuming one has per-
X mission to write to the directory). The option and
X directory may be concatenated without any white space
X between them, but note that this may cause normal shell
X behavior to be suppressed. In particular, ``-d ~''
X (tilde) is expanded by Unix C shells into the name of
X the user's home directory, but ``-d~'' is treated as a
X literal subdirectory ``~'' of the current directory.
X As with -x, the -d option may only be used if one or
X more files are given.
X
XOPTIONS
X unzipsfx supports the following unzip(1L) options: -c and
X -p (extract to standard output/screen), -f and -u (freshen
X and update existing files upon extraction), -t (test
X archive) and -z (print archive comment). All normal listing
X options (-l, -v and -Z) have been removed, but the testing
X option (-t) may be used as a ``poor man's'' listing. Alter-
X natively, those creating self-extracting archives may wish


X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 2
X

XUNZIPSFX(1L) MISC. REFERENCE MANUAL PAGES UNZIPSFX(1L)
X
X to include a short listing in the zipfile comment.
X
X See unzip(1L) for a more complete description of these
X options.
X
XMODIFIERS
X unzipsfx currently supports all unzip(1L) modifiers: -a
X (convert text files), -n (never overwrite), -o (overwrite
X without prompting), -q (operate quietly), -C (match names
X case-insenstively), -L (convert uppercase-OS names to lower-
X case), -j (junk paths) and -V (retain version numbers); plus
X the following operating-system specific options: -X
X (restore VMS owner/protection info), -s (convert spaces in
X filenames to underscores [DOS, OS/2, NT]) and -$ (restore
X volume label [DOS, OS/2, NT, Amiga]).
X
X (Support for regular ASCII text-conversion may be removed in
X future versions, since it is simple enough for the archive's
X creator to ensure that text files have the appropriate for-
X mat for the local OS. EBCDIC conversion will of course con-
X tinue to be supported since the zipfile format implies ASCII


X storage of text files.)
X

X See unzip(1L) for a more complete description of these
X modifiers.
X
XENVIRONMENT OPTIONS
X unzipsfx uses the same environment variables as unzip(1L)
X does, although this is likely to be an issue only for the
X person creating and testing the self-extracting archive.
X See unzip(1L) for details.
X
XDECRYPTION
X Decryption is supported exactly as in unzip(1L); that is,
X interactively with a non-echoing prompt for the password(s).
X See unzip(1L) for details. Once again, note that if the
X archive has no encrypted files there is no reason to use a
X version of unzipsfx with decryption support; that only adds
X to the size of the archive.
X
XEXAMPLES
X To create a self-extracting archive letters from a regular
X zipfile letters.zip and change the new archive's permissions
X to be world-executable under Unix:
X
X cat unzipsfx letters.zip > letters
X chmod 755 letters
X
X To create the same archive under MS-DOS, OS/2 or NT (note
X the use of the /b [binary] option to the copy command):


X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 3
X

XUNZIPSFX(1L) MISC. REFERENCE MANUAL PAGES UNZIPSFX(1L)
X
X copy /b unzipsfx.exe+letters.zip letters.exe
X
X Under VMS:
X
X copy unzipsfx.exe,letters.zip letters.exe
X letters == "$currentdisk:[currentdir]letters.exe"
X
X (The VMS append command may also be used. The second com-
X mand installs the new program as a ``foreign command'' capa-
X ble of taking arguments.) To test (or list) the newly
X created self-extracting archive:
X
X letters -t
X
X To test letters quietly, printing only a summary message
X indicating whether the archive is OK or not:
X
X letters -tq
X
X To extract the complete contents into the current directory,
X recreating all files and subdirectories as necessary:
X
X letters
X
X To extract all *.txt files (in Unix quote the `*'):
X
X letters *.txt
X
X To extract everything except the *.txt files:
X
X letters * -x *.txt
X
X (Note that with regular unzip(1L) it would not be necessary
X to use the first `*'; ``unzip letters -x *.txt'' would work
X equally well. With unzipsfx the -x option would be silently
X ignored and the effect would be the same as in the previous
X example, i.e., the opposite of what was intended.) To
X extract only the README file to standard output (the
X screen):
X
X letters -c README
X
X To print only the zipfile comment:
X
X letters -z
X
XLIMITATIONS
X The principle and fundamental limitation of unzipsfx is that
X it is not portable across architectures or operating sys-
X tems, and therefore neither are the resulting archives. For
X some architectures there is limited portability, however
X (e.g., between some flavors of Intel-based Unix).


X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 4
X

XUNZIPSFX(1L) MISC. REFERENCE MANUAL PAGES UNZIPSFX(1L)
X
X unzipsfx has no knowledge of the user's PATH, so in general
X an archive must either be in the current directory when it
X is invoked, or else a full or relative path must be given.
X If a user attempts to extract the archive from a directory
X in the PATH other than the current one, unzipsfx will print
X a warning to the effect, ``can't find myself.'' This is
X always true under Unix and may be true in some cases under
X MS-DOS, depending on the compiler used (Microsoft C fully
X qualifies the program name, but other compilers may not).
X Under OS/2 and NT there are operating-system calls available
X which provide the full path name, so the archive may be
X invoked from anywhere in the user's path. The situation is
X not known for Atari TOS, MacOS, etc.
X
X As noted above, a number of the normal unzip(1L) functions
X have been removed in order to make unzipsfx smaller: usage
X and diagnostic info, listing functions and extraction to
X other directories. Also, only stored and deflated files are
X supported. The latter limitation is mainly relevant to
X those who create SFX archives, however.
X
X VMS users must know how to set up self-extracting archives
X as foreign commands in order to use any of unzipsfx's
X options. This is not necessary for simple extraction, but
X the command to do so then becomes, e.g., ``run letters'' (to
X continue the examples given above).
X
X unzipsfx is not supported on the Amiga because of the way
X the loader works; the entire archive contents would be
X loaded into memory by default. It may be possible to work
X around this by defining the attached archive to be a ``debug
X hunk,'' but compatibility problems between the ROM levels of
X older Amigas and newer ones are likely to cause problems
X regardless.
X
X All current bugs in unzip(1L) exist in unzipsfx as well.
X
XDIAGNOSTICS
X unzipsfx's exit status (error level) is identical to that of
X unzip(1L); see the corresponding man page.
X
XSEE ALSO
X funzip(1L), unzip(1L), zip(1L), zipcloak(1L), zipgrep(1L),
X zipinfo(1L), zipnote(1L), zipsplit(1L)
X
XAUTHORS
X Greg Roelofs was responsible for the basic modifications to
X UnZip necessary to create UnZipSFX. See unzip(1L) for the
X current list of zip-bugs authors, or the file CONTRIBS in
X the UnZip source distribution for the full list of Info-ZIP
X contributors.


X
XInfo-ZIP Last change: 28 Aug 94 (v5.12) 5
X

END_OF_FILE
if test 12334 -ne `wc -c <'unzip-5.12/unzipsfx.doc'`; then
echo shar: \"'unzip-5.12/unzipsfx.doc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unzipsfx.doc'
fi
if test -f 'unzip-5.12/vms/unzipsfx.hlp' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unzipsfx.hlp'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unzipsfx.hlp'\" \(9759 characters\)
sed "s/^X//" >'unzip-5.12/vms/unzipsfx.hlp' <<'END_OF_FILE'
X1 UNZIPSFX
X
X unzipsfx - self-extracting stub for prepending to ZIP
X archives
X
X <name of unzipsfx+archive combo> [-cfptuz[ajnoqsCLV$]]
X [file(s) ...] [-x xfile(s) ...]
X
X unzipsfx is a modified version of unzip designed to be
X prepended to existing ZIP archives in order to form self-
X extracting archives. Instead of taking its first non-flag
X argument to be the zipfile(s) to be extracted, unzipsfx
X seeks itself under the name by which it was invoked and
X tests or extracts the contents of the appended archive.
X Because the executable stub adds bulk to the archive (the
X whole purpose of which is to be as small as possible), a
X number of the regular version's less-vital capabilities have
X been removed. Among these are the usage (or help) screen,
X the listing and diagnostic functions (-l and -v), the abil-
X ity to decompress older compression formats (the ``reduce,''
X ``shrink'' and ``implode'' methods), and the ability to
X extract to a directory other than the current one. Decryp-
X tion is supported as a compile-time option but should be
X avoided unless the attached archive contains encrypted
X files.
X
X Note that self-extracting archives made with unzipsfx are no
X more (or less) portable across different operating systems
X than is the unzip executable itself. In general a self-
X extracting archive made on a particular Unix system, for
X example, will only self-extract under the same flavor of
X Unix. Regular unzip may still be used to extract the embed-
X ded archive as with any normal zipfile, although it will
X generate a harmless warning about extra bytes at the begin-
X ning of the zipfile.
X
X
X
X[file(s)]
X
X An optional list of archive members to be processed.
X Regular expressions (wildcards) similar to those in
X Unix egrep(1) may be used to match multiple members.
X These wildcards may contain:


X
X * matches a sequence of 0 or more characters
X
X ? matches exactly 1 character
X
X [...]
X matches any single character found inside the
X brackets; ranges are specified by a beginning
X character, a hyphen, and an ending character. If
X an exclamation point or a caret (`!' or `^') fol-
X lows the left bracket, then the range of charac-
X ters within the brackets is complemented (that is,
X anything except the characters inside the brackets
X is considered a match).
X
X (Be sure to quote any character which might otherwise
X be interpreted or modified by the operating system,

X particularly under Unix and VMS.)


X
X[-x xfile(s)]
X
X An optional list of archive members to be excluded from
X processing. Since wildcard characters match directory
X separators (`/'), this option may be used to exclude
X any files which are in subdirectories. For example,
X ``unzip foo *.[ch] -x */*'' would extract all C source
X files in the main directory, but none in any subdirec-

X tories. Without the -x option, all C source files in
X all directories within the zipfile would be extracted.
X
X2 Options
X
X unzipsfx supports the following unzip options: -c and
X -p (extract to standard output/screen), -f and -u (freshen
X and update existing files upon extraction), -t (test
X archive) and -z (print archive comment). All normal listing
X options (-l, -v and -Z) have been removed, but the testing
X option (-t) may be used as a ``poor man's'' listing. Alter-
X natively, those creating self-extracting archives may wish
X to include a short listing in the zipfile comment.
X
X See unzip for a more complete description of these
X options.
X
X MODIFIERS
X
X unzipsfx currently supports all unzip modifiers: -a
X (convert text files), -n (never overwrite), -o (overwrite
X without prompting), -q (operate quietly), -C (match names
X case-insenstively), -L (convert uppercase-OS names to lower-
X case), -j (junk paths) and -V (retain version numbers); plus
X the following operating-system specific options: -X
X (restore VMS owner/protection info), -s (convert spaces in
X filenames to underscores [DOS, OS/2, NT]) and -$ (restore
X volume label [DOS, OS/2, NT, Amiga]).
X
X (Support for regular ASCII text-conversion may be removed in
X future versions, since it is simple enough for the archive's
X creator to ensure that text files have the appropriate for-
X mat for the local OS. EBCDIC conversion will of course con-
X tinue to be supported since the zipfile format implies ASCII


X storage of text files.)
X

X See unzip for a more complete description of these
X modifiers.
X
X2 Environment_options
X
X unzipsfx uses the same environment variables as unzip
X does, although this is likely to be an issue only for the
X person creating and testing the self-extracting archive.
X See unzip for details.
X
X2 Decryption
X
X Decryption is supported exactly as in unzip; that is,
X interactively with a non-echoing prompt for the password(s).
X See unzip for details. Once again, note that if the
X archive has no encrypted files there is no reason to use a
X version of unzipsfx with decryption support; that only adds
X to the size of the archive.
X
X2 Examples
X
X To create a self-extracting archive letters from a regular
X zipfile letters.zip and change the new archive's permissions
X to be world-executable under Unix:
X
X cat unzipsfx letters.zip > letters
X chmod 755 letters
X
X To create the same archive under MS-DOS, OS/2 or NT (note
X the use of the /b [binary] option to the copy command):
X
X copy /b unzipsfx.exe+letters.zip letters.exe
X
X Under VMS:
X
X copy unzipsfx.exe,letters.zip letters.exe
X letters == "$currentdisk:[currentdir]letters.exe"
X
X (The VMS append command may also be used. The second com-
X mand installs the new program as a ``foreign command'' capa-
X ble of taking arguments.) To test (or list) the newly
X created self-extracting archive:
X
X letters -t
X
X To test letters quietly, printing only a summary message
X indicating whether the archive is OK or not:
X
X letters -tq
X
X To extract the complete contents into the current directory,
X recreating all files and subdirectories as necessary:
X
X letters
X
X To extract only the README file to standard output (the
X screen):
X
X letters -c README
X
X To print only the zipfile comment:
X
X letters -z
X
X2 Limitations
X
X The principle and fundamental limitation of unzipsfx is that
X it is not portable across architectures or operating sys-
X tems, and therefore neither are the resulting archives. For
X some architectures there is limited portability, however
X (e.g., between some flavors of Intel-based Unix).
X
X unzipsfx has no knowledge of the user's PATH, so in general
X an archive must either be in the current directory when it
X is invoked, or else a full or relative path must be given.
X If a user attempts to extract the archive from a directory
X in the PATH other than the current one, unzipsfx will print
X a warning to the effect, ``can't find myself.'' This is
X always true under Unix and may be true in some cases under
X MS-DOS, depending on the compiler used (Microsoft C fully
X qualifies the program name, but other compilers may not).
X Under OS/2 and NT there are operating-system calls available
X which provide the full path name, so the archive may be
X invoked from anywhere in the user's path. The situation is
X not known for Atari TOS, MacOS, etc.
X
X As noted above, a number of the normal unzip functions
X have been removed in order to make unzipsfx smaller: usage
X and diagnostic info, listing functions and extraction to
X other directories. Also, only stored and deflated files are
X supported. The latter limitation is mainly relevant to
X those who create SFX archives, however.
X
X VMS users must know how to set up self-extracting archives
X as foreign commands in order to use any of unzipsfx's
X options. This is not necessary for simple extraction, but
X the command to do so then becomes, e.g., ``run letters'' (to
X continue the examples given above).
X
X unzipsfx is not supported on the Amiga because of the way
X the loader works; the entire archive contents would be
X loaded into memory by default. It may be possible to work
X around this by defining the attached archive to be a ``debug
X hunk,'' but compatibility problems between the ROM levels of
X older Amigas and newer ones are likely to cause problems
X regardless.
X
X All current bugs in unzip exist in unzipsfx as well.
X
X2 Diagnostics
X
X unzipsfx's exit status (error level) is identical to that of
X unzip; see the corresponding man page.
X
X2 See_also
X
X funzip, unzip, zip, zipcloak, zipgrep,
X zipinfo, zipnote, zipsplit
X
X2 Authors
X
X Greg Roelofs was responsible for the basic modifications to
X UnZip necessary to create UnZipSFX. See unzip for the
X current list of zip-bugs authors, or the file CONTRIBS in
X the UnZip source distribution for the full list of Info-ZIP
X contributors.
END_OF_FILE
if test 9759 -ne `wc -c <'unzip-5.12/vms/unzipsfx.hlp'`; then
echo shar: \"'unzip-5.12/vms/unzipsfx.hlp'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unzipsfx.hlp'
fi
if test -f 'unzip-5.12/vms/vms.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/vms.h'\"
else
echo shar: Extracting \"'unzip-5.12/vms/vms.h'\" \(8436 characters\)
sed "s/^X//" >'unzip-5.12/vms/vms.h' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X vms.h
X
X Generic VMS header file for Info-ZIP's UnZip; now includes VMSmunch.h (at
X end, except fchdef part deleted).
X
X ---------------------------------------------------------------------------*/
X
X#include <descrip.h>
X#include <starlet.h>
X#include <syidef.h>
X#include <atrdef.h>
X#include <fibdef.h>
X#include <iodef.h>
X#include <fchdef.h>
X/* #include <rms.h> already included in unzip.h */
X#include <lib$routines.h>
X#include <unixlib.h>
X
X#define ERR(s) !((s) & 1) /* VMS system error */
X
X#ifndef SYI$_VERSION
X#define SYI$_VERSION 4096 /* VMS 5.4 definition */
X#endif
X
X/*
X * Under Alpha (DEC C?), the FIB unions are declared as variant_unions.
X * FIBDEF.H includes the definition of __union, which we check
X * below to make sure we access the structure correctly.
X */
X#define variant_union 1
X#if defined(__union) && (__union == variant_union)
X# define FIB$W_DID fib$w_did
X# define FIB$W_FID fib$w_fid
X# define FIB$L_ACCTL fib$l_acctl
X# define FIB$W_EXCTL fib$w_exctl
X#else
X# define FIB$W_DID fib$r_did_overlay.fib$w_did
X# define FIB$W_FID fib$r_fid_overlay.fib$w_fid
X# define FIB$L_ACCTL fib$r_acctl_overlay.fib$l_acctl
X# define FIB$W_EXCTL fib$r_exctl_overlay.fib$w_exctl
X#endif
X#undef variant_union
X
X
Xstruct EB_header /* Common header of extra block */
X{ ush tag;
X ush size;
X uch data[1];
X};
X
X/*------ Old style INFO-ZIP extra field definitions -----*/
X
X#if (!defined(VAXC) && !defined(_RMS_H) && !defined(__RMS_LOADED))
X
Xstruct XAB { /* This definition may be skipped */
X unsigned char xab$b_cod;
X unsigned char xab$b_bln;
X short int xabdef$$_fill_1;
X char *xab$l_nxt;
X};
X
X#endif /* !VAXC && !_RMS_H */
X
X#define BC_MASK 07 /* 3 bits for compression type */
X#define BC_STORED 0 /* Stored */
X#define BC_00 1 /* 0byte -> 0bit compression */
X#define BC_DEFL 2 /* Deflated */
X
X/*
X * Extra record format
X * ===================
X * signature (2 bytes) = 'I','M'
X * size (2 bytes)
X * block signature (4 bytes)
X * flags (2 bytes)
X * uncomprssed size(2 bytes)
X * reserved (4 bytes)
X * data ((size-12) bytes)
X * ....
X */
X
Xstruct IZ_block
X{
X ush sig; /* Extra field block header structure */
X ush size;
X ulg bid;
X ush flags;
X ush length;
X ulg reserved;
X uch body[1];
X};
X
X/*
X * Extra field signature and block signatures
X */
X
X#define IZ_SIGNATURE "IM"
X#define FABL (cc$rms_fab.fab$b_bln)
X#define RABL (cc$rms_rab.rab$b_bln)
X#define XALLL (cc$rms_xaball.xab$b_bln)
X#define XDATL (cc$rms_xabdat.xab$b_bln)
X#define XFHCL (cc$rms_xabfhc.xab$b_bln)
X#define XKEYL (cc$rms_xabkey.xab$b_bln)
X#define XPROL (cc$rms_xabpro.xab$b_bln)
X#define XRDTL (cc$rms_xabrdt.xab$b_bln)
X#define XSUML (cc$rms_xabsum.xab$b_bln)
X#define EXTBSL 4 /* Block signature length */
X#define RESL 8 /* Reserved 8 bytes */
X#define EXTHL (4+EXTBSL)
X#define FABSIG "VFAB"
X#define XALLSIG "VALL"
X#define XFHCSIG "VFHC"
X#define XDATSIG "VDAT"
X#define XRDTSIG "VRDT"
X#define XPROSIG "VPRO"
X#define XKEYSIG "VKEY"
X#define XNAMSIG "VNAM"
X#define VERSIG "VMSV"
X
Xtypedef unsigned char byte;
X
Xstruct iosb
X{ ush status;
X ush count;
X ulg spec;
X};
X
X/*------------ PKWARE extra block definitions ----------*/
X
X/* Structure of PKWARE extra header */
X
X#ifdef VMS_ZIP
X
Xstruct PK_info
X{
X ush tag_ra; ush len_ra; byte ra[ATR$S_RECATTR];
X ush tag_uc; ush len_uc; byte uc[ATR$S_UCHAR];
X ush tag_jr; ush len_jr; byte jr[ATR$S_JOURNAL];
X ush tag_cd; ush len_cd; byte cd[ATR$S_CREDATE];
X ush tag_rd; ush len_rd; byte rd[ATR$S_REVDATE];
X ush tag_ed; ush len_ed; byte ed[ATR$S_EXPDATE];
X ush tag_bd; ush len_bd; byte bd[ATR$S_BAKDATE];
X ush tag_rn; ush len_rn; ush rn;
X ush tag_ui; ush len_ui; byte ui[ATR$S_UIC];
X ush tag_fp; ush len_fp; byte fp[ATR$S_FPRO];
X ush tag_rp; ush len_rp; byte rp[ATR$S_RPRO];
X};
X
X#endif /* ?VMS_ZIP */
X
X/* PKWARE "VMS" tag */
X#define PK_SIGNATURE 0x000C
X#define IZ_NEW_SIGNATURE 0x010C /* New signature, extra record format
X * mostly compatible with PKWARE's */
X
X/* Total number of attributes to be saved */
X#define VMS_ATTR_COUNT 11
X#define VMS_MAX_ATRCNT 20
X
Xstruct PK_field
X{ ush tag;
X ush size;
X byte value[1];
X};
X
X#define PK_FLDHDR_SIZE 4
X
Xstruct PK_header
X{ ush tag;
X ush size;
X ulg crc32;
X byte data[1];
X};
X
X#define PK_HEADER_SIZE 8
X
X#ifdef VMS_ZIP
X/* File description structure for Zip low level I/O */
Xstruct ioctx
X{ ush chan;
X int status;
X struct iosb iosb;
X long vbn;
X long size;
X long rest;
X struct PK_info PKi;
X long acllen;
X uch aclbuf[ATR$S_READACL];
X};
X#endif /* VMS_ZIP */


X
X
X
X/*---------------------------------------------------------------------------
X

X VMSmunch.h
X
X A few handy #defines, plus the contents of three header files from Joe
X Meadows' FILE program. Used by VMSmunch and by various routines which
X call VMSmunch (e.g., in Zip and UnZip).
X
X ---------------------------------------------------------------------------*/
X
X#define GET_TIMES 4
X#define SET_TIMES 0
X#define GET_RTYPE 1
X#define CHANGE_RTYPE 2
X#define RESTORE_RTYPE 3
X
X/*---------------------------------------------------------------------------
X fatdef.h
X ---------------------------------------------------------------------------*/
X
X/* This header file was created by Joe Meadows, and is not copyrighted
X in any way. No guarantee is made as to the accuracy of the contents
X of this header file. This header file was last modified on Sep. 22th,
X 1987. (Modified to include this statement) */
X#define FAT$K_LENGTH 32
X#define FAT$C_LENGTH 32
X#define FAT$S_FATDEF 32
X
Xstruct fatdef {
X union {
X unsigned char fat$b_rtype;
X struct {
X unsigned fat$v_rtype : 4;
X unsigned fat$v_fileorg : 4;
X } fat$r_rtype_bits;
X } fat$r_rtype_overlay;
X# define FAT$S_RTYPE 4
X# define FAT$V_RTYPE 0
X# define FAT$C_UNDEFINED 0
X# define FAT$C_FIXED 1
X# define FAT$C_VARIABLE 2
X# define FAT$C_VFC 3
X# define FAT$C_STREAM 4
X# define FAT$C_STREAMLF 5
X# define FAT$C_STREAMCR 6
X# define FAT$S_FILEORG 4
X# define FAT$V_FILEORG 4
X# define FAT$C_SEQUENTIAL 0
X# define FAT$C_RELATIVE 1
X# define FAT$C_INDEXED 2
X# define FAT$C_DIRECT 3
X union {
X unsigned char fat$b_rattrib;
X struct {
X unsigned fat$v_fortrancc : 1;
X unsigned fat$v_impliedcc : 1;
X unsigned fat$v_printcc : 1;
X unsigned fat$v_nospan : 1;
X } fat$r_rattrib_bits;
X } fat$r_rattrib_overlay;
X# define FAT$V_FORTRANCC 0
X# define FAT$M_FORTRANCC 1
X# define FAT$V_IMPLIEDCC 1
X# define FAT$M_IMPLIEDCC 2
X# define FAT$V_PRINTCC 2
X# define FAT$M_PRINTCC 4
X# define FAT$V_NOSPAN 3
X# define FAT$M_NOSPAN 8
X unsigned short int fat$w_rsize;
X union
X {
X unsigned long int fat$l_hiblk;
X struct
X {
X unsigned short int fat$w_hiblkh;
X unsigned short int fat$w_hiblkl;
X } fat$r_hiblk_fields;
X } fat$r_hiblk_overlay;
X union
X {
X unsigned long int fat$l_efblk;
X struct
X {
X unsigned short int fat$w_efblkh;
X unsigned short int fat$w_efblkl;
X } fat$r_efblk_fields;
X } fat$r_efblk_overlay;
X unsigned short int fat$w_ffbyte;
X unsigned char fat$b_bktsize;
X unsigned char fat$b_vfcsize;
X unsigned short int fat$w_maxrec;
X unsigned short int fat$w_defext;
X unsigned short int fat$w_gbc;
X char fat$fill[8];
X unsigned short int fat$w_versions;
X};
X
X
X/*---------------------------------------------------------------------------
X fjndef.h
X ---------------------------------------------------------------------------*/
X
X/* This header file was created by Joe Meadows, and is not copyrighted
X in any way. No guarantee is made as to the accuracy of the contents
X of this header file. This header file was last modified on Sep. 22th,
X 1987. (Modified to include this statement) */
X
X#define FJN$M_ONLY_RU 1
X#define FJN$M_RUJNL 2
X#define FJN$M_BIJNL 4
X#define FJN$M_AIJNL 8
X#define FJN$M_ATJNL 16
X#define FJN$M_NEVER_RU 32
X#define FJN$M_JOURNAL_FILE 64
X#define FJN$S_FJNDEF 1
Xstruct fjndef {
X unsigned fjn$v_only_ru : 1;
X unsigned fjn$v_rujnl : 1;
X unsigned fjn$v_bijnl : 1;
X unsigned fjn$v_aijnl : 1;
X unsigned fjn$v_atjnl : 1;
X unsigned fjn$v_never_ru : 1;
X unsigned fjn$v_journal_file:1;
X} ;
END_OF_FILE
if test 8436 -ne `wc -c <'unzip-5.12/vms/vms.h'`; then
echo shar: \"'unzip-5.12/vms/vms.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/vms.h'
fi
echo shar: End of archive 16 \(of 20\).
cp /dev/null ark16isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:16:56 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 82
Archive-name: unzip/part17

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/CONTRIBS unzip-5.12/COPYING
# unzip-5.12/amiga/filedate.c unzip-5.12/amiga/stat.c
# unzip-5.12/mac/macdir.c unzip-5.12/mac/macscreen.c
# unzip-5.12/mac/rsrc.hqx unzip-5.12/os2/makefile.os2
# unzip-5.12/vms/unzip_cli.help
# Wrapped by kent@sparky on Sat Sep 17 23:33:47 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 17 (of 20)."'
if test -f 'unzip-5.12/CONTRIBS' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/CONTRIBS'\"
else
echo shar: Extracting \"'unzip-5.12/CONTRIBS'\" \(8435 characters\)
sed "s/^X//" >'unzip-5.12/CONTRIBS' <<'END_OF_FILE'
XThis is a partial list of contributors to Info-ZIP UnZip and the code upon
Xwhich it is based. Others have also contributed, and if you are among them,
Xplease let us know (don't be shy!). Everyone who contributed via the Info-
XZIP digest *should* now be listed here, but oversights are quite possible.
X
X Mark Adler decryption, inflate, explode, funzip code; misc. casts
X Steve Alpert VMS rms.h bugfix
X Glenn Andrews MS-DOS makefiles; prototyping bugfix; bogus main() fix
X Joel Aycock descrip.mms bugfix
X Eric Baatz Borland version() info
X Charles Bailey VMS_SEVERITY fix; VMSWILD () extension
X Audrey Beck Where info for AOL OS/2 forum
X Mike Bernardi Unix makefile entry
X James Birdsall extract.c/makefile/NT stuff, etc.; awesome beta tester
X Allan Bjorklund in misc.c
X Denise Blakeley Unix makefile entry
X Wim Bonner original OS/2 port; Unix makefile entry
X Paul Borman BSD/386 (BSDI) fixes; Unix makefile entry
X Rodney Brown stdin-/dev/null bugfix; VMS error levels
X John Bush first full Amiga port; FileDate; Amiga fixes; etc.
X Valter Cavecchia Unix makefile entry
X John Cowan mods to original match.c; other stuff?
X Frank da Cruz xxu.c, on which original mapname.c was based
X Bill Davidsen -q(q); mapname stuff; envargs; Xenix stuff; etc.
X Matt "Doc" D'Errico AIX stuff, Unix makefile entry
X Kim DeVaughn Unix makefile entry
X Arjan de Vet various things, but I don't remember exactly what...
X James Dugal ZMEM stuff; unshrink bugfix; file perms stuff; etc.
X Jim Dumser -z stuff; umask bugfixes; opendir/Borland fix; etc.
X Mark Edwards mapname.c, misc.c fixes; Unix makefile entry
X Gershon Elber Unix makefile entry
X Bruce Evans Unix makefile entry
X David Feinleib Windows NT port
X David Fenyes Unix makefile entry
X Greg Flint Unix makefile entry
X Jeffrey Foy OS/2 stuff(?); [CP/M]
X Mike Freeman VMS GCC makefiles; VMS fixes; etc.
X Kevin Fritz Borland bugfixes; etc.
X Jean-loup Gailly decryption code; ReadByte replacement; much nagging :-)
X Forrest Gehrke Unix makefile entry
X Tim Geibelhaus Unix makefile entry
X Henry Gessau flush/Fwrite/outcnt fixes; new NT port
X Christian Ghisler inflate tweaks
X Filip Gieszczykiewicz Unix makefile entry
X Hunter Goatley VMSCLI interface; VMS help/RUNOFF; list maintainer
X Michael Graff Unix makefile entry
X Richard H. Gumpertz Unix makefile entry
X Steve Hanna Macintosh stuff
X Mark Hanning-Lee docs corrections, Unix Makefile fix
X Robert Heath Windows port (WizUnZip)
X Dave Heiland new usage screen
X Ron Henderson -a bugfix
X Chris Herborth new Atari port; Atari fixes
X Phil Howard Unix makefile entry
X Joe Isuzu Unix makefile entry
X Aubrey Jaffer pixel, v7 targets
X Graham Jenkins Sequent Dynix/ptx bugfix
X Peter Jones Unix makefile entry
X Larry Jones ZMEM stuff; unimplod bugfix; etc.
X Warren Jones MKS bugfix
X Kjetil J{\o}rgenson ln/copy misc_.c Makefile bugfix; OSF/1 fix; NetBSD fix
X Bruce Kahn DOS floppy detection?; Unix makefile entry
X Bob Kemp NOTINT16 rewrite; Unix makefile entry
X J. Kercheval filmatch.c, on which second match.c was based
X Paul Kienitz continuing general Amiga porting; Aztec C support; ASM
X Mike Kincer AIX "ps2" bugfix
X David Kirschbaum mapname port; general-purpose meddling; Python jokes
X Paul Klahr Regulus port
X Jim Knoble Turbo C++ makefile fix
X Alvin Koh Borland C++ bugfixes
X Karel Kubat Linux strncasecmp bugfix
X Bo Kullmar -z code; bugfixes: umask, do_string, BSD time; etc.
X Michael Lawler Borland version() info
X Johnny Lee Macintosh port; Win3.1 port; far strings/small model
X Marty Leisner man pages fonts; install-target fixes
X Daniel Lewart AIX stuff; compiler warnings
X John Limpert Unix makefile entry
X Hogan Long Borland preprocessor bugfix
X Mike Long Unix Makefile installation bugfix
X Warner Losh in misc.c
X Dave Lovelace Data General AOS/VS port
X Tony Luu NT timezone bugfix
X Igor Mandrichenko vms.c; many improvements and VMS modifications
X Javier Manero file_io.c bugfix; MS-DOS version() bugfix
X Paul Manno makefile.tc fixes
X Fulvio Marino revised UnZip and ZipInfo man pages; Makefile entry
X Carl Mascott original Unix port
X Rafal Maszkowski Convex unzip.h fixes; Unix makefile entry
X Peter Mauzey Unix makefile entry
X Scott Maxwell version.h; OS/2 DLL port [coming soon!]
X Bob Maynard 16-bit OS/2 pathname bugfix
X Randy McCaskile Unix makefile entry
X Gene McManus -o code
X Joe Meadows file.c, on which VMSmunch.c (timestamps) was based
X Jason Merrill Sequent patches
X Tom Metro corrupted-zipfile handler bugfix
X Ricky Mobley Unix makefile entry
X Navin Modi Unix makefile entry
X Paul Motsuk Borland _rtl_chmod() fix
X Anthony Naggs MS-DOS error handling stuff
X NIIMI Satoshi Human68k port
X Mike O'Carroll early OS/2 stuff
X "Moby" Dick O'Connor Unix makefile entry
X Thomas Opheys Watcom C stat() bugfix
X Humberto Ortiz-Zuazaga Linux port; permissions bugfix; missing declarations
X Rafael Pappalardo Convex CRYPT bugfix; Convex Makefile entry, useful info
X Trevor Paquette Unix makefile entry
X Keith Petersen Pyramid fixes; former Info-ZIP list maintainer
X Alan Phillips Unix makefile entry
X Art Pina C Set/2 crypt.c optimization bug
X Piet W. Plomp nice fix for msc_dos Makefile target
X Clint Pulley Unix makefile entry
X Antonio Querubin, Jr. descrip.mms (VMS makefile)
X Alistair Rae Encore preprocessor bugfix
X David Robinson MSC 6.0 stat() bugfix
X Jochen Roderburg floating-point BSD4_4 fix
X Greg Roelofs maintainer; ZipInfo; orig VMS port; SFX; unshrink; etc.
X Kai Uwe Rommel "real" OS/2 port; many new compilers; bugfixes; etc.
X Paul Roub first self-extracting code
X Steve Salisbury NT fixes; dual-mode SFX instructions; variable INBUFSIZ
X Georg Sassen Amiga DICE compiler port
X Jon Saxton date formats, OS/2 fixes
X Tom Schmidt Unix makefile entry
X Hugh Schmidt VMS stuff
X Martin Schulz original Atari port, symlinks bugfix
X Charles Scripter various bug reports and bugfixes
X Chris Seaman Unix time stuff
X Richard Seay MS-DOS Quick C makefile
X Alex Sergejew file_io.c, stat(), Makefile fixes; Down Under jokes :-)
X Jim Seymour Borland OS/2 fixes
X Timur Shaporev inflate optimizations
X Fred Smith Coherent 4.0 fixes
X Samuel H. Smith original unzip code (Pascal and C) for MS-DOS
X Christian Spieler performance tweaks; VMS and other fixes
X Cliff Stanford file_io.c umask bug
X Jack Stansbury DEC Alpha NT makefile fix
X Jim Steiner Unix makefile entry
X Richard Stephen Unix makefile entry
X Brian Tillman "Where" file VMS correction
X Onno van der Linden many fixes, esp. Intel Unix and 386 DOS
X Jim Van Zandt one of original man pages
X Geraldo Veiga Pyramid strrchr/rindex
X Erik-Jan Vens Unix makefile entry
X Antoine Verheijen new Mac port; Mac fixes; MTS/EBCDIC stuff; etc.
X Rich Wales former Info-ZIP moderator and zip guy; MKS stuff
X Frank Wancho original TOPS-20 port
X Paul Weiss unzipsfx bugfix
X Paul Wells original Amiga port for SAS/C and Lattice C (?)
X Mark Wright Netware 3.11 NLM port
X Randy Wright Unix makefile entry
X Meiwei Wu open() return bugfix
X Martin Zinser VMS .hlp file for unzipsfx; MAKESFX.COM command file
END_OF_FILE
if test 8435 -ne `wc -c <'unzip-5.12/CONTRIBS'`; then
echo shar: \"'unzip-5.12/CONTRIBS'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/CONTRIBS'
fi
if test -f 'unzip-5.12/COPYING' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/COPYING'\"
else
echo shar: Extracting \"'unzip-5.12/COPYING'\" \(8192 characters\)
sed "s/^X//" >'unzip-5.12/COPYING' <<'END_OF_FILE'
X__________________________________________________________________________
X
X This is the Info-ZIP file COPYING (for UnZip), last updated 10 Aug 94.
X__________________________________________________________________________
X
X There are currently three explicit copyrights on portions of UnZip
X code (at least, of which Info-ZIP is aware): the original Sam Smith
X copyright on unzip 2.0, upon which Info-ZIP's UnZip 3.0 was based;
X Igor Mandrichenko's copyright on his routines in vms.c; and Greg
X Roelofs' copyright on the new version of unshrink.c. In addition,
X Mark Adler has placed inflate.h, inflate.c, explode.c and funzip.c
X into the public domain; i.e., these files may be used without any
X restrictions beyond those of simple courtesy (credit where it's due).
X All of these are discussed immediately below; the Frequently Asked
X Questions regarding (re)distribution of Zip and UnZip are near the
X end of this file.
X__________________________________________________________________________
X
X The original unzip source code has been extensively modified and
X mostly rewritten (changes include random zipfile access rather than
X sequential; replacement of unimplode() with explode(); replacement
X of output routines; addition of inflate(), wildcards, filename-
X mapping, text translation, ...; etc.). As far as we can tell, the
X only remaining code which is substantially similar to Mr. Smith's
X is that in the files unreduce.c and the old version of unshrink.c
X (although even those have been modified), to which the following
X copyright therefore applies:
X
X * Copyright 1989 Samuel H. Smith; All rights reserved
X *
X * Do not distribute modified versions without my permission.
X * Do not remove or alter this notice or any other copyright notice.
X * If you use this in your own program you must distribute source code.
X * Do not use any of this in a commercial product.
X
X Regarding the first stipulation, Mr. Smith was finally tracked down
X in southern California [Samuel H. Smith, The Tool Shop, P.O. Box 8808,
X Panorama City, CA 91412-4808, (818) 891-4228 (voice), (818) 891-6780
X (BBS, 2400 baud, free access)] [ADDITIONAL NOTE, July 1994: he's
X moved again, as of mid-May 1994; these numbers are no longer correct]:
X
X "He says that he thought that whoever contacted him understood that
X he has no objection to the Info-ZIP group's inclusion of his code.
X His primary concern is that it remain freely distributable, he said."
X
X Info-ZIP is indebted and grateful to Mr. Smith; we hope he finds our
X contributions as useful as we have his.
X
X Note that the third and fourth stipulations still apply to any com-
X pany which wishes to incorporate the unreduce and/or "old" unshrink
X code into its products; if you wish to do so, you must contact Mr.
X Smith regarding licensing.
X
X
X The following copyright applies to most of the VMS code in vms.c,
X distributed with UnZip versions 4.2 and later:
X
X * Copyright (C) 1992 Igor Mandrichenko.
X * Permission is granted to any individual or institution to use,
X * copy, or redistribute this software so long as all of the orig-
X * inal files are included unmodified, that it is not sold for
X * profit, and that this copyright notice is retained.
X
X
X The following copyright applies to the new version of "unshrink" in
X unshrink.c, distributed with UnZip versions 5.11 and later:
X
X * Copyright (C) 1994 Greg Roelofs.
X * Permission is granted to any individual/institution/corporate
X * entity to use, copy, redistribute or modify this software for
X * any purpose whatsoever, subject to the conditions noted in the
X * Frequently Asked Questions section below, plus one additional
X * condition: namely, that my name remain attached to the source
X * code. (Other names may, of course, be added as modifications
X * are made.) Corporate legal staff (like at IBM :-) ) who have
X * problems understanding this can contact me through zip-bugs...
X
X
X The remaining code was written by many people associated with the
X Info-ZIP group, with large contributions from (but not limited to):
X Mark Adler (inflate, explode, funzip), Kai Uwe Rommel (OS/2), John
X Bush and Paul Kienitz (Amiga), Antoine Verheijen (Macintosh), Hunter
X Goatley (more VMS) and Greg Roelofs (lots of stuff). See the file
X CONTRIBS in the source distribution for a much more complete list of
X contributors. As noted above, Mark Adler's inflate.[ch], explode.c
X and funzip.c are in the public domain. As for the remaining code,
X while it may not be explicitly copyrighted, we do request that no
X one else try to copyright it, either. In other words, use it with
X our blessings, but it's still our code. (You can consider that an
X implicit copyright if it makes you feel better. :-) ) Thank you!
X__________________________________________________________________________
X
X Frequently Asked Questions about distributing Zip and UnZip:
X
X
X Q. Can I distribute Zip and UnZip sources and/or executables?
X
X A. You may redistribute the latest official distributions without
X any modification, and without even asking us for permission.
X [Note that an "executable distribution" includes documentation,
X even if it's in a separate zipfile; plain executables do NOT
X count.] You can charge for the cost of the media (CDROM, disk-
X ettes, etc.) and a small copying fee. Distributed archives
X should follow the naming conventions used in the Where file.
X If you want to distribute modified versions please contact us
X at zip-...@wkuvx1.wku.edu first. You must not distribute beta
X versions without explicit permission to do so.
X
X
X Q. Can I use the executables of Zip and UnZip to distribute my
X software?
X
X A. Yes, so long as it is clear that Zip and UnZip are not being
X sold, that the source code is freely available, and that there
X are no extra or hidden charges resulting from its use by or in-
X clusion with the commercial product. Here is an example of a
X suitable notice:
X
X NOTE: <Product> is packaged on this CD using Info-ZIP's
X compression utility. The installation program uses UnZip
X to read zip files from the CD. Info-ZIP's software (Zip,
X UnZip and related utilities) is free and can be obtained
X as source code or executables from various bulletin board
X services and anonymous-ftp sites, including CompuServe's
X IBMPRO forum and ftp.uu.net:/pub/archiving/zip/*.
X
X
X Q. Can I use the source code of Zip and UnZip in my commercial
X application?
X
X A. Yes, so long as you include in your product an acknowledgment
X and an offer of the original compression sources for free or for
X a small copying fee, and make clear that there are no extra or
X hidden charges resulting from the use of the compression code by
X your product (see below for an example). The acknowledgment should
X appear in at least one piece of human-readable documentation (e.g.,
X a README file or man page), although additionally putting it in
X the executable(s) is OK, too. In other words, you are allowed to
X sell only your own work, not ours--and we'd like a little credit.
X [Note the additional restrictions above on the code in unreduce.c,
X unshrink.c and vms.c.] Contact us at zip-...@wkuvx1.wku.edu if
X you have special requirements. We also like to know when our code
X is being used, but we don't require that.
X
X <Product> incorporates compression code by the Info-ZIP group.
X There are no extra charges or costs due to the use of this code,
X and the original compression sources are freely available from
X CompuServe in the IBMPRO forum and by anonymous ftp from the
X Internet site ftp.uu.net:/pub/archiving/zip. We will also, upon
X request, mail you the full sources on a 3.5" MSDOS-format disk-
X ette for the cost of mailing. Send $2.00 to <address> and ..."
X
X__________________________________________________________________________
X
END_OF_FILE
if test 8192 -ne `wc -c <'unzip-5.12/COPYING'`; then
echo shar: \"'unzip-5.12/COPYING'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/COPYING'
fi
if test -f 'unzip-5.12/amiga/filedate.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/filedate.c'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/filedate.c'\" \(7106 characters\)
sed "s/^X//" >'unzip-5.12/amiga/filedate.c' <<'END_OF_FILE'
X/***********************/
X/* Function filedate() */
X/***********************/
X
X/* FileDate() (originally utime.c), by Paul Wells. Modified by John Bush
X * and others (see also sendpkt() comments, below); NewtWare SetFileDate()
X * clone cheaply ripped off from utime().
X */
X
X/* HISTORY/CHANGES
X * 2 Sep 92, Greg Roelofs, Original coding.
X * 6 Sep 92, John Bush, Incorporated into UnZip 5.1
X * 6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or
X * redefines SetFileDate() depending upon AMIGADOS2 definition.
X * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining
X * revision via OpenLibrary() call. Now only one version of
X * the program runs on both platforms (1.3.x vs. 2.x)
X * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing
X * to take time_t input instead of struct DateStamp.
X * Arg passing made to conform with utime().
X * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some
X * lint-ish errors; simplified test for AmigaDOS version.
X */
X
X/* DESCRIPTION
X * This routine chooses between 2 methods to set the file date on AMIGA.
X * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36
X * and higher). Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate()
X * must be accomplished by constructing a message packet and sending it
X * to the file system handler of the file to be stamped.
X *
X * The system's ROM version is extracted from the external system Library
X * base.
X *
X * NOTE: although argument passing conforms with utime(), note the
X * following differences:
X * - Return value is boolean success/failure.
X * - If a structure or array is passed, only the first value
X * is used, which *may* correspond to date accessed and not
X * date modified.
X */
X
X#include <string.h>
X#include <time.h>
X#include <errno.h>
X#include <stdio.h>
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <exec/libraries.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X
X#ifdef AZTEC_C
X extern int timezone;
X void tzset(void);
X# include <clib/exec_protos.h>
X# include <clib/dos_protos.h>
X# include <pragmas/exec_lib.h>
X# include <pragmas/dos_lib.h>
X# define ESRCH ENOENT
X# define EOSERR EIO
X#endif
X
X#if defined(LATTICE) || defined(__SASC)
X# include <proto/exec.h>
X# include <proto/dos.h>
X#endif
X
Xextern int _OSERR;
X
X#ifndef SUCCESS
X# define SUCCESS (-1L)
X# define FAILURE 0L
X#endif
X
X#define ReqVers 36L /* required library version for SetFileDate() */
X
Xextern struct Library *SysBase;
X
XLONG FileDate (char *filename, time_t u[]);
X
X/* =============================================================== */
X
XLONG FileDate(filename, u)
X char *filename;
X time_t u[];
X{
X LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate);
X LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
X struct MsgPort *taskport;
X struct FileLock *dirlock, *lock;
X struct FileInfoBlock *fib;
X LONG pktargs[4];
X UBYTE *ptr;
X long ret;
X
X struct DateStamp pDate;
X time_t mtime;
X
X tzset();
X mtime=u[0]-timezone;
X
X#ifdef DEBUG
X fprintf (stderr,"Entry to FileDate(): mtime=%s\n",ctime(&mtime));
X#endif
X
X/* magic number = 2922 = 8 years + 2 leaps between 1970 - 1978 */
X
X pDate.ds_Days = (mtime / 86400L) - 2922L;
X mtime = mtime % 86400L;
X pDate.ds_Minute = mtime / 60L;
X mtime = mtime % 60L;
X pDate.ds_Tick = mtime * TICKS_PER_SECOND;
X
X#ifdef DEBUG
X fprintf (stderr,"In FileDate(): Days=%ld Minutes=%ld Ticks=%ld\n",
X pDate.ds_Days,pDate.ds_Minute,pDate.ds_Tick);
X#endif
X
X if (SysBase->lib_Version >= ReqVers) {
X return (SetFileDate(filename,&pDate)); /* native routine at 2.0+ */
X }
X else /* !(SysBase->lib_Version >=ReqVers) */
X {
X if( !(taskport = (struct MsgPort *)DeviceProc(filename)) )
X {
X errno = ESRCH; /* no such process */
X _OSERR = IoErr();
X return FAILURE;
X }
X
X if( !(lock = (struct FileLock *)Lock(filename,SHARED_LOCK)) )
X {
X errno = ENOENT; /* no such file */
X _OSERR = IoErr();
X return FAILURE;
X }
X
X if( !(fib = (struct FileInfoBlock *)AllocMem(
X (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
X {
X errno = ENOMEM; /* insufficient memory */
X UnLock((BPTR)lock);
X return FAILURE;
X }
X
X if( Examine((BPTR)lock,fib)==FAILURE )
X {
X errno = EOSERR; /* operating system error */
X _OSERR = IoErr();
X UnLock((BPTR)lock);
X FreeMem((char *)fib,(long)sizeof(*fib));
X return FAILURE;
X }
X
X dirlock = (struct FileLock *)ParentDir((BPTR)lock);
X ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
X strcpy((ptr+1),fib->fib_FileName);
X *ptr = strlen(fib->fib_FileName);
X FreeMem((char *)fib,(long)sizeof(*fib));
X UnLock((BPTR)lock);
X
X /* now fill in argument array */
X
X pktargs[0] = 0;
X pktargs[1] = (LONG)dirlock;
X pktargs[2] = (LONG)&ptr[0] >> 2;
X pktargs[3] = (LONG)&pDate;
X
X errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L);
X
X FreeMem(ptr,64L);
X UnLock((BPTR)dirlock);
X
X return SUCCESS;
X } /* ?(SysBase->lib_Version >= ReqVers) */
X} /* FileDate() */
X
X/* LOW LEVEL SUPPORT ROUTINES */
X
X/* sendpkt.c
X * by A. Finkel, P. Lindsay, C. Sheppner
X * returns Res1 of the reply packet
X */
X/*
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <proto/exec.h>
X#include <proto/dos.h>
X*/
X
XLONG sendpkt(pid,action,args,nargs)
Xstruct MsgPort *pid; /* process identifier (handler message port) */
XLONG action, /* packet type (desired action) */
X *args, /* a pointer to argument list */
X nargs; /* number of arguments in list */
X{
X
X struct MsgPort *replyport, *CreatePort(UBYTE *, long);
X void DeletePort(struct MsgPort *);
X struct StandardPacket *packet;
X LONG count, *pargs, res1;
X
X replyport = CreatePort(NULL,0L);
X if( !replyport ) return(0);
X
X packet = (struct StandardPacket *)AllocMem(
X (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
X if( !packet )
X {
X DeletePort(replyport);
X return(0);
X }
X
X packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X
X /* copy the args into the packet */
X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of 1st argument */
X for( count=0; count<nargs; count++ )
X pargs[count] = args[count];
X
X PutMsg(pid,(struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X res1 = packet->sp_Pkt.dp_Res1;
X
X FreeMem((char *)packet,(long)sizeof(*packet));
X DeletePort(replyport);
X
X return(res1);
X
X} /* sendpkt() */
END_OF_FILE
if test 7106 -ne `wc -c <'unzip-5.12/amiga/filedate.c'`; then
echo shar: \"'unzip-5.12/amiga/filedate.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/filedate.c'
fi
if test -f 'unzip-5.12/amiga/stat.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/stat.c'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/stat.c'\" \(7102 characters\)
sed "s/^X//" >'unzip-5.12/amiga/stat.c' <<'END_OF_FILE'
X/* Here we have a handmade stat() function because Aztec's c.lib stat() */
X/* does not support an st_mode field, which we need... also a chmod(). */
X
X/* This stat() is by Paul Wells, modified by Paul Kienitz. */
X/* for use with Aztec C >= 5.0 and Lattice C <= 4.01 */
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#ifdef AZTEC_C
X# include <clib/exec_protos.h>
X# include <clib/dos_protos.h>
X# include <pragmas/exec_lib.h>
X# include <pragmas/dos_lib.h>
X# include "amiga/z-stat.h" /* fake version of stat.h */
X#else
X# include <sys/types.h>
X# include <sys/stat.h>
X# include <proto/exec.h>
X# include <proto/dos.h>
X#endif
X
X#ifndef SUCCESS
X# define SUCCESS (-1)
X# define FAILURE (0)
X#endif
X
Xextern int stat(char *file,struct stat *buf);
X
Xstat(file,buf)
Xchar *file;
Xstruct stat *buf;
X{
X
X struct FileInfoBlock *inf;
X struct FileLock *lock;
X long ftime;
X
X if( (lock = (struct FileLock *)Lock(file,SHARED_LOCK))==0 )
X /* file not found */
X return(-1);
X
X if( !(inf = (struct FileInfoBlock *)AllocMem(
X (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
X {
X UnLock((BPTR)lock);
X return(-1);
X }
X
X if( Examine((BPTR)lock,inf)==FAILURE )
X {
X FreeMem((char *)inf,(long)sizeof(*inf));
X UnLock((BPTR)lock);
X return(-1);
X }
X
X /* fill in buf */
X buf->st_dev =
X buf->st_nlink =
X buf->st_uid =
X buf->st_gid =
X buf->st_rdev = 0;
X
X buf->st_ino = inf->fib_DiskKey;
X buf->st_blocks = inf->fib_NumBlocks;
X buf->st_size = inf->fib_Size;
X
X /* now the date. AmigaDOS has weird datestamps---
X * ds_Days is the number of days since 1-1-1978;
X * however, as Unix wants date since 1-1-1970...
X */
X
X ftime =
X (inf->fib_Date.ds_Days * 86400 ) +
X (inf->fib_Date.ds_Minute * 60 ) +
X (inf->fib_Date.ds_Tick / TICKS_PER_SECOND ) +
X (86400 * 8 * 365 ) +
X (86400 * 2 ); /* two leap years */
X
X /* ftime += timezone; */
X
X buf->st_ctime =
X buf->st_atime =
X buf->st_mtime = ftime;
X
X buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR);
X
X /* lastly, throw in the protection bits */
X buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF);
X
X FreeMem((char *)inf, (long)sizeof(*inf));
X UnLock((BPTR)lock);
X
X return(0);


X
X}
X
X
X

X/* opendir(), readdir(), closedir() and rmdir() by Paul Kienitz: */
X
Xunsigned short disk_not_mounted;
X
Xstatic DIR *dir_cleanup_list = NULL; /* for resource tracking */
X
XDIR *opendir(char *path)
X{
X DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC);
X if (!dd) return NULL;
X if (!(dd->d_parentlock = Lock(path, MODE_OLDFILE))) {
X disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED;
X FreeMem(dd, sizeof(DIR));


X return NULL;
X } else

X disk_not_mounted = 0;
X if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) {
X UnLock(dd->d_parentlock);
X FreeMem(dd, sizeof(DIR));
X return NULL;
X }
X dd->d_cleanuplink = dir_cleanup_list; /* track them resources */
X if (dir_cleanup_list)
X dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink;
X dd->d_cleanupparent = &dir_cleanup_list;
X dir_cleanup_list = dd;
X return dd;
X}
X
Xvoid closedir(DIR *dd)
X{
X if (dd) {
X if (dd->d_cleanuplink)
X dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent;
X *(dd->d_cleanupparent) = dd->d_cleanuplink;
X if (dd->d_parentlock)
X UnLock(dd->d_parentlock);
X FreeMem(dd, sizeof(DIR));
X }
X}
X
X/* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */
Xvoid close_leftover_open_dirs(void)
X{
X while (dir_cleanup_list)
X closedir(dir_cleanup_list);
X}
X
XDIR *readdir(DIR *dd)
X{
X return (ExNext(dd->d_parentlock, &dd->d_fib) ? dd : NULL);
X}
X
Xint rmdir(char *path)
X{
X return (DeleteFile(path) ? 0 : IoErr());
X}
X
X
Xint chmod(char *filename, int bits) /* bits are as for st_mode */
X{
X long protmask = (bits & 0xFF) ^ 0xF;
X return !SetProtection(filename, protmask);
X}
X
X
X#ifdef AZTEC_C
X
X/* This here removes unnecessary bulk from the executable with Aztec: */
Xvoid _wb_parse() { }
X
X/* This here pretends we have time zone support and suchlike when we don't: */
Xint timezone = 0;
Xvoid tzset() { }
X
X/* fake a unix function that does not apply to amigados: */
Xint umask() { return 0; }
X
Xint _OSERR;
X
X# include <signal.h>
X
X/* C library signal() messes up debugging yet adds no actual usefulness */
Xtypedef void (*__signal_return_type)(int);
X__signal_return_type signal() { return SIG_ERR; }
X
X
X/* The following replaces Aztec's argv-parsing function for compatibility with
Xthe standard AmigaDOS handling of *E, *N, and *". It also fixes the problem
Xthe standard _cli_parse() has of accepting only lower-ascii characters. */
X
Xint _argc, _arg_len;
Xchar **_argv, *_arg_lin;
X
Xvoid _cli_parse(struct Process *pp, long alen, register UBYTE *aptr)
X{
X register UBYTE *cp;
X register struct CommandLineInterface *cli;
X register short c;
X register short starred = 0;
X
X cli = (struct CommandLineInterface *) (pp->pr_CLI << 2);
X cp = (UBYTE *) (cli->cli_CommandName << 2);
X _arg_len = cp[0] + alen + 2;
X if (!(_arg_lin = AllocMem((long) _arg_len, 0L)))
X return;
X c = cp[0];
X strncpy(_arg_lin, cp + 1, c);
X _arg_lin[c] = 0;
X for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--)
X *cp++ = *aptr++;
X *cp = 0;
X for (_argc = 1, aptr = cp = _arg_lin + c + 1; ; _argc++) {
X while (*cp == ' ' || *cp == '\t')
X cp++;
X if (!*cp)
X break;
X if (*cp == '"') {
X cp++;
X while (c = *cp++) {
X if (starred) {
X if (c | 0x20 == 'n')
X *aptr++ = '\n';
X else if (c | 0x20 == 'e')
X *aptr++ = 27;
X else
X *aptr++ = c;
X starred = 0;
X } else if (c == '"') {
X *aptr++ = 0;
X break;
X } else if (c == '*')
X starred = 1;
X else
X *aptr++ = c;
X }
X } else {
X while ((c = *cp++) && c != ' ' && c != '\t')
X *aptr++ = c;
X *aptr++ = 0;
X }
X if (c == 0)
X --cp;
X }
X *aptr = 0;
X if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) {
X _argc = 0;
X return;
X }
X for (c = 0, cp = _arg_lin; c < _argc; c++) {
X _argv[c] = cp;
X cp += strlen(cp) + 1;
X }
X _argv[c] = NULL;
X}


X
X#endif /* AZTEC_C */

END_OF_FILE
if test 7102 -ne `wc -c <'unzip-5.12/amiga/stat.c'`; then
echo shar: \"'unzip-5.12/amiga/stat.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/stat.c'
fi
if test -f 'unzip-5.12/mac/macdir.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macdir.c'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macdir.c'\" \(2914 characters\)
sed "s/^X//" >'unzip-5.12/mac/macdir.c' <<'END_OF_FILE'
X#include <Errors.h>
X#include <Files.h>
X#ifndef THINK_C
X#include <Strings.h>
X#endif
X
X#ifndef FSFCBLen


X#define FSFCBLen (*(short *)0x3F6)
X#endif
X

X#include <errno.h>
X#include <stdlib.h>
X#include <string.h>
X
X#include "macdir.h"
X
Xint closedir(dPtr) DIR *dPtr; {
X free(dPtr);


X
X return 0;
X}
X

XDIR *opendir(dirName) char *dirName; {
X int fullPath, pathLen;
X char *s, pName[256];
X HParamBlockRec hPB;
X CInfoPBRec cPB;
X DIR *dPtr;
X OSErr err;
X
X if (dirName == NULL || *dirName == '\0' || (pathLen = strlen(dirName)) > 255) {
X errno = EINVAL;


X return NULL;
X }
X

X if (FSFCBLen <= 0) {

X errno = ENOTDIR;
X return NULL;
X }
X
X /* Get information about volume. */
X
X memset(&hPB, '\0', sizeof(hPB));
X
X strcpy(pName, dirName);
X
X if (((s = strchr(pName, ':')) == NULL) || (*pName == ':')) {
X fullPath = false;
X } else {
X *(s + 1) = '\0';
X c2pstr(pName);
X hPB.volumeParam.ioVolIndex = -1;
X fullPath = true;
X }
X
X hPB.volumeParam.ioNamePtr = (StringPtr)pName;
X
X err = PBHGetVInfo(&hPB, 0);
X
X if ((err != noErr) || (hPB.volumeParam.ioVFSID != 0)) {
X errno = ENOENT;
X return NULL;
X }
X
X /* Get information about file. */
X
X memset(&cPB, '\0', sizeof(cPB));
X
X strcpy(pName, dirName);
X c2pstr(pName);
X
X if (fullPath)
X cPB.hFileInfo.ioVRefNum = hPB.volumeParam.ioVRefNum;
X
X cPB.hFileInfo.ioNamePtr = (StringPtr)pName;


X
X err = PBGetCatInfo(&cPB, false);
X
X if (err != noErr) {

X errno = (err == fnfErr) ? ENOENT : EIO;


X return NULL;
X }
X

X if (!(cPB.hFileInfo.ioFlAttrib & ioDirMask)) {
X errno = ENOTDIR;
X return NULL;
X }
X
X /* Get space for, and fill in, DIR structure. */
X
X if ((dPtr = (DIR *)malloc(sizeof(DIR))) == NULL) {


X return NULL;
X }
X

X dPtr->ioVRefNum = cPB.dirInfo.ioVRefNum;
X dPtr->ioDrDirID = cPB.dirInfo.ioDrDirID;
X dPtr->ioFDirIndex = 1;
X dPtr->flags = 0;
X
X return dPtr;
X}
X
Xstruct dirent *readdir(dPtr) DIR *dPtr; {
X struct dirent *dirPtr;
X CInfoPBRec cPB;
X char name[32];
X OSErr err;
X
X if (dPtr->flags) {
X return NULL;
X }
X
X /* Get information about file. */
X
X memset(&cPB, '\0', sizeof(cPB));
X
X cPB.hFileInfo.ioNamePtr = (StringPtr)name;
X cPB.hFileInfo.ioFDirIndex = dPtr->ioFDirIndex;
X cPB.hFileInfo.ioVRefNum = dPtr->ioVRefNum;
X cPB.hFileInfo.ioDirID = dPtr->ioDrDirID;


X
X err = PBGetCatInfo(&cPB, false);
X
X if (err != noErr) {

X dPtr->flags = 0xff;
X errno = (err == fnfErr) ? ENOENT : EIO;


X return NULL;
X }
X

X p2cstr((StringPtr)name);
X
X dirPtr = &dPtr->currEntry;
X
X dirPtr->d_fileno = dPtr->ioFDirIndex++;
X dirPtr->d_namlen = strlen(name);
X strcpy(dirPtr->d_name, name);
X dirPtr->d_reclen = sizeof(struct dirent) - sizeof(dirPtr->d_name) + dirPtr->d_namlen;
X
X return dirPtr;
X}
END_OF_FILE
if test 2914 -ne `wc -c <'unzip-5.12/mac/macdir.c'`; then
echo shar: \"'unzip-5.12/mac/macdir.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macdir.c'
fi
if test -f 'unzip-5.12/mac/macscreen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macscreen.c'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macscreen.c'\" \(7587 characters\)
sed "s/^X//" >'unzip-5.12/mac/macscreen.c' <<'END_OF_FILE'
X#include <QuickDraw.h>
X
X#include <stdio.h>
X#include <stdarg.h>
X#include <string.h>
X
X#define bufferSize 1024
X
X#define screenWindow 128
X
Xstatic Rect scrollRect, pauseRect;
Xstatic WindowPtr theWindow;
Xstatic RgnHandle scrollRgn;
X
Xstatic short fontHeight, fontWidth, screenHeight, screenWidth;
Xstatic short currentPosition, maxPosition, pausePosition;
X
Xstatic short *screenLength, startLine, endLine;
Xstatic char *screenImage, **screenLine;
X
Xstatic int screenOptions;
X
X#define pauseOption 0x0001
X#define scrollOption 0x0002
X
Xvoid screenOpen(char *Title) {
X FontInfo fontInfo;
X int n;
X
X theWindow = GetNewWindow(screenWindow, nil, (WindowPtr)(-1));
X
X if ((Title != NULL) && (*Title != '\0')) {
X c2pstr(Title);
X SetWTitle(theWindow, Title);
X p2cstr(Title);
X }
X
X ShowWindow(theWindow);
X
X SetPort(theWindow);
X TextFont(monaco);
X TextSize(9);
X
X GetFontInfo(&fontInfo);
X fontHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
X fontWidth = fontInfo.widMax;
X
X scrollRgn = NewRgn();
X
X screenWidth = (theWindow->portRect.right - theWindow->portRect.left - 10) /
X fontWidth;
X screenHeight = (theWindow->portRect.bottom - theWindow->portRect.top) /
X fontHeight;
X maxPosition = screenHeight * fontHeight;
X pausePosition = maxPosition - (currentPosition = fontHeight);
X
X SetRect(&scrollRect, theWindow->portRect.left, theWindow->portRect.top + fontInfo.descent,
X theWindow->portRect.right, theWindow->portRect.bottom);
X SetRect(&pauseRect, theWindow->portRect.left, pausePosition + fontInfo.descent,
X theWindow->portRect.right, theWindow->portRect.bottom);
X
X MoveTo(5, currentPosition);
X
X n = (sizeof(char *) + sizeof(short) + screenWidth) * screenHeight;
X
X screenLine = (char **)NewPtr(n);
X
X screenLength = (short *)&screenLine[screenHeight];
X screenImage = (char *)&screenLength[screenHeight];
X
X for (n = 0; n < screenHeight; n++) {
X screenLine[n] = &screenImage[n * screenWidth];
X screenLength[n] = 0;
X }
X
X startLine = endLine = 0;
X
X screenOptions = 0;


X
X return;
X}
X

Xvoid screenControl(options, setting) char *options; int setting; {
X int n = 0;
X
X while (*options) {
X switch (*options) {
X case 'p':
X n |= pauseOption;


X break;
X case 's':

X n |= scrollOption;


X break;
X default:
X break;
X }

X options += 1;
X }
X
X if (setting == 0)
X screenOptions &= (n ^ (-1));
X else
X screenOptions |= n;
X
X if ((pausePosition = maxPosition - currentPosition) == 0)
X pausePosition = maxPosition - fontHeight;


X
X return;
X}
X

Xvoid screenClose(void) {
X DisposPtr(screenLine);
X
X DisposeWindow(theWindow);


X
X return;
X}
X

Xvoid screenUpdate(WindowPtr window) {
X GrafPort *savePort;


X int m, n;
X

X if (window == theWindow) {
X BeginUpdate(window);
X if (!EmptyRgn(window->visRgn)) {
X GetPort(&savePort);
X SetPort(window);
X n = startLine;
X for (m = 1; ; m++) {
X MoveTo(5, m * fontHeight);
X if (screenLength[n] != 0)
X DrawText(screenLine[n], 0, screenLength[n]);
X if (n == endLine) break;
X if ((n += 1) == screenHeight) n = 0;
X }
X SetPort(savePort);
X }
X EndUpdate(window);


X }
X
X return;
X}
X

Xstatic void screenNewline(void) {
X MoveTo(5, currentPosition += fontHeight);
X if (currentPosition > maxPosition) {
X if (screenOptions & scrollOption) {
X ScrollRect(&scrollRect, 0, -fontHeight, scrollRgn);
X MoveTo(5, currentPosition = maxPosition);
X if ((startLine += 1) == screenHeight) startLine = 0;
X } else {
X ScrollRect(&scrollRect, 0, -maxPosition + fontHeight, scrollRgn);
X MoveTo(5, currentPosition = fontHeight + fontHeight);
X startLine = endLine;
X }
X }
X pausePosition -= fontHeight;
X
X if ((endLine += 1) == screenHeight) endLine = 0;
X screenLength[endLine] = 0;


X
X return;
X}
X

Xstatic char waitChar(void) {
X WindowPtr whichWindow;
X EventRecord theEvent;


X
X for ( ; ; ) {

X SystemTask();
X if (GetNextEvent(everyEvent, &theEvent)) {
X switch (theEvent.what) {
X case keyDown:
X if ((theEvent.modifiers & cmdKey) &&
X ((theEvent.message & charCodeMask) == '.'))
X ExitToShell();
X return(theEvent.message & charCodeMask);
X case mouseDown:
X if (FindWindow(theEvent.where, &whichWindow) == inSysWindow)
X SystemClick(&theEvent, whichWindow);
X break;
X case updateEvt:
X screenUpdate((WindowPtr)theEvent.message);
X break;


X }
X }
X }
X}
X

Xstatic void screenPause(void) {
X
X if (pausePosition == 0) {
X if (screenOptions & pauseOption) {
X DrawText("Press any key to continue ...", 0, 29);
X memcpy(screenLine[endLine], "Press any key to continue ...", 29);
X screenLength[endLine] = 29;
X
X (void)waitChar();
X
X EraseRect(&pauseRect);
X MoveTo(5, currentPosition);
X screenLength[endLine] = 0;
X }
X
X pausePosition = maxPosition - fontHeight;


X }
X
X return;
X}
X

Xvoid screenDisplay(char *s) {
X GrafPort *savePort;
X int m, n;
X char *t;
X
X GetPort(&savePort);
X SetPort(theWindow);
X
X while (*s) {
X screenPause();
X
X for (t = s; (*s) && (*s != '\n') && (*s != '\r'); s++);
X
X if ((n = s - t) > (m = screenWidth - screenLength[endLine])) n = m;
X
X if (n > 0) {
X DrawText(t, 0, n);
X memcpy(screenLine[endLine] + screenLength[endLine], t, n);
X screenLength[endLine] += n;
X }
X
X if ((*s == '\n') || (*s == '\r')) {
X screenNewline();
X s += 1;
X }
X }
X
X SetPort(savePort);


X
X return;
X}
X

Xvoid screenDump(char *s, long n) {
X GrafPort *savePort;
X int k, m;
X char *t;
X
X GetPort(&savePort);
X SetPort(theWindow);
X
X while (n) {
X screenPause();
X
X for (t = s; (n) && (*s != '\n') && (*s != '\r'); s++, n--);
X
X if ((k = s - t) > (m = screenWidth - screenLength[endLine])) k = m;
X
X if (k > 0) {
X DrawText(t, 0, k);
X memcpy(screenLine[endLine] + screenLength[endLine], t, k);
X screenLength[endLine] += k;
X }
X
X if ((*s == '\n') || (*s == '\r')) {
X screenNewline();
X s += 1;
X n -= 1;
X }
X }
X
X SetPort(savePort);


X
X return;
X}
X

Xchar *wfgets(char *s, int n, FILE *stream) {
X GrafPort *savePort;
X char c, *t = s;
X
X GetPort(&savePort);
X SetPort(theWindow);
X
X for (n -= 1; (n > 0) && ((c = waitChar()) != '\r'); n -= 1) {
X DrawChar(*t++ = c);
X if (screenLength[endLine] < screenWidth)
X screenLine[endLine][screenLength[endLine]++] = c;
X }
X
X if (c == '\r') screenNewline();
X
X *t = '\0';
X
X SetPort(savePort);
X
X return(s);
X}
X
Xvoid wfprintf(FILE *stream, char *format, ...) {
X char buffer[bufferSize];
X va_list ap;
X
X va_start(ap, format);
X vsprintf(buffer, format, ap);
X va_end(ap);
X
X screenDisplay(buffer);


X
X return;
X}
X

Xvoid wprintf(char *format, ...) {
X char buffer[bufferSize];
X va_list ap;
X
X va_start(ap, format);
X vsprintf(buffer, format, ap);
X va_end(ap);
X
X screenDisplay(buffer);
X
X return;
X}
END_OF_FILE
if test 7587 -ne `wc -c <'unzip-5.12/mac/macscreen.c'`; then
echo shar: \"'unzip-5.12/mac/macscreen.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macscreen.c'
fi
if test -f 'unzip-5.12/mac/rsrc.hqx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/rsrc.hqx'\"
else
echo shar: Extracting \"'unzip-5.12/mac/rsrc.hqx'\" \(6945 characters\)
sed "s/^X//" >'unzip-5.12/mac/rsrc.hqx' <<'END_OF_FILE'


X(This file must be converted with BinHex 4.0)
X

X:%A9ZHQP`,R4SD@jVBbjbFh*M!(*cFQ058d9%!*!)'PGPLJ#3"!%!N!-B)J!!&b)
X!!!)eFR)T$3N*)#"l$3N*)*!%HLdqE%4TFNP%)$dJF'eT,4&eERTTF#jdD'PZDf-
XZFR0bB`)!N!0bFh*M8P0&4!%!N!0bFh*M8P0&4!%!!*`"J!#3%UThLmB!N!BD9fP
XcG#!UF(ST$AX0)#"0B@0*EQC[)#T`E@NJ25"MB@aXEf-S)$%X)(0THQ9[CL!SFh4
XbG@0d)%eKBdPZCQmT+6X0)#!0)#"TCL!SF'eT+3dJ)(X0)*!%3dPZCQp33P*PBb"
XMDA"LFMX0)*!%8'&bB@e#E'pMDe*PBb"`BR)l$5!J!*!$8`85J!#3!aK*EQC[,9T
XTF#Gc)&9ZHQP`)'C[FL"0B@-c5@jQEbeDDA!RFb"9ERTTF#"QEh)JG'KP)%eKBfP
XZG'pcD#`J3fp`HA*TCfKd)+Na16Nd!*!$4!I!(c!r#(m%I`6r![m#rrk"rS(q3Ia
X"r#(i'I!(`!!!"m!Im$riIrarr2rqrrlrr[rqrrjrr(rm2rJIm!I!!*!$"`!(!*!
X$4!I!(r!rq&rd6q5(`S1#J3+$JSI#6q4Ip$ri(r!(`!!!"m!Im$riIrarr2rqrrl
Xrr[rqrrjrr(rm2rJIm!I!!*!$"`!(!*!$4!I!'I!Kq%(m3Ib"rS(qrrlr![m#I`4
Xr"$m)(c!(`!!!"m!Im$riIrarr2rqrrlrr[rqrrjrr(rm2rJIm!I!!*!$"`!(!*!
X$4!I!'$!J#(!FH$cmI[lqrrk3!raqH$a`(#!)'$!(`!!!"m!Im$riIrarr2rqrrl
Xrr[rqrrjrr(rm2rJIm!I!!*!$"`!(!*!$+!#!!*!)rj!$q`%8$%&LEh9d)&9ZHQP
X`b3#3"!%Y!*!)5!##!*!)rj!$ZJ4&C'Pd"&9ZC'm!@J!!!5d!N!3$3h9d!&J!!!4
X$Eh"j!%-!!!93BA0dC3"@!!!&3faPBA)!N!J+!!3!J!#"!))!J`#3!hB!!`#3"8B
X"-3"D!@d%!Np,!*!&4J$K!&S"(33'3f&ZBf9X!*!&+J!C!$S"E4!!N!B8!"N!*!&
XY#$06F'9MD@Cj)'CTE'8JEQ&YC5Kc+5"[FL"`BA4dCA*Z+(-T)(4[)'*P)'9iG(*
XKBh4PC$S!N!3-!#J!+!$k!B%!J%4%!*!$&3!S!#J!PJ'Z!!%"!!%!N!D"!*!%%`!
XS!!S"3!(d!!3!N!`(39"36!#3"3%!N!E'B`!!aR-!!-Cl!!$'I`!!aQm!!2jR!!"
XmB`#3#Ari!!"rq!!!IrMJ!("ii!"`q1!!!I!!!!2J!!!(`12i$i$Mr"m!iriq!11
X1I$MMMRJiiijrq12qIrMMr(riirJ!!!1!!!!$J!!!!i!!!!1!!!!$J!#3"2q3J!#
X3!d!5N!!5d"+`(T!!!!$pJ2f!h!!j[('qlEEp[[fm!$!!-!!`rj!J!!!"!"rrrJ!
X3!!-!%!!#J"!LLN!3)XSJ%#+U%"!LQrJ3()J)%!!!#"!!!!J6q!!)%rJ!#"-jJ!J
X61B!)%(!!#""`!!J3iCm)%1'IL"("QFJ4`CM)%jQBb"1CQFJ6qCq)%rQI#"!!'!J
X3!"J)%!!B#"!!'!J3!"J)%!!!#"!!!!JIrrri(rrq!"rrr`!Irrq!(rrr`"rrrq!
XIrrr`(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJ
XIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJ
XIrrri(rrrq"rrrrJ!N!-(,RTTF!!"!*!%*&9DDA!!N!-"4P*&4J!"!*!$J!!"!)&
X*3diM!!%!N!1!!!%!J3#3!d"rm%!B5V4+rNkL3!*H!P+#4!*)ZP+UAVT!)N!L3!*
XrrRr`IrKrr(rqIrjrrRrqIrjrrRrqIrjrrRrqIrjrrRrq!*!$!3#3!`3!N!6rN"3
X!N!cr!*!5rrm!N![r!#Z3%Im!r`#3#[m!+j!&l#Z3!q`Vl#Z3!q`Vr`!Vr`#3#Im
X!+j!&l#Z3!q`Vl1`V+q`Vr`!V+rm!N!Mr!#Z3"H`VN!2X+q`Vl#[X+rrjN!6r!*!
X(r`!VN!AX+j!$l#[X+b[Xl#[rN!F!N!Er!#Z3"Zb3!bXVl#Z3!q`VN!Ejr`#3"[m
X!+j!@qIm!N!Er!#Z3&[Rr!*!'r`!Vl*!(+j!1qIm!N!Er!#[XN!FVN!ljr`#3"[m
X!+qcX+b[XN!-V+qcX+j!+qIm!N!Er!#[Xl#XVl*!$+b[Xl#Z3#[Rr!*!'r`!VN!6
XXN!-VN!rjr`#3"[m!+j!%l*!$+j!2qIm!N!Er!#Z3!qb3!bZ3"1cX+b[XN!8VN!2
Xjr`#3"[m!+j!$l*!$+j!%l1`V+qb3"LXVqIm!N!Er!#XVl*!$+j!&l1`V+qcX+b[
XXN!-VqIm!N!Er!#XVl*!$+j!&l1`V+qcX+j!$l1`VqIm!N!Er!#[XN!-V+qcX+b[
XXl#XVl1`VN!2Xl#[jr`#3"[m!+qb3!bXVl1`V+qcX+b[Xl#XVl*!$+rRr!*!'r`!
XVl*!(+b[Xl#XVl*!'+b[jr`#3"[m!+qb3"bXVl1`V+qb3"5Z3!rRr!*!'r`!VN!l
XXl#Z3"[Rr!*!'r`!VN!lXl#Z3"[Rr!*!'r`!VN!lXl#Z3"[Rr!*!'r`!VN!lXl#Z
X3"[Rr!*!'r`!VN!lXl#Z3"[Rr!*!'r`!VN"Ejr`#3"[rjN"Mr!*!'rj!D!*!&!3!
X!rj!,!*!&r`#3#Irr!*!%r`!Vl#[X+q`Vl2mVr`#3!rm!+q`Vl#[XN!2rN!3!!2m
X!+qb3!b[X+q`V+rRr!!$r!#Z3#[Rr!!$r!1b3"#Z3"[Rr!!$r!1`V+q`Vl#Z3"2R
Xr!!$r!#XVl#Z3"rRr!!$r!#[X+j!$l#[XN!2jr`!!r`$X+b[X+q`Vl#[XqIm!!2m
X!l*!%+q`Vl*!$qIm!!2m!+j!(l#XVqIm!!2m!+j!(l#XVqIm!!2rjN!cr!!$rN!i
X!N!-#!!!2rj!*m!#3"3m!N!Rr!*!&$`c-N!M`m!#3"!m-c-cmc2cmc2c`c`#3"!m
X-c-cmc2crc2c`c2!!N!-2$-c-r-cmN!6phGm!N!-2$-c-r-cmr-rmrj!$m!!!$`c
X-c-rrc2c-r-c-cI!!!!m-c*!+cI!!!!m-c*!+cI!!!!m-rj!$r-b3"Xh`!!!2$2q
X3!rc-N!E0m!!!$`crc2rmcrc-N!60m!!!$`crc2rmcrc-N!60m!!!$`c-crr-N!I
X0m!!!$`c-crr-N!I0m!!!$`c-rrc-crc2rrr-cI!!!!m-c2rmc-rmcrrrr-h`!!!
X2$-rrc-c2r-rmcrr0m!!!$`c2rmc-crc2r-crcI!!!!m-rrc2r-rmcrc-rmh`!!!
X2$2rmcrc2r-rmcrr0m!!!$`crN!2mcrc2rrrmcI!!!!m-rj!$r-rmcrrrc-h`!!!
X2$-b3"Xrmc-c0m!!!$`c-N!E2r-c-cI!!!!m-c*!'crc-c-h`!!!2$-b3"Xrmc-c
X0m!!!$`c-N!E2r-c-cI!!!!m-c*!+cI!!!!rGN!c`!!!2rj!-m!#3")!2rj!&!!!
X2!*!%$r!!$`cmN!2rc`!2$2cmrj!$m!m-rrb3!mh`$`c-N!60m!m2rrc-c-h`$`r
X-r2c-cI!2$-r-N!20m!m-r-cmrrh`$`r-r*!$rI!2$rrmr2rpm!m-c*!$r-h`$`c
X-N!2mcI!2hC!'m!rrN!E`!*!$J-c2c2cmcmc0c-r-r2r2c-h-cmcmr2r-cFc2rrc
Xmcmc0c*!(cIq3!mrmc-c0rj!$crc-c-hrcrr-N!60c2rmcrcrrmh2rmc2r2rrrIr
Xmrmrmrmrprj!$crcrrrhrN!22r2rrcFb3"Ir-cFb3"Ir-cGf3"IrGh3!!"!!VN"r
Xj+j!)l1`VN!2Xl#XVl1`VN!2Xl#Z3"rNVN!MXl#Z3!qcX+b[XN!-V+qcX+j!(q5Z
X3#1cX+j!$l1`V+qb3"#[Xl#Z3"rNVN!MXl#Z3!qcX+b[XN!FVN!Ij+j!)l1`VN!2
XXl#XVl1`Vl*!%+j!(q5Z3#1b3"bXVl1`V+qb3!bZ3"rNVN!RXN!8VN!2Xl#Z3!qc
XX+j!(q5Z3(rNVN"rj+qb3$#Z3%[NVl*!-+j!5q5[XN!`VN!2XN!-VN!cj+qb3!bZ
X3"Hb3"#Z3!qb3!bZ3$2NVl*!$+j!%l*!&+j!$l*!$+j!-q5Z3"qb3"5Z3%rNVN!E
XXN!8VN"6j+j!&l*!&+j!'l*!$+j!$l*!(+b[j+j!%l*!&+j!(l*!$+j!$l*!)+rN
XVN!2XN!8VN!MXN!-VN!2XN!Rj+b[XN!8VN!RXN!-VN!2XN!-VN!2XN!2j+qb3"5Z
X3"1b3!bZ3!qb3!bZ3!qb3!bZ3!qb3!rNVl*!%+j!&l*!$+j!$l*!$+j!$l*!$+j!
X$l*!$q5[XN!`VN!2XN!-VN!2XN!Rj+qb3$#Z3!qb3!bZ3!qb3##[j+qb3$#Z3!qb
X3!bZ3!qb3"bXVq5Z3&Zb3!bZ3"[NVN"EXN!-VN!Ej+j!@l*!$+j!'q5Z3&Zb3!bZ
X3"[NVN"EXN!-VN!EjN#%!!!)!c*!2cFb3"2r-crc2r-crc*!$cFb3"2r-crc2rmc
Xrc*!$cFb3"2r-crc2rrcrc*!$cFb3"2r-crc2rj!$c*!$cFb3"2r-crc2r2rrc*!
X$cFb3"2q3!rc2r-rrc*!$cFb3"-rrrmc2r-crc*!$cFb3$mh-N!r0crq3"Ic-N!M
X0crq3"Ic-N!M0crq3"Ic-rrc-N!A0crr-c-rrr-crr-b3"Fh2rmc-rrrmc2rmc*!
X&cFb3!mrrrmb3#Fh-N!2rrrc-N!R0c-c2rrr-N!2rr-crN!2mcFc-rrrmc*!$rrc
X-rj!%cFc2rrr-N!6rr-crN!6pc2rrr-b3"2rmc2rmc2rpcrrrc-crr-crr-crr-c
XrrFrrr-c-rrc-rrc-rrc-rrh2rj!&r-crr-crN!6pcrq3"Ic-rrc-rj!%cFrrN!A
Xmc2rmc2q3!rc0c*!,rrc-c-h-N![rr-c-cFb3#rrmc-c0c*!,rrc-c-h-N![rr-c
X-cGf3%!!!!3!VN!2X+b[X+q`V+q`VN!2j+j!$l#XVl#[Xl#[X+j!$q5Z3!q`V+q`
XVl#[Xl#Z3!rNVN!2XN!3Vl#XVl#Z3!rNVN!rjl*!'+qcX+j!'qHb3"L[Xl#Z3"[R
XXl#[XN!-VN!Rj+b[XN!-V+qcX+qb3"#[j+qb3!bZ3!qcX+qb3"IRXN!-Vl1`Vl1`
XVl1`Vl1cjl*!'+qcX+qb3"IRXN!BVl1`Vl*!%+rNVN!VXl#Z3!rNVN!VXl#Z3!rQ
X3#qcXqC!%!*!$P!#"!*!)rrrlA`4'D@aP#%9iG(*KBh6*!%m!!!9*EQC[b3"*!!!
X&6'PcG-N!6!!!"94PFh6*!&3!!!%Y!*!%%%4TFh"XBANJ3fpYE@9ZG-N!N!3",3#
X3"!j'FQ9cD'9Z)%CTE'9cb3#3"!e9F'4KG'8J4QPXCA2*!*!%!5d!N!3%8A9TG!"
X4!*!'bJ!"!*!&UJ%%!,i"3!3#6dX!N!88!"N!P`&!#+P9EPTTF#"H-#`JBRNJ5@j
XQEbeD59!Z$9"[FR4TEfjc)#KM+5!a16Jj)'*j)&-Z)%JZ)&0YDA4S,Jd0@QP`5@j
XQEb"H-5`JBRNJ6Q9hG(GKFQ8JB@jN)(4SC5"QD@jP)'C[E'Yc)'&d)%PZCQmY@NP
X3,Jd08f9ZC#"LG@FJFQ9`Eh*dFb"dEb"KGA4SEh*c)'&d)(TTF#eLG@Gc3(GVGAC
Xi-5jhDh8ZC@4e!*!%p!#$!*!)rj!$Z`P0Ef4TCQPPFR-08f9XC@0d)%CTE'9cb3"
X6!!!",3#3""&&H(4bB@0d)(4[)&0MFQ9PEJ#3"!a3BA9cC5"6Bh*PC@i!!")!$90
XMFQpXE#"6Bh*PC@i!!")!!5d!N!333fpZGQ9bG#"1CAGXD@jPF`!!%J!+5R9ZDb"
X3BA4SF`#3"!p-EhGPFQ0KFf8J6Q&YCA-!!")!$djPGQ9b)%pfCA*hFQPdC3#3""0
X3FQpYF(3JEfiJ6hCPFRGbDA4P!!!5!!T4G@PPG#"0Ef4P!*!%$&CPFQ*[Ff8J6'P
XcG!!!%J#3"4B&%S!!N!-%05ia-JT9ERTTF#!e,M%b!!!"!*!$'#)!!"FL!!!#03!
XN""3(Z!#3!a`#*J!3GQ9bF`!"!)T$99*6!!-!SNe&6P8!!`$568*"8J!!!3*%594
X-!!%"$N4-6dF!!!%Q9dP14!!!!6*"6&*8!!!"2NP$6L-!!3&+3Nj%6!!!!@*'8N9
X'!!%"EQPMFb-!!3''99TTF!!!!CjTBf`i!!%"UQPMFcJ!!3(#D@0X0!!"!GTTBh-
Xd!!%"mJ!"rrm!N!8N!`3!![rr!!!A#!!N!``!J2rr"!!!9`#3"B(rr`3!!*m!N!@
X#rrm%!!$R!*!&Jrrr"!!",`#3"B$rr`!!!AF!N!@"rrm!!"5U!*!&J[rr"!!"S`#
X3"B2rr`!!&K!!N!@!rrm!!!([!*!&JIrr!!!"r3#3"B$rr`!!&8)!N!@"rrm!!!+
X(!*!&J2rr!!!#S!#3"B$rr`!!!RF!N!@"rrm!!!3+!*!&J2rr!!!#`J#3"B$rr`!
X!"4N!N!@!rrm!!!+h!*!&JIrr!!!&$J#3"B$rr`!!!mB!N!@"rrm!!!9"!*!+"B8
X!N!@"rrm!!!@+!*!&J2rr!!!0RJ#3"B(rr`!!#Bi!N!@!rrm!!"1Q!*!&JIrr!!!
X+NJ#3"B$rr`!!%D)!N!@"rrm!!!b@!*!&J2rr!!!0'J#3"!j2GfjPFL"bCA0[GA*
XMCC%`!:
END_OF_FILE
if test 6945 -ne `wc -c <'unzip-5.12/mac/rsrc.hqx'`; then
echo shar: \"'unzip-5.12/mac/rsrc.hqx'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/rsrc.hqx'
fi
if test -f 'unzip-5.12/os2/makefile.os2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/makefile.os2'\"
else
echo shar: Extracting \"'unzip-5.12/os2/makefile.os2'\" \(7372 characters\)
sed "s/^X//" >'unzip-5.12/os2/makefile.os2' <<'END_OF_FILE'
X# Makefile for UnZip, UnZipSFX and fUnZip 23 July 1994
X#
X# - for Microsoft C, version 6.00 or higher, for use under OS/2 1.x (16-bit)
X# - for Watcom C/386, version 9.0 or higher, for use under OS/2 2.x (32-bit)
X# - for IBM C/C++ Set/2, for use under OS/2 2.x (32-bit)
X# - for Borland C++, for use under OS/2 2.x (32-bit)
X# - for GNU gcc (emx kit), version 0.8e or higher, for use under OS/2 2.x
X#
X# cross-compilation:
X# - for Microsoft C, version 6.00 or higher, for use under MS-DOS (16-bit)
X# - for GNU gcc (emx), version 0.8h or higher, for use under MS-DOS (32-bit)
X
X# To use, enter "{d,n}make -f makefile.os2" (this makefile depends on its
X# name being "makefile.os2", and it must be in the main unzip directory).
X
X# Notes on Microsoft C 6.00 compilation for OS/2:
X#
X# The resulting programs can be used under OS/2 1.x or 2.x protected
X# mode only, not under DOS. A larger stack has to be used for OS/2
X# because system calls use more stack than under DOS; 8k is recommended
X# by Microsoft.
X
X# Notes on IBM C Set/2, Watcom C/386, Borland C++ or emx+gcc compilation:
X#
X# The resulting programs can be used under protected mode of OS/2 2.x
X# only, not under OS/2 1.x and not under DOS.
X#
X# The NFLAGS macro is used to work around an optimization bug in the IBM
X# C++ Set compiler; this is fixed by CSD #4, so NFLAGS="" can be used for
X# all targets below. We'll leave it as is for this release...
X#
X# For Watcom C/386, edit the os2$(OBJ) target so that os2/os2.c reads
X# os2\os2.c instead. Watcom can't handle forward slashes; gcc can't
X# handle backslashes. We'll see about making this a macro next time...


X
Xdefault:
X @echo "Enter `$(MAKE) -f makefile.os2 target' with makefile.os2 copied"
X @echo "to the main UnZip directory and where target is one of:"
X @echo " msc mscdos ibm ibmdyn ibmdebug ibmprof"

X @echo " watcom borland gcc gccdyn gccdebug gccdos"
X
X# MS C 6.00 for OS/2, 16-bit (should figure out way to split unzip/funzip
X# compiles so former is always large model and latter always small model...)
Xmsc:


X $(MAKE) -f makefile.os2 all \

X CC="cl -nologo -AL -Ocegit -Gs -I. $(FP)" \
X CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-Lp -Fe" \
X LDFLAGS2="-link /noe" \


X OUT="-Fo" \
X OBJ=".obj" \

X DEF="os2\unzip16.def"
X
X# cross-compilation for MS-DOS with MS C 6.00 (same comment as above...formerly;
X# now unzip is small model again, with [almost] all strings in far memory)
Xmscdos:


X $(MAKE) -f makefile.os2 all \

X CC="cl -nologo -AS -Oaict -Gs -I. $(FP)" \
X CFLAGS="-Zp1 -W3 $(LOCAL_UNZIP)" \
X NFLAGS="" \

X LDFLAGS="-F 0c00 -Lr -Fe" \


X LDFLAGS2="-link /noe /exe" \
X OUT="-Fo" \
X OBJ=".obj" \

X OBJU2="msdos.obj" \
X OBJX2="msdos_.obj"
X
X# IBM C Set/2, statically linked runtime
Xibm:


X $(MAKE) -f makefile.os2 all \

X CC="icc -Q -O -Gs -I." \
X CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="-O-" \
X LDFLAGS="-Fe" \


X LDFLAGS2="" \
X OUT="-Fo" \

X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X# IBM C Set/2, dynamically linked runtime
Xibmdyn:


X $(MAKE) -f makefile.os2 all \

X CC="icc -Q -O -Gs -Gd -I." \
X CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="-O-" \
X LDFLAGS="-Fe" \


X LDFLAGS2="" \
X OUT="-Fo" \

X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X# IBM C Set/2, debug version
Xibmdebug:


X $(MAKE) -f makefile.os2 all \

X CC="icc -Q -Ti -I." \
X CFLAGS="-Sm -Sp1 -D__DEBUG_ALLOC__ -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="-O-" \
X LDFLAGS="-Fe" \


X LDFLAGS2="" \
X OUT="-Fo" \

X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X# IBM C Set/2, profiling version for PROFIT
Xibmprof:


X $(MAKE) -f makefile.os2 all \

X CC="icc -Q -O -Gs -Gh -Ti -I." \
X CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="-O-" \
X LDFLAGS="-Fe" \
X LDFLAGS2="profit.obj" \
X OUT="-Fo" \
X OBJ=".obj" \
X DEF="os2\unzip.def"
X
X# Watcom C/386 9.0
Xwatcom:


X $(MAKE) -f makefile.os2 all \
X CC="wcl386 -zq -Ox -s -I." \
X CFLAGS="-Zp1 -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \

X LDFLAGS="-k0x40000 -x -Fe=" \


X LDFLAGS2="" \
X OUT="-Fo" \
X OBJ=".obj" \
X DEF=""
X
X# Borland C++
Xborland:

X $(MAKE) -f makefile.os2 all \

X CC="bcc -O -I." \
X CFLAGS="-w- -D__cdecl -D__32BIT__ -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-e" \
X LDFLAGS2="" \
X OUT="-o" \
X OBJ=".obj" \
X DEF="-sDos2\unzip.def"
X
X# emx 0.8f and later, gcc, OMF format, statically linked C runtime and emx
Xgcc:


X $(MAKE) -f makefile.os2 all \

X CC="gcc -Zomf -Zsys -O -I." \
X CFLAGS="-Wall -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-o ./" \
X LDFLAGS2="-s -los2" \
X OUT="-o" \
X OBJ=".obj" \
X DEF="os2/unzip.def"
X
X# emx 0.8g and later, gcc, OMF format, dynamically linked C runtime and emx
X# (for 0.8f or earlier, change -Zmtd to -Zmt)
Xgccdyn:


X $(MAKE) -f makefile.os2 all \

X CC="gcc -Zomf -Zmtd -O -I." \
X CFLAGS="-Wall -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-o ./" \
X LDFLAGS2="-s -los2" \
X OUT="-o" \
X OBJ=".obj" \
X DEF="os2/unzip.def"
X
X# emx, gcc, a.out format, with debug info for gdb
Xgccdebug:


X $(MAKE) -f makefile.os2 all \

X CC="gcc -g -I." \
X CFLAGS="-Wall -DOS2 $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-o ./" \
X LDFLAGS2="-los2" \
X OUT="-o" \
X OBJ=".o"
X
X# emx, gcc, a.out format, for MS-DOS
Xgccdos:


X $(MAKE) -f makefile.os2 all \

X CC="gcc -O -I." \
X CFLAGS="-Wall -DMSDOS $(LOCAL_UNZIP)" \
X NFLAGS="" \
X LDFLAGS="-o ./" \
X LDFLAGS2="-s" \
X OUT="-o" \
X OBJ=".o" \
X OBJU2="msdos.o" \
X OBJX2="msdos_.o"
X
X# variables
XOBJU = unzip$(OBJ) crypt$(OBJ) envargs$(OBJ) explode$(OBJ) \


X extract$(OBJ) file_io$(OBJ) inflate$(OBJ) match$(OBJ) \
X unreduce$(OBJ) unshrink$(OBJ) zipinfo$(OBJ)
XOBJU2 = os2$(OBJ)

XOBJX = unzip_$(OBJ) crypt$(OBJ) extract_$(OBJ) file_io$(OBJ) \


X inflate$(OBJ) match$(OBJ)
XOBJX2 = os2_$(OBJ)
XOBJF = funzip$(OBJ) crypt_$(OBJ) inflate_$(OBJ)
X

X.SUFFIXES: .c $(OBJ)
X
X.c$(OBJ):
X $(CC) -c $(CFLAGS) $<
X
Xall: unzip.exe funzip.exe unzipsfx.exe
X#all: unzipsfx.exe
X
Xunzip.exe: $(OBJU) $(OBJU2)
X $(CC) $(LDFLAGS)$@ $(DEF) $(OBJU) $(OBJU2) $(LDFLAGS2)
X
Xfunzip.exe: $(OBJF)
X $(CC) $(LDFLAGS)$@ $(DEF) $(OBJF) $(LDFLAGS2)
X
Xunzipsfx.exe: $(OBJX) $(OBJX2)
X $(CC) $(LDFLAGS)$@ $(DEF) $(OBJX) $(OBJX2) $(LDFLAGS2)
X
X
Xenvargs$(OBJ): envargs.c unzip.h
Xexplode$(OBJ): explode.c unzip.h
Xextract$(OBJ): extract.c unzip.h crypt.h
Xfile_io$(OBJ): file_io.c unzip.h crypt.h tables.h
Xfunzip$(OBJ): funzip.c unzip.h crypt.h tables.h
Xinflate$(OBJ): inflate.c unzip.h
Xmatch$(OBJ): match.c unzip.h
Xunreduce$(OBJ): unreduce.c unzip.h
Xunshrink$(OBJ): unshrink.c unzip.h
Xunzip$(OBJ): unzip.c unzip.h crypt.h version.h
Xzipinfo$(OBJ): zipinfo.c unzip.h
X
Xmsdos$(OBJ): msdos/msdos.c unzip.h # MS-DOS only
X $(CC) -c $(CFLAGS) msdos/msdos.c
X
Xmsdos_$(OBJ): msdos/msdos.c unzip.h # MS-DOS unzipsfx only
X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ msdos/msdos.c
X
Xos2$(OBJ): os2/os2.c unzip.h # OS/2 only
X $(CC) -c $(CFLAGS) os2/os2.c
X
Xos2_$(OBJ): os2/os2.c unzip.h # OS/2 unzipsfx only
X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ os2/os2.c
X
X# NFLAGS are solely used as work-around for optimization bug in IBM C++ Set
Xcrypt$(OBJ): crypt.c unzip.h crypt.h zip.h
X $(CC) -c $(CFLAGS) $(NFLAGS) crypt.c
X
Xcrypt_$(OBJ): crypt.c unzip.h zip.h crypt.h # funzip only
X $(CC) -c $(CFLAGS) $(NFLAGS) -DFUNZIP $(OUT)$@ crypt.c
X
Xextract_$(OBJ): extract.c unzip.h crypt.h # unzipsfx only
X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ extract.c
X
Xinflate_$(OBJ): inflate.c inflate.h unzip.h crypt.h # funzip only


X $(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ inflate.c
X

Xunzip_$(OBJ): unzip.c unzip.h crypt.h version.h # unzipsfx only


X $(CC) -c $(CFLAGS) -DSFX $(OUT)$@ unzip.c

END_OF_FILE
if test 7372 -ne `wc -c <'unzip-5.12/os2/makefile.os2'`; then
echo shar: \"'unzip-5.12/os2/makefile.os2'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/makefile.os2'
fi
if test -f 'unzip-5.12/vms/unzip_cli.help' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unzip_cli.help'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unzip_cli.help'\" \(8254 characters\)
sed "s/^X//" >'unzip-5.12/vms/unzip_cli.help' <<'END_OF_FILE'
X.!
X.! File: UNZIP_CLI.HELP
X.!
X.! Author: Hunter Goatley
X.!
X.! Date: 12 Jul 94 (orig. UNZIP.RNH, 23 Oct 91)
X.!
X.! Description:
X.!
X.! TPU-processable source file to produce VMS on-line help for
X.! portable UnZip. Adapted from UNZIP.RNH, originally based on
X.! UNZIP.MAN (now UNZIP.DOC).
X.!
X.! To build:
X.! $ EDIT /TPU/NOSECTION/NODISPLAY/COMMAND=CVTHELP.TPU UNZIP_CLI.HELP
X.! $ REN UNZIP_CLI.RNH UNZIP.RNH
X.! $ RUNOFF UNZIP.RNH
X.! $ LIBR /HELP/INSERT libr UNZIP
X.!
X.! Modification history:
X.!
X.! 02-001 Hunter Goatley 12-JUL-1994 16:59
X.! Genesis.
X.! 02-002 Cave Newt 14-JUL-1994 11:36
X.! Fixed /*TEXT options and added/removed various options.
X.! 02-003 Cave Newt 28-JUL-1994 08:54
X.! Removed semicolons from comments and moved /ZIPINFO.
X.!
X<INIT>
X<MAIN>
XUNZIP
X
XUnZip is used to extract files compressed and packaged by Zip (see HELP ZIP
Xfor information on ZIP).
X
XFor a brief help on Zip and Unzip, run each without specifying any
Xparameters on the command line.
X
XUNZIP will list, test, or extract from a ZIP archive. ZIP archives are commonly
Xfound on MS-DOS systems; a VMS version of ZIP can also be found here.
X
XArchive member extraction is implied by the absence of the -c, -p, -t, -l, -v or
X-z options. All archive members are processed unless a filespec is provided to
Xspecify a subset of the archive members.
X<FORMAT>
XUNZIP zipfile [file[,...]] [/qualifiers]
X
X.!
X<TOPIC>
XParameters
X
X<PARAMETER>
Xzipfile
X
X<PTEXT>
XFile specification for the ZIP archive(s) with optional wildcards. UnZip will
Xperform actions specified for every zipfile matching the specification.
XThe default file specification is SYS$DISK:[].ZIP.
X
XNote that self-extracting ZIP files are supported; just specify the .EXE
Xsuffix yourself.
X<TXETP>
X
X<PARAMETER>
Xfile
X
X<PTEXT>
XAn optional comma-separated list of archive members to be processed;
Xif no list is given, all archive members are processed. Expressions
Xmay be used to match multiple members. Expressions should be enclosed
Xin double-quotes to prevent interpretation by DCL. Multiple filenames
Xshould be separated by blanks. Each file specification is similar to
Xa Unix egrep expression and may contain:
X
X<LITERAL>


X|* matches a sequence of 0 or more characters

X|? matches exactly 1 character
X|[...] matches any single character found inside the brackets;
X| ranges are specified by a beginning character,
X| a hyphen, and an ending character. If a '!' or '^'
X| immediately follows the left bracket, then any character
X| not in the given range is matched.
X<LARETIL>
X<TXETP>
X
X<QUALIFIERS>
X<QUALIFIER>
X/ZIPINFO
X
X/ZIPINFO
X
XDisplays information about the Zip archive and the files contained therein.
XThis function used to be provided by a separate ZipInfo program.
X
XThe following qualifiers may be specified with /ZIPINFO:
X
X<LITERAL>
X| /SHORT Short UNIX "ls -l" format (default)
X| /MEDIUM Medium UNIX "ls -l" format
X| /LONG Long UNIX "ls -l" format
X| /ONE_LINE Filenames only, one per line
X| /VERBOSE Verbose, multi-page format
X| /HEADER Print header lines
X| /TOTALS Print totals for files
X| /TIMES Print file times in sortable decimal format
X<LARETIL>
X<QUALIFIER>
X/AUTOTEXT
X
X/AUTOTEXT
X/NOAUTOTEXT
X
XAutomatically extracts files marked as "text" (rather than "binary") in
Xin standard VMS text file format.
X<QUALIFIER>
X/BRIEF
X
X/BRIEF
X
XWhen used with /LIST, specifies that a brief listing of the archive's
Xcontents is to be displayed. A brief listing shows the length, date,
Xtime, and file name for the files in the archive.
X<QUALIFIER>
X/CASE_INSENSITIVE
X
X/CASE_INSENSITIVE
X/NOCASE_INSENSITIVE
X
XMatch filenames case-insensitively. (Good default option under VMS.)
X<QUALIFIER>
X/COMMENT
X
X/COMMENT
X/NOCOMMENT
X
XDisplay the archive comment.
X<QUALIFIER>
X/DIRECTORY
X
X/DIRECTORY=directory-spec
X
XSpecifies the output directory where all the extracted files are to be
Xplaced.
X<QUALIFIER>
X/EXCLUDE
X
X/EXCLUDE=file
X
XA comma-separated list of files to exclude when extracting files.
XIf multiple files are specified, the list should be included in
Xparentheses.
X
X<QUALIFIER>
X/FRESHEN
X
X/FRESHEN
X/NOFRESHEN
X
XFreshen existing files; replace if newer. Does not cause any new files to
Xbe created.
X<QUALIFIER>
X/FULL
X
X/FULL
X
XWhen used with /LIST, specifies that a full listing of the archive's
Xcontents is to be displayed. A full listing shows the length,
Xcompression method, compressed size, compression ratio, date,
Xtime, CRC value, and file name for the files in the archive.
X<QUALIFIER>
X/JUNK
X
X/JUNK
X/NOJUNK
X
XJunk the stored paths (don't recreated the archive's directory
Xstructure.
X<QUALIFIER>
X/LIST
X
X/LIST
X
XList the contents of the archive. /BRIEF and /FULL can be used to
Xspecify the amount of information displayed. The default is /BRIEF.
X<QUALIFIER>
X/LOWERCASE
X
X/LOWERCASE
X/NOLOWERCASE
X
XConvert filenames from all-uppercase operating systems to lowercase. This
Xoption has no effect under VMS.
X<QUALIFIER>
X/OVERWRITE
X
X/OVERWRITE
X/NOOVERWRITE
X
XOverwrite existing files when extracting.
X<QUALIFIER>
X/PIPE
X
X/PIPE
X
XExtract files to SYS$OUTPUT with no informational messages.
X<QUALIFIER>
X/QUIET
X
X/QUIET
X
XPerform operations quietly. /SUPER_QUIET can be specified to make it
Xeven quiet.
X<QUALIFIER>
X/RESTORE
X
X/RESTORE
X/NORESTORE
X
XRestore file owner and protection settings.
X<QUALIFIER>
X/SCREEN
X
X/SCREEN
X/NOSCREEN
X
XExtracts matching files to SYS$OUTPUT (the terminal).
X<QUALIFIER>
X/SUPER_QUIET
X
X/SUPER_QUIET
X
XPerform operations super-quietly.
X<QUALIFIER>
X/TEST
X
X/TEST
X/NOTEST
X
XTest archive files.
X<QUALIFIER>
X/TEXT
X
X/TEXT
X/NOTEXT
X
XExtracts all files in standard VMS text file format.
X<QUALIFIER>
X/UPDATE
X
X/UPDATE
X/NOUPDATE
X
XUpdate existing files; create new ones if needed.
X<QUALIFIER>
X/VERSION
X
X/VERSION
X/NOVERSION
X
XRetain VMS file version numbers.
X
X<TOPIC>
XAuthors
X
XInfo-ZIP; currently maintained by Greg Roelofs. VMS support maintained
Xby Igor Mandrichenko and Hunter Goatley. Originally based on a program
Xby Samuel H. Smith.
X
XVMS on-line help ported from UNZIP.DOC by Hunter Goatley.
X
X<TOPIC>
XUNIX_Options
X
XThe default action of UnZip is to extract all zipfile entries. The following
Xoptions and modifiers can be provided:
X
X<LITERAL>
X| -Z ZipInfo mode
X| -c extract files to SYS$OUTPUT (terminal)
X| -f freshen existing files (replace if newer); create none


X| -l list archive files (short format)

X| -p extract files to SYS$OUTPUT; no informational messages
X| -t test archive files
X| -u update existing files; create new ones if needed
X| -v list archive files (verbose format)


X| -z display only the archive comment

X|
X| MODIFIERS
X| -a auto-extract only text files in standard VMS text file format
X| -aa extract all files as text
X| -j junk paths (don't recreate archive's directory structure)
X| -n never overwrite existing files; don't prompt
X| -o OK to overwrite files without prompting


X| -q perform operations quietly (-qq => even quieter)

X| -C match filenames case-insensitively
X| -L convert filenames to lowercase if created under MS-DOS, VMS, etc.
X| -V retain (VMS) file version numbers
X| -X restore owner/protection info (may require privileges)
X<LARETIL>
X
XNote that uppercase options such as -C, -L, -V, -X and -Z must be specified
Xin quotes. For example:
X
X<LITERAL>
X| $ unzip "-VX" -a zipfile
X<LARETIL>
X
X.![this should probably be a separate section]:
XIn addition, default options may be specified via the UNZIP_OPTS logical.
XFor example, the following will cause UnZip to match filenames without regard
Xto case, restore owner/protection information and perform all operations at
Xquiet-level 1 by default:
X
X<LITERAL>
X| $ define UNZIP_OPTS "-qCX"
X<LARETIL>
X
XNote that the quotation marks here are required to preserve lowercase options
X(opposite of the command-line behavior). To negate a default option on the
Xcommand line, add one or more minus signs before the option letter, in
Xaddition to the leading switch character `-':
X
X<LITERAL>
X| $ unzip --ql zipfile
X<LARETIL>
X
Xor
X
X<LITERAL>
X| $ unzip -l-q zipfile
X<LARETIL>
X
XAt present it is not possible to decrement an option below zero--that is,
Xmore than a few minuses have no effect.
X
XUNZIP_OPTS may be defined as a symbol rather than a logical, but if both
Xare defined, the logical is used.
END_OF_FILE
if test 8254 -ne `wc -c <'unzip-5.12/vms/unzip_cli.help'`; then
echo shar: \"'unzip-5.12/vms/unzip_cli.help'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unzip_cli.help'
fi
echo shar: End of archive 17 \(of 20\).
cp /dev/null ark17isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:17:01 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 83
Archive-name: unzip/part18

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/BUGS unzip-5.12/History.512
# unzip-5.12/amiga/SMakeFile unzip-5.12/envargs.c
# unzip-5.12/os2/unzip16.def unzip-5.12/tables.h
# unzip-5.12/tops20/tops20.c unzip-5.12/unix/funzip.1
# unzip-5.12/unreduce.c unzip-5.12/vms/README
# unzip-5.12/vms/cvthelp.tpu unzip-5.12/vms/descrip.mms
# unzip-5.12/vms/unzip_def.rnh
# Wrapped by kent@sparky on Sat Sep 17 23:33:48 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 18 (of 20)."'
if test -f 'unzip-5.12/BUGS' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/BUGS'\"
else
echo shar: Extracting \"'unzip-5.12/BUGS'\" \(4786 characters\)
sed "s/^X//" >'unzip-5.12/BUGS' <<'END_OF_FILE'
XBogus bugs (not our fault!):
X---------------------------
X
X By far THE BIGGEST source of bug reports to Info-ZIP/zip-bugs is the
X incorrect transfer of zipfiles (or of the UnZip executable itself).
X ALWAYS TRANSFER IN BINARY MODE! This includes ftp transfers and *both*
X ends of a Kermit connection ("set file type binary"). If your copy
X isn't exactly the same size as the original, you made a mistake.
X
X Another common source of errors such as "compression method 8 not sup-
X ported" is the existence of an old version of UnZip somewhere in your
X path. Make sure you're using the version you think you're using; give
X the full path explicitly if necessary. Executing "unzip" without any
X options will print a help screen, at the top of which is the UnZip
X version number and release date; and executing "unzip -v" without any
X zipfile or other options will give information about what compiler was
X used, the target operating system, any special UnZip options, and the
X date of compilation--only for version 5.11 and later, though! (Also,
X under Unix C shell and some Bourne shells, "which unzip" will print
X the path of the unzip you're actually using. Under OS/2 and MS-DOS,
X whch21gr.zip [on SimTel mirror sites] will do the same thing; in addi-
X tion, "which -a unzip" will show *all* copies of unzip in your path.)
X
X
XBugs (real and/or imagined):
X---------------------------
X
X - MKS Korn shell: unzip assumes the MKS-style command-line environment
X options are relevant to it, but this is not the case if unzip was called
X by another program (e.g., from a .BAT file). A fix for this exists for
X Borland compilers but not for MSC, Watcom, djgpp, etc.
X - OS/2: for paths with one long component, the .LONGNAME EA may be saved for
X all components (waste of disk space): how to check??
X - VMS: for extracting to other directories, only the VMS-style "-d [.foo]"
X format is accepted; "-d foo" should also be allowed. Long filenames are
X not automatically truncated to 39.39. Even with -o specified, the user
X is queried before overwriting; without -o, there are two levels of query.
X - Novell Netware: Netware drives may clear the archive bit on extracted
X files under OS/2 and/or MS-DOS. UnZip always *tries* to set the archive
X bit, however. [pynq@uchicago, 940527]
X - DEC Ultrix: on long zipfiles, unzip will sometimes fail (bad CRC, not always
X reproducible); this is apparently due either to a hardware bug (cache mem)
X or OS bug (page faults?) [Igor, Jean-loup, bottom of BUGS.long]
X - Pyramid: USE_FWRITE causes CRC errors (???) [Kevin]
X - funzip/more/decryption/no-echo bug: race condition(?) causes terminal to
X be "reset" to no-echo state
X - directory dates/times (special Unix perms?) not restored
X - Macintosh (100200), Atari (020000) external file attributes not interpreted
X correctly (both unzip and zipinfo)
X - pkbug error: zipfile with incorrect csize and/or ucsize--check for end of
X compressed (csize) data in uncompression routines:
X unreduce.c: while (((outpos + outcnt) < ucsize) && (!zipeof)) {
X [James Birdsall, Mark, bottom of BUGS.long]
X - OS/2: directory EAs not restored if directory exists [Kai Uwe, KG27515@uark]
X (subsequent note: no way to determine which EAs are newer ==> cannot
X restore without user input)
X - MS-DOS: Borland executables don't allow other than 80-column, 25/43/50-line
X screen modes (Borland bug) [Michael Stillwell]
X
X
XFeatures (possible and/or definite):
X-----------------------------------
X
X - put man pages in more "proper" nroff format
X - ignore case for internal filename match on non-Unix systems, unless file-
X specs enclosed in single quotes
X - save/extract Unix mtime/ctime/atime/UID/GID info (Unix extra field)
X - modify to decompress input stream if part of a pipe, but continue using
X central directory if not (BIG job!)--extended local header capability
X - add zipinfo option(s) to sort alphabetically, by date/time, in reverse, etc.
X - add "near" to global vars [Steve Salisbury, 92.4.21]
X - modify set_file_time routines to share common code (macro?)
X - when listing filenames, use '?' for non-printables? [Thomas Wolff, 92.6.1]
X - add zipinfo "in-depth" option? (check local vs. central filenames, etc.)
X - create zipcat program to concatenate zipfiles
X - assembly-language routines?
X - VM/CMS version (Walter Moore, Phil Howard, Chua Kong Sian, others)
X - add -oo option (overwrite and override)? no user queries (if bad password,
X skip file; if disk full, take default action; if VMS special on non-VMS,
X unpack anyway; etc.)
X - add -Q[Q[Q]] option (quiet mode on comments, cautions, warnings and errors)?
X forget -oo, or make synonym? Default level -Q?
X - add OS/2 .INF format helpfiles for UnZip and ZipInfo?
END_OF_FILE
if test 4786 -ne `wc -c <'unzip-5.12/BUGS'`; then
echo shar: \"'unzip-5.12/BUGS'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/BUGS'
fi
if test -f 'unzip-5.12/History.512' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/History.512'\"
else
echo shar: Extracting \"'unzip-5.12/History.512'\" \(4654 characters\)
sed "s/^X//" >'unzip-5.12/History.512' <<'END_OF_FILE'
XUnZip, version 5.12, 28 August 1994
X
XNew features, you betcha:
X
X5.12a:
X - added zipinfo patch for empty space within zipfile (Novell/PKZIP bug); moved
X newzip variable out of crypt.[ch] [CN]
X - MS-DOS, OS/2: added EMX, EMXOPT, GO32 and GO32TMP environment-variable info
X to unzip -v output [CN]
X - OS/2: replaced watcom.dif with wat_met.dif (support for Metaware C++ as
X well as 16/32-bit Watcom) [Kai Uwe]
X5.12b:
X - added another acknowledgment example to COPYING [CN]
X - VMS: modified VMSWILD to use () instead of [] for sets; had been disallowed
X entirely [Charles Bailey, CN]
X - VMS: added .hlp file for unzipsfx and MAKESFX.COM script [Martin Zinser]
X5.12c:
X - MS-DOS: updated README with djgpp 1.12 and QEMM 7.04 info [CN, Kevin
X Fritz]
X - added timezone-debugging code to file_io.c (define DEBUG_TIME) [CN]
X - MS-DOS: updated gcc_dos Makefile target and README to include notes about
X GNU make and djgpp timezone bugs [CN]
X - changed "unzip -v" to print only version*100 if -qqqq (or greater) [CN]
X - changed all putc/putchar calls to PUTC macro for future DLL use [CN]
X - Unix, NT: changed all local printf/fprintf calls to macros; deleted a bunch
X of OS/2 stuff in nt.c [CN]
X - updated README to note Kevin's finding: 32-bit DOS UnZip *faster* than
X PKUNZIP on most archives...whoa. [CN, Keven F]
X - added SFX_EXDIR option to allow use of -d in UnZipSFX [CN]
X5.12d:
X - Mac: updated version numbers in *.hqx files [Antoine]
X - MS-DOS: added _gcc_dos_new sub-target to unix/Makefile, to be used when
X djgpp 1.12m1 is released (new coff2exe -g option) [CN]
X - added AOL info to Where file [Audrey Beck, CN]
X - removed obsolete DEBUG_STRUC code [CN]
X - added regulus target and zstat() function [Paul Klahr, CN]
X - updated docs, version numbers for release [CN]
X - VMS: last(!) Ident and clean: tweaks [Igor, Christian, Hunter]
X5.12e:
X - Unix: changed "strip" to "$(STRIP)" for easier debugging [Marty Leisner]
X - MS-DOS: updated msdos/README with djgpp 1.12m1 timezone fixes info [CN]
X
XBugs fixed:
X
X5.12a:
X - ifdef'd two unused string variables in non-crypt extract.c [CN]
X - put newzip back into crypt.h: CRYPT not yet defined in unzip.h [CN]
X - fixed unzipsfx bug: first filespec ignored [Paul Weiss, CN]
X - updated unzipsfx man page to note problem with "foo -x *.c" [CN, Paul Weiss]
X5.12b:
X - VMS: updated Where file entry for VMS ftp sites [Brian Tillman, Hunter]
X - updated README.CR and INSTALL to note that zipcloak is for zip sources only
X [CN, Richard Lloyd]
X - fixed -d bug w.r.t. extraction to / (all but VMS, TOPS-20) [CN, Piet]
X - Amiga, Mac, etc.: fixed non-OLD_EXDIR bug [CN]
X - OS/2, MS-DOS: removed left-over EMX,EMXOPT notes [CN]
X - VMS: fixed VMS_SEVERITY return values [Charles Bailey]
X - VMS: fixed(?) MAKE.COM to check for DEC C and use VAXC option [CN, Hunter]
X5.12c:
X - VMS: fixed various descrip.mms bugs [Christian Spieler]
X - MS-DOS: added LOCAL_UNZIP support to makefile.msc and makefile.bc;
X fixed MED_MEM typo in unzip.h [Christian]
X - moved extern declaration of CompiledWith[] from unzip.h into local files
X (avoid VMS warnings) [CN, Christian]
X - fixed one overlooked fprintf/FPRINTF macro in unzip.h [CN]
X - VMS: fixed /DIRECTORY bug; fixed __DEBUG__ stuff in descrip.mms [Igor]
X - VMS: tweaked RETURN_SEVERITY levels some more [CN, Christian, Igor, Rodney]
X - documented -b option in unzip.1 and UnZipSFX usage line [CN]
X - fixed a bunch of broken Trace() statements in extract.c [Christian]
X5.12c2:
X - VMS: real fix for do_wild() bug [Christian]
X5.12d:
X - swapped two PUTC's for a PRINTF in zipinfo.c [CN]
X - VMS: removed incorrect Where file info [Hunter]
X - VMS: fixed do_wild() and descrip.mms again [Christian, CN]
X - MS-DOS: updated INSTALL and Makefile to note problems with long command
X lines and LOCAL_UNZIP [Piet, CN]
X - VMS: fixed make.com [Rodney, Hunter, CN, Christian]
X - VMS: fixed cmdline.c double usage() bug with unzipsfx, VMSCLI [Rodney, CN]
X - VMS: added lots of typecasts and fixed some initializers for DEC C; added
X a newline to an inflate.c debug line [Christian]
X - MS-DOS: improved gcc_dos target's creation of empty zipinfo file via FIND
X instead of COPY [Jean-loup, Kai Uwe]
X - added some more typecasts [CN, Kai Uwe]
X5.12e:
X - fixed explode.c comment (long-lost patch from Feb 93, blush...) [Mark]
X - VMS: fixed makefiles for unzipsfx+VMSCLI [CN, Hunter]
X
X==================
X
XThese changes occurred in beta versions 5.12a to 5.12e. This list may have
Xleft out some bugfixes and even some features...the brain cell is going,
Xfolks (as Mark would say). Apologies, etc.


X
XGreg Roelofs (a.k.a. Cave Newt)

END_OF_FILE
if test 4654 -ne `wc -c <'unzip-5.12/History.512'`; then
echo shar: \"'unzip-5.12/History.512'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/History.512'
fi
if test -f 'unzip-5.12/amiga/SMakeFile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/SMakeFile'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/SMakeFile'\" \(4286 characters\)
sed "s/^X//" >'unzip-5.12/amiga/SMakeFile' <<'END_OF_FILE'
X#===========================================================================
X# Makefile for UnZip, ZipInfo & fUnZip: AMIGA SAS/C Version 6.x
X# Version: 5.11 9 July 1993
X#===========================================================================
X# John Bush <john...@east.sun.com> last modified: 10 Jul 94
X#---------------------------------------------------------------------------


X
X#####################
X# MACRO DEFINITIONS #
X#####################
X

X# Compiler and loader debug flags. Uncomment as needed. Recomment when done.
X#
X# CDBG = DEBUG=L DEF=DEBUG
X# LDBG = ADDSYM
X# LMAP = MAP AMIGA/UNZIP.MAP
X
X# Compiler definitions
X#
XCC = sc
X#
XOPT = OPT OPTINL OPTINLOCAL OPTTIME OPTCOMP=5 OPTDEP=5 OPTRDEP=5
X#
X# Choose one DATAOPTS & SASLIB. NOTE! only DATA=FAR is known to work!
X#
XDATAOPTS = DATA=FAR # link with SCNB.lib
XSASLIB = scnb
X# DATAOPTS = DATA=FAR SINT # link with SCSNB.lib [not working yet!]
X# SASLIB = scsnb
X# DATAOPTS = DATA=NEAR # link with SC.lib
X# SASLIB = sc
X#
XCDEFINES = DEF=AMIGA DEF=PROTO
XCOPTIONS = $(DATAOPTS) NOSTKCHK STRMERGE CPU=ANY CODE=NEAR NMINC UNSCHAR
XCOPTIONS = $(COPTIONS) ERRORREXX NOERRORCONSOLE NOICONS
X#
XCFLAGS = $(CDEFINES) $(COPTIONS) $(CDBG) $(OPT)
X
X# Linker definitions
X# See SASLIB definition above
X#
XLD = slink
XLDFLAGS = FROM LIB:c.o
XLDFLAGS2 = NOICONS $(LDBG) $(LMAP)
XLIBFLAGS = LIB LIB:$(SASLIB).lib+LIB:amiga.lib
X
X# UnZip Objects
X#
XOBJS1 = unzip.o crypt.o envargs.o explode.o extract.o file_io.o
XOBJS2 = inflate.o match.o unreduce.o unshrink.o zipinfo.o
XOBJSA = amiga.o
XOBJS = $(OBJS1) $(OBJS2) $(OBJSA)
XLOBJS = $(OBJS)
X
X# UnZipSFX Objects
XOBJX = unzip_x.o crypt.o extract_x.o file_io.o inflate.o match.o amiga_x.o
X
X# fUnZip Objects
XOBJF = funzip.o crypt_f.o inflate_f.o
X
X# Output targets
XUNZIPS = unzip unzipsfx funzip
X
X# Temp filename for object lists to load using linker "WITH" command.
XOBJLIST = ram:OBJLIST.TMP
X
X#######################################
X# DEFAULT TARGET AND PROCESSING RULES #
X#######################################
X
Xall: $(UNZIPS)
X
X.c.o :
X $(CC) $(CFLAGS) OBJNAME=$@ $*.c
X
X
X#########################
X# Final output targets. #
X#########################
X
X# NOTE: When generating MAP files, don't make "all" because only the last
X# map generated will be the one that remains after this is finished.
X# Or, put specific MAP statements in below for each.
X
Xunzip: $(OBJS)
X echo "$(OBJS)" >$(OBJLIST)
X $(LD) TO UnZip $(LDFLAGS) WITH $(OBJLIST) $(LIBFLAGS) $(LDFLAGS2)
X
Xunzipsfx: $(OBJX)
X echo "$(OBJX)" >$(OBJLIST)
X $(LD) TO UnZipSFX $(LDFLAGS) WITH $(OBJLIST) $(LIBFLAGS) $(LDFLAGS2)
X
Xfunzip: $(OBJF)
X echo "$(OBJF)" >$(OBJLIST)
X $(LD) TO fUnZip $(LDFLAGS) WITH $(OBJLIST) $(LIBFLAGS) $(LDFLAGS2)
X
Xclean:
X -delete >nil: $(OBJS1)
X -delete >nil: $(OBJS2)
X -delete >nil: $(OBJSA)
X -delete >nil: $(OBJF)
X
Xspotless: clean
X -delete >nil: UnZip UnZipSFX fUnZip
X
X# special rules for objects used in UnZipSFX and fUnZip
X#
Xunzip_x.o: unzip.c unzip.h version.h
X $(CC) DEF=SFX $(CFLAGS) OBJNAME=unzip_x.o unzip.c
X
Xextract_x.o: extract.c unzip.h crypt.h
X $(CC) DEF=SFX $(CFLAGS) OBJNAME=extract_x.o extract.c
X
Xamiga_x.o: amiga/amiga.c amiga/amiga.h
X $(CC) DEF=SFX $(CFLAGS) OBJNAME=amiga_x.o amiga/amiga.c
X
Xcrypt_f.o: crypt.c unzip.h zip.h crypt.h
X $(CC) DEF=FUNZIP $(CFLAGS) OBJNAME=crypt_f.o crypt.c
X
Xinflate_f.o: inflate.c inflate.h unzip.h crypt.h
X $(CC) DEF=FUNZIP $(CFLAGS) OBJNAME=inflate_f.o inflate.c
X
X# objects common to all revisions/ports:
X#
Xcrypt.o: crypt.c unzip.h zip.h crypt.h
Xenvargs.o: envargs.c unzip.h
Xexplode.o: explode.c unzip.h
Xextract.o: extract.c unzip.h crypt.h
Xfile_io.o: file_io.c unzip.h crypt.h tables.h
Xfunzip.o: funzip.c unzip.h crypt.h tables.h
Xinflate.o: inflate.c inflate.h unzip.h
Xmatch.o: match.c unzip.h
Xshared.o: shared.c unzip.h
Xunreduce.o: unreduce.c unzip.h
Xunshrink.o: unshrink.c unzip.h
Xunzip.o: unzip.c unzip.h version.h
Xzipinfo.o: zipinfo.c unzip.h
X
X
X# objects specific to Amiga
Xamiga.o: amiga/amiga.c amiga/amiga.h
X
END_OF_FILE
if test 4286 -ne `wc -c <'unzip-5.12/amiga/SMakeFile'`; then
echo shar: \"'unzip-5.12/amiga/SMakeFile'\" unpacked with wrong size!
fi
chmod +x 'unzip-5.12/amiga/SMakeFile'
# end of 'unzip-5.12/amiga/SMakeFile'
fi
if test -f 'unzip-5.12/envargs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/envargs.c'\"
else
echo shar: Extracting \"'unzip-5.12/envargs.c'\" \(6181 characters\)
sed "s/^X//" >'unzip-5.12/envargs.c' <<'END_OF_FILE'
X/*----------------------------------------------------------------*
X | envargs - add default options from environment to command line
X |----------------------------------------------------------------
X | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
X | This program is in the public domain.
X |----------------------------------------------------------------
X | Minor program notes:
X | 1. Yes, the indirection is a tad complex
X | 2. Parenthesis were added where not needed in some cases
X | to make the action of the code less obscure.
X | 3. Set tabsize to four to make this pretty
X |----------------------------------------------------------------
X | UnZip notes: 24 May 92 ("v1.4"):
X | 1. #include "unzip.h" for prototypes (24 May 92)
X | 2. changed ch to type char (24 May 92)
X | 3. added an ifdef to avoid Borland warnings (24 May 92)
X | 4. included Rich Wales' mksargs() routine (for MS-DOS, maybe
X | OS/2? NT?) (4 Dec 93)
X | 5. added alternate-variable string envstr2 (21 Apr 94)
X *----------------------------------------------------------------*/


X
X
X#include "unzip.h"
X

Xstatic int count_args __((char *));
Xstatic void mem_err __((void));
X
X#if (defined(SCCS) && !defined(lint)) /* causes warnings: annoying */
X static char *SCCSid = "@(#)envargs.c 1.3 23 Oct 1991";
X#endif
X
Xstatic char Far NoMemArguments[] = "envargs: can't get memory for arguments";
X
X
X
Xvoid envargs(Pargc, Pargv, envstr, envstr2)
X int *Pargc;
X char ***Pargv, *envstr, *envstr2;
X{
X char *getenv();
X char *envptr; /* value returned by getenv */
X char *bufptr; /* copy of env info */
X int argc = 0; /* internal arg count */
X char ch; /* spare temp value */
X char **argv; /* internal arg vector */
X char **argvect; /* copy of vector address */
X
X /* see if anything in either of valid environment variables */
X if ((envptr = getenv(envstr)) == (char *)NULL || *envptr == 0)
X if ((envptr = getenv(envstr2)) == (char *)NULL || *envptr == 0)
X return;
X
X /* count the args so we can allocate room for them */
X argc = count_args(envptr);
X bufptr = (char *)malloc(1+strlen(envptr));
X if (bufptr == (char *)NULL)
X mem_err();
X strcpy(bufptr, envptr);
X
X /* allocate a vector large enough for all args */
X argv = (char **)malloc((argc+*Pargc+1)*sizeof(char *));
X if (argv == (char **)NULL)
X mem_err();
X argvect = argv;
X
X /* copy the program name first, that's always true */
X *(argv++) = *((*Pargv)++);
X
X /* copy the environment args next, may be changed */
X do {
X *(argv++) = bufptr;
X /* skip the arg and any trailing blanks */
X while (((ch = *bufptr) != '\0') && ch != ' ')
X ++bufptr;
X if (ch == ' ')
X *(bufptr++) = '\0';
X while (((ch = *bufptr) != '\0') && ch == ' ')
X ++bufptr;
X } while (ch);
X
X /* now save old argc and copy in the old args */
X argc += *Pargc;
X while (--(*Pargc))
X *(argv++) = *((*Pargv)++);
X
X /* finally, add a NULL after the last arg, like UNIX */
X *argv = (char *)NULL;
X
X /* save the values and return */
X *Pargv = argvect;
X *Pargc = argc;
X}
X
X
X
Xstatic int count_args(s)
X char *s;
X{
X int count = 0;
X char ch;
X
X do {
X /* count and skip args */
X ++count;
X while (((ch = *s) != '\0') && ch != ' ')
X ++s;
X while (((ch = *s) != '\0') && ch == ' ')
X ++s;
X } while (ch);
X
X return count;
X}
X
X
X
Xstatic void mem_err()
X{
X perror(LoadFarString(NoMemArguments));
X exit(2);


X}
X
X
X
X#ifdef TEST

X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X int i;
X
X printf("Orig argv: %p\n", argv);
X dump_args(argc, argv);
X envargs(&argc, &argv, "ENVTEST");
X printf(" New argv: %p\n", argv);
X dump_args(argc, argv);
X}
X
X
X
Xdump_args(argc, argv)


X int argc;
X char *argv[];
X{

X int i;
X
X printf("\nDump %d args:\n", argc);
X for (i = 0; i < argc; ++i)
X printf("%3d %s\n", i, argv[i]);
X}
X
X#endif /* TEST */
X
X
X
X#ifdef MSDOS /* DOS_OS2? DOS_NT_OS2? */
X
X/*
X * void mksargs(int *argcp, char ***argvp)
X *
X * Substitutes the extended command line argument list produced by
X * the MKS Korn Shell in place of the command line info from DOS.
X *
X * The MKS shell gets around DOS's 128-byte limit on the length of
X * a command line by passing the "real" command line in the envi-
X * ronment. The "real" arguments are flagged by prepending a tilde
X * (~) to each one.
X *
X * This "mksargs" routine creates a new argument list by scanning
X * the environment from the beginning, looking for strings begin-
X * ning with a tilde character. The new list replaces the original
X * "argv" (pointed to by "argvp"), and the number of arguments
X * in the new list replaces the original "argc" (pointed to by
X * "argcp").
X *
X * Rich Wales
X */
Xvoid mksargs(argcp, argvp)
X int *argcp;
X char ***argvp;
X{
X#ifndef MSC /* declared differently in MSC 7.0 headers, at least */


X extern char **environ; /* environment */

X#endif


X char **envp; /* pointer into environment */
X char **newargv; /* new argument list */

X char **argp; /* pointer into new arg list */
X int newargc; /* new argument count */
X
X /* sanity check */
X if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
X return;
X
X /* find out how many environment arguments there are */
X for (envp = environ, newargc = 0; *envp != NULL && (*envp)[0] == '~';
X envp++, newargc++)
X ;
X if (newargc == 0)
X return; /* no environment arguments */
X
X /* set up new argument list */
X newargv = (char **) malloc(sizeof(char **) * (newargc+1));
X if (newargv == NULL)
X return; /* malloc failed */
X
X for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
X *argp++ = &(*envp++)[1])
X ;
X *argp = NULL; /* null-terminate the list */
X
X /* substitute new argument list in place of old one */
X *argcp = newargc;
X *argvp = newargv;
X}
X
X#endif /* MSDOS */
END_OF_FILE
if test 6181 -ne `wc -c <'unzip-5.12/envargs.c'`; then
echo shar: \"'unzip-5.12/envargs.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/envargs.c'
fi
if test -f 'unzip-5.12/os2/unzip16.def' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/unzip16.def'\"
else
echo shar: Extracting \"'unzip-5.12/os2/unzip16.def'\" \(106 characters\)
sed "s/^X//" >'unzip-5.12/os2/unzip16.def' <<'END_OF_FILE'
XNAME WINDOWCOMPAT NEWFILES
XDESCRIPTION 'The world-famous Info-ZIP unarchiving utilities'
XSTACKSIZE 0x2000
END_OF_FILE
if test 106 -ne `wc -c <'unzip-5.12/os2/unzip16.def'`; then
echo shar: \"'unzip-5.12/os2/unzip16.def'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/unzip16.def'
fi
if test -f 'unzip-5.12/tables.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/tables.h'\"
else
echo shar: Extracting \"'unzip-5.12/tables.h'\" \(6079 characters\)
sed "s/^X//" >'unzip-5.12/tables.h' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X tables.h
X
X This file contains only the 32-bit CRC table and the EBCDIC translation
X table used in fUnZip and in UnZip's file_io.c; they're in a separate file
X because they are rather big and ugly and because they get in the way dur-
X ing editing. This file can be included in no more than ONE source file
X per executable, of course.


X
X ---------------------------------------------------------------------------*/
X
X

X#ifdef FUNZIP
X
X/* Table of CRC-32's of all single-byte values (made by makecrc.c) */
Xulg near crc_32_tab[] = {
X 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
X 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
X 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
X 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
X 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
X 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
X 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
X 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
X 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
X 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
X 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
X 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
X 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
X 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
X 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
X 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
X 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
X 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
X 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
X 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
X 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
X 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
X 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
X 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
X 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
X 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
X 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
X 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
X 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
X 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
X 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
X 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
X 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
X 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
X 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
X 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
X 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
X 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
X 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
X 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
X 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
X 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
X 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
X 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
X 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
X 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
X 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
X 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
X 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
X 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
X 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
X 0x2d02ef8dL
X};
X
X#endif /* FUNZIP */
X
X
X
X#ifdef EBCDIC
X
X/*
X * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1
X * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC.
X */
X
Xunsigned char ebcdic[] =
X{
X 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
X 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
X 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
X 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
X 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
X 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
X 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
X 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
X 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
X 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
X 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
X 0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d,
X 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
X 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
X 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
X 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
X 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
X 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
X 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
X 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xff,
X 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5,
X 0xbd, 0xb4, 0x9a, 0x8a, 0x5f, 0xca, 0xaf, 0xbc,
X 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
X 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
X 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
X 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
X 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
X 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xad, 0xae, 0x59,
X 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
X 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
X 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
X 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf
X};
X
X#endif /* EBCDIC */
END_OF_FILE
if test 6079 -ne `wc -c <'unzip-5.12/tables.h'`; then
echo shar: \"'unzip-5.12/tables.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/tables.h'
fi
if test -f 'unzip-5.12/tops20/tops20.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/tops20/tops20.c'\"
else
echo shar: Extracting \"'unzip-5.12/tops20/tops20.c'\" \(5608 characters\)
sed "s/^X//" >'unzip-5.12/tops20/tops20.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X tops20.c
X
X TOPS20-specific routines for use with Info-ZIP's UnZip 5.1 and later.
X
X Contains: mapattr()
X close_outfile()
X version()
X upper()
X enquote()
X dequote()
X fnlegal()
X
X (not yet ported: do_wild(), mapname(), checkdir(), ...)


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"


X
X
X/**********************/
X/* Function mapattr() */
X/**********************/
X

Xint mapattr() /* just like Unix except no umask() */


X{
X ulg tmp = crec.external_file_attributes;
X

X switch (pInfo->hostnum) {
X case UNIX_:

X case VMS_:
X pInfo->file_attr = (unsigned)(tmp >> 16);

X break;
X case AMIGA_:
X tmp = (unsigned)(tmp>>1 & 7); /* Amiga RWE bits */


X pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
X break;

X case FS_FAT_: /* MSDOS half of attributes should always be correct */


X case FS_HPFS_:
X case FS_NTFS_:
X case MAC_:
X case ATARI_:

X case TOPS20_:
X default:
X tmp = !(tmp & 1) << 1; /* read-only bit --> write perms bits */
X pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
X break;

X#if 0
X case ATARI_:


X case TOPS20_:
X default:

X pInfo->file_attr = 0666;
X break;
X#endif


X } /* end switch (host-OS-created-by) */

X
X return 0;
X

X} /* end function mapattr() */


X
X
X
X
X

X/****************************/
X/* Function close_outfile() */
X/****************************/
X
Xvoid close_outfile()
X{

X# define JSYS_CLASS 0070000000000
X# define FLD(val,mask) (((unsigned)(val)*((mask)&(-(mask))))&(mask))
X# define _DEFJS(name,class) (FLD(class,JSYS_CLASS) | (monsym(name)&0777777))
X# define IDTIM _DEFJS("IDTIM%", 1)
X# define SFTAD _DEFJS("SFTAD%", 0)
X# define YRBASE 1900
X int ablock[5], tblock[2];
X int yr, mo, dy, hh, mm, ss;
X char temp[100];
X unsigned tad;
X
X
X /* dissect the date */


X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);

X mo = (lrec.last_mod_file_date >> 5) & 0x0f;
X dy = lrec.last_mod_file_date & 0x1f;
X
X /* dissect the time */


X hh = (lrec.last_mod_file_time >> 11) & 0x1f;
X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
X ss = (lrec.last_mod_file_time & 0x1f) * 2;
X

X sprintf(temp, "%02d/%02d/%02d %02d:%02d:%02d", mo, dy, yr, hh, mm, ss);
X
X ablock[1] = (int)(temp - 1);
X ablock[2] = 0;
X if (!jsys(IDTIM, ablock)) {
X fprintf(stderr, "error: IDTIM failure for %s\n", filename);
X fclose(outfile);
X return;
X }
X
X tad = ablock[2];
X tblock[0] = tad;
X tblock[1] = tad;
X tblock[2] = -1;
X
X ablock[1] = fcntl(fileno(outfile), F_GETSYSFD, 0); /* _uffd[outfd]->uf_ch */
X ablock[2] = (int) tblock;
X ablock[3] = 3;
X if (!jsys(SFTAD, ablock))
X fprintf(stderr, "error: can't set the time for %s\n", filename);
X
X fclose(outfile);
X
X} /* end function close_outfile() */


X
X
X
X
X

X#ifndef SFX
X
X/************************/
X/* Function version() */
X/************************/
X
Xvoid version()

X{


X extern char Far CompiledWith[];
X#if 0
X char buf[40];
X#endif
X
X printf(LoadFarString(CompiledWith),
X
X#ifdef __GNUC__
X "gcc ", __VERSION__,
X#else
X# if 0
X "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
X# else

X# ifdef __COMPILER_KCC__
X "KCC", "",


X# else
X "unknown compiler", "",
X# endif
X# endif
X#endif
X

X "TOPS-20",
X
X#if defined(foobar) || defined(FOOBAR)
X " (Foo BAR)", /* OS version or hardware */


X#else
X "",
X#endif /* Foo BAR */

X
X#ifdef __DATE__
X " on ", __DATE__
X#else
X "", ""

X#endif
X );
X


X} /* end function version() */
X

X#endif /* !SFX */


X
X
X
X
X

X/**********************/
X/* Function upper() */
X/**********************/
X
Xint upper(s) /* returns s in uppercase */
X char *s; /* string to be uppercased */
X{
X for (; *s; ++s)
X *s = toupper(*s);


X}
X
X
X
X
X

X/************************/
X/* Function enquote() */
X/************************/
X
Xint enquote(s) /* calls dequote(s) to normalize string, then */
X char *s; /* inserts ^Vs before otherwise illegal characters */
X{ /* in s, assuming that s is a TOPS-20 filename */
X char d[100];
X char *p, *q;
X char c;
X
X if (s && *s) {
X dequote(s);
X p = s - 1;
X q = d - 1;
X while (c = *++p) {
X if (!fnlegal(c))
X *++q = '\026';
X *++q = c;
X }
X *++q = '\0';
X strcpy(s, d);
X }
X return 0;


X}
X
X
X
X
X

X/************************/
X/* Function dequote() */
X/************************/
X
Xint dequote(s) /* returns s without ^Vs */
X char *s; /* string to be dequoted */
X{
X char d[100];
X char *p, *q;
X int c;
X
X if (s && *s) {
X p = s - 1;
X q = d - 1;
X while (c = *++p)
X if (c != '\026')
X *++q = c;
X *++q = '\0';
X strcpy(s, d);
X }
X return 0;


X}
X
X
X
X
X

X/************************/
X/* Function fnlegal() */
X/************************/
X
Xint fnlegal(c) /* returns TRUE if c is a member of the */
X char c; /* legal character set for filenames */
X{
X char *q;
X static char *legals = {"$%**-<>>AZ[[]]__az"};
X
X q = legals;
X while (*q)
X if (c < *q++)
X break;
X else if (c <= *q++)
X return TRUE;
X
X return FALSE;
X}
END_OF_FILE
if test 5608 -ne `wc -c <'unzip-5.12/tops20/tops20.c'`; then
echo shar: \"'unzip-5.12/tops20/tops20.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/tops20/tops20.c'
fi
if test -f 'unzip-5.12/unix/funzip.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/funzip.1'\"
else
echo shar: Extracting \"'unzip-5.12/unix/funzip.1'\" \(4441 characters\)
sed "s/^X//" >'unzip-5.12/unix/funzip.1' <<'END_OF_FILE'


X.\" Info-ZIP grants permission to any individual or institution to use, copy,
X.\" or redistribute this software, so long as: (1) all of the original files
X.\" are included; (2) it is not sold for profit; and (3) this notice is re-

X.\" tained. See the UnZip COPYING file for details.
X.\"
X.\" funzip.1 by Greg Roelofs and others.


X.\"
X.\" =========================================================================
X.\" define .Y macro (for user-command examples; normal Courier font):
X.de Y
X.ft CW
X.in +4n
X.nf
X\&\\$1
X.ft
X.in
X.fi
X..
X.\" =========================================================================

X.TH FUNZIP 1 "28 Aug 94 (v3.83)"
X.SH NAME
Xfunzip \- filter for extracting from a ZIP archive in a pipe
X.\" =========================================================================
X.SH SYNOPSIS
X[.\|.\|.] |\ \ \fBfunzip\fP [\fB\-password\fP]\ \ | [.\|.\|.]
X.LP
X\fBfunzip\fP [\fB\-password\fP] \fIinput.zip\fP\ \ | [.\|.\|.]
X.\" =========================================================================
X.SH ARGUMENTS
X.IP [\fI\-password\fP]
XOptional password to be used if ZIP archive is encrypted. Decryption
Xmay not be supported at some sites. See DESCRIPTION for more details.
X.PD
X.\" =========================================================================
X.SH DESCRIPTION
X.I funzip
Xacts as a filter; that is, it assumes that a ZIP archive is being piped into
Xstandard input, and it extracts the first member from the archive to stdout.
XIf there is an argument, then the input comes from the specified file
Xinstead of from stdin. A password for encrypted zip files can be specified
Xon the command line (preceding the file name, if any) by prefixing the
Xpassword with a dash. Note that this constitutes a security risk on many
Xsystems; currently running processes are often visible via simple commands
X(e.g., \fIps\fP(1) under Unix), and command-line histories can be read.
XIf the first entry of the zip file is encrypted and
Xno password is specified on the command line, then the user is prompted for
Xa password and the password is not echoed on the console.
X.LP
XGiven the limitation on single-member extraction, \fIfunzip\fP is most
Xuseful in conjunction with a secondary archiver program such as \fItar\fP(1).
XThe following section includes an example illustrating this usage in the
Xcase of disk backups to tape.


X.PD
X.\" =========================================================================
X.SH EXAMPLES

XTo use \fIfunzip\fP to extract the first member file of the archive test.zip
Xand to pipe it into \fImore\fP(1):
X.LP
X.Y "funzip test.zip | more"
X.LP
XTo use \fIfunzip\fP to test the first member file of test.zip (any errors
Xwill be reported on standard error):
X.LP
X.Y "funzip test.zip > /dev/null"
X.LP
XTo use \fIzip\fP and \fIfunzip\fP in place of \fIcompress\fP(1) and
X\fIzcat\fP(1) (or \fIgzip\fP(1L) and \fIgzcat\fP(1L)) for tape backups:
X.LP
X.PD 0
X.Y "tar cf \- . | zip \-7 | dd of=/dev/nrst0 obs=8k"
X.Y "dd if=/dev/nrst0 ibs=8k | funzip | tar xf \-"
X.PD
X.LP
X(where, for example, nrst0 is a SCSI tape drive).


X.PD
X.\" =========================================================================
X.SH BUGS

XWhen piping an encrypted file into \fImore\fP and allowing \fIfunzip\fP
Xto prompt for password, the terminal may sometimes be reset to a non-echo
Xmode. This is apparently due to a race condition between the two programs;
X\fIfunzip\fP changes the terminal mode to non-echo before \fImore\fP reads
Xits state, and \fImore\fP then ``restores'' the terminal to this mode before
Xexiting. To recover, run \fIfunzip\fP on the same file but redirect to
X/dev/null rather than piping into more; after prompting again for the
Xpassword, \fIfunzip\fP will reset the terminal properly.
X.LP
XThere is presently no way to extract any member but the first from a ZIP
Xarchive. This would be useful in the case where a ZIP archive is included
Xwithin another archive. In the case where the first member is a directory,
X\fIfunzip\fP simply creates the directory and exits.
X.LP
XThe functionality of \fIfunzip\fP should be incorporated into \fIunzip\fP
Xitself (future release).


X.PD
X.\" =========================================================================
X.SH SEE ALSO

X\fIgzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L), \fIzip\fP(1L),
X\fIzipcloak\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)


X.PD
X.\" =========================================================================
X.SH AUTHOR

XMark Adler (Info-ZIP)
END_OF_FILE
if test 4441 -ne `wc -c <'unzip-5.12/unix/funzip.1'`; then
echo shar: \"'unzip-5.12/unix/funzip.1'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/funzip.1'
fi
if test -f 'unzip-5.12/unreduce.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unreduce.c'\"
else
echo shar: Extracting \"'unzip-5.12/unreduce.c'\" \(5772 characters\)
sed "s/^X//" >'unzip-5.12/unreduce.c' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X unreduce.c
X
X The Reducing algorithm is actually a combination of two distinct algorithms.
X The first algorithm compresses repeated byte sequences, and the second al-
X gorithm takes the compressed stream from the first algorithm and applies a
X probabilistic compression method.


X
X ---------------------------------------------------------------------------*/
X
X

X#include "unzip.h"
X
X
X/**************************************/
X/* UnReduce Defines, Typedefs, etc. */
X/**************************************/
X
X#define DLE 144
X
Xtypedef uch f_array[64]; /* for followers[256][64] */
X
Xstatic void LoadFollowers __((void));
X
X
X
X/*******************************/
X/* UnReduce Global Variables */
X/*******************************/
X
X#if defined(MALLOC_WORK) || defined(MTS)
X f_array *followers; /* shared work space */
X#else
X f_array *followers = (f_array *) (slide + 0x4000);
X#endif
X
Xuch Slen[256];
Xint factor;
X
Xint L_table[] =
X{0, 0x7f, 0x3f, 0x1f, 0x0f};
X
Xint D_shift[] =
X{0, 0x07, 0x06, 0x05, 0x04};
Xint D_mask[] =
X{0, 0x01, 0x03, 0x07, 0x0f};
X
Xint B_table[] =
X{8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
X 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
X 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
X 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
X 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
X 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
X 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
X 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 8};


X
X
X
X
X
X/*************************/

X/* Function unreduce() */
X/*************************/
X
Xvoid unreduce() /* expand probabilistically reduced data */
X{
X register int lchar = 0;
X int nchar;
X int ExState = 0;
X int V = 0;
X int Len = 0;
X long s = ucsize; /* number of bytes left to decompress */
X unsigned w = 0; /* position in output window slide[] */
X unsigned u = 1; /* true if slide[] unflushed */
X
X
X#if defined(MALLOC_WORK) || defined(MTS)
X followers = (f_array *)(slide + 0x4000);
X#endif
X
X factor = lrec.compression_method - 1;
X LoadFollowers();
X
X while (s > 0 /* && (!zipeof) */) {
X if (Slen[lchar] == 0)
X READBITS(8, nchar) /* ; */
X else {
X READBITS(1, nchar) /* ; */
X if (nchar != 0)
X READBITS(8, nchar) /* ; */
X else {
X int follower;
X int bitsneeded = B_table[Slen[lchar]];
X
X READBITS(bitsneeded, follower) /* ; */
X nchar = followers[lchar][follower];
X }
X }
X /* expand the resulting byte */
X switch (ExState) {
X
X case 0:
X if (nchar != DLE) {
X s--;
X slide[w++] = (uch)nchar;
X if (w == 0x4000) {
X flush(slide, w, 0);
X w = u = 0;
X }
X }
X else
X ExState = 1;
X break;
X
X case 1:
X if (nchar != 0) {
X V = nchar;
X Len = V & L_table[factor];
X if (Len == L_table[factor])
X ExState = 2;
X else
X ExState = 3;
X } else {
X s--;
X slide[w++] = DLE;
X if (w == 0x4000)


X {
X flush(slide, w, 0);
X w = u = 0;
X }

X ExState = 0;
X }
X break;
X
X case 2:{
X Len += nchar;
X ExState = 3;
X }
X break;
X
X case 3:{
X register unsigned e;
X register unsigned n = Len + 3;
X register unsigned d = w - ((((V >> D_shift[factor]) &
X D_mask[factor]) << 8) + nchar + 1);
X


X s -= n;
X do {

X n -= (e = (e = 0x4000 - ((d &= 0x3fff) > w ? d : w)) > n ?
X n : e);


X if (u && w <= d)
X {
X memzero(slide + w, e);
X w += e;
X d += e;

X }
X else
X if (w - d < e) /* (assume unsigned comparison) */
X do { /* slow to avoid memcpy() overlap */


X slide[w++] = slide[d++];
X } while (--e);

X else


X {
X memcpy(slide + w, slide + d, e);
X w += e;
X d += e;
X }

X if (w == 0x4000)


X {
X flush(slide, w, 0);

X w = u = 0;
X }
X } while (n);
X
X ExState = 0;
X }
X break;
X }
X
X /* store character for next iteration */
X lchar = nchar;


X }
X
X /* flush out slide */
X flush(slide, w, 0);

X}
X
X
X
X
X

X/******************************/
X/* Function LoadFollowers() */
X/******************************/
X
Xstatic void LoadFollowers()
X{
X register int x;
X register int i;
X
X for (x = 255; x >= 0; x--) {
X READBITS(6, Slen[x]) /* ; */
X for (i = 0; (uch)i < Slen[x]; i++)
X READBITS(8, followers[x][i]) /* ; */
X }
X}
END_OF_FILE
if test 5772 -ne `wc -c <'unzip-5.12/unreduce.c'`; then
echo shar: \"'unzip-5.12/unreduce.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unreduce.c'
fi
if test -f 'unzip-5.12/vms/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/README'\"
else
echo shar: Extracting \"'unzip-5.12/vms/README'\" \(4831 characters\)
sed "s/^X//" >'unzip-5.12/vms/README' <<'END_OF_FILE'
Xvms/README for UnZip 5.12 and later, 25 Aug 94
X----------------------------------------------
X
XNotes about using UnZip and zipfiles under VMS (see INSTALL for instructions
Xon compiling):
X
X - Install UnZip as foreign symbol by adding this to login.com:


X $ unzip == "$disk:[dir]unzip.exe"
X $ zipinfo == "$disk:[dir]unzip.exe -Z"

X where "disk" and "dir" are location of UnZip executable; the "$" before
X the disk name is important. Some people, including the author, prefer
X a short alias such as "ii" instead of "zipinfo"; edit to taste.
X
X - Optionally install UnZipSFX for use with the MAKESFX.COM command file:
X $ unzipsfx :== disk:[dir]unzipsfx.exe
X Thereafter an archive "foo.zip" may be converted to "foo.exe" simply by
X typing "@makesfx foo" (assuming MAKESFX.COM is in the current directory).
X Note that there is *no* leading "$" in this case.
X
X - After proper installation, the default version of UnZip is invoked just
X as in Unix or MS-DOS: "unzip -opts archive files". The hyphen ('-') is
X the switch character, not the slash ('/') as in native VMS commands. An
X alternative is available if VMSCLI is defined during compilation; this
X version does provide a native VMS-style command interface (e.g., /ZIPINFO
X instead of -Z). Both versions accept the command "unzip -v", which can
X be used to check whether VMSCLI was defined or not; but an even simpler
X method is to type "unzip" and look at the help screen. Note that options
X placed in an environment variable (UNZIP_OPTS) must be of the short, hy-
X phenated form regardless of how UnZip was compiled.
X
X - VMS (or the C compiler) translates all command-line text to lowercase
X unless it is quoted, making some options and/or filenames not work as
X intended. For example:
X unzip -V zipfile vms/README
X is tranlated to
X unzip -v zipfile vms/readme
X which may not match the contents of the zipfile and definitely won't
X extract the file with its version number as intended. This can be
X avoided by use of the -C option (/CASE_INSENSITIVE) or by enclosing
X the uppercase stuff in quotes:
X unzip "-V" zipfile "vms/README"
X Note that quoting the whole line probably won't work, since it would
X be interpreted as a single argument by the C library.
X
X - Wildcards which refer to files internal to the archive behave like Unix
X wildcards, not VMS ones (assuming UnZip was not compiled with VMSWILD
X defined). This is both a matter of consistency (see above) and power--
X full Unix regular expressions are supported, so that one can specify
X "all .c and .h files which start with a, b, c or d and do not have a 2
X before the dot" as "[a-d]*[^2].[ch]". Of course, "*.[ch]" is a much more
X common wildcard specification, but the power is there if you need it.
X Note that "*" matches zipfile directory separators ('/'), too. If UnZip
X *was* compiled with VMSWILD defined (do "unzip -v" to check), the single-
X character wildcard is "%" rather than "?", and character sets (ranges)
X are delimited with () instead of [] (for example, "*.(ch)").
X
X - Created files get whatever permissions were stored in the archive (mapped
X to VMS and/or masked with your default permissions, depending on the
X originating operating system), but created directories additionally in-
X herit the (possibly more restrictive) permissions of the parent directory.
X And obviously things won't work if you don't have permission to write to
X the extraction directory.
X
X - When transferring files, particularly via Kermit, pay attention to the
X settings! In particular, zipfiles must be transferred in some binary
X mode, which is NOT Kermit's default mode, and this mode must usually be
X set on BOTH sides of the transfer (e.g., both VAX and PC). See the notes
X below for details.
X
X
X
X
XFrom Info-ZIP Digest (Wed, 6 Nov 1991), Volume 91, Issue 290:
X
X Date: Tue, 5 Nov 91 15:31 CDT
X From: Hugh Schmidt <HU...@macc.wisc.edu>
X
X ****************************************************
X *** VMS ZIP and PKZIP compatibility using KERMIT ***
X ****************************************************
X
X Many use Procomm's kermit to transfer zipped files between PC and VMS
X VAX. The following VMS kermit settings make VMS Zip/UnZip compatible
X with PC Zip/UnZip or PKZIP/PKUNZIP:
X VMS kermit Procomm kermit
X ------------------- --------------------
X Uploading PC zipfile to VMS: set file type fixed set file type binary
X Downloading VMS zipfile to PC: set file type block set file type binary
X
X "Block I/O lets you bypass the VMS RMS record-processing capabilities
X entirely", (Guide to VMS file applications, Section 8.5). The kermit
X guys must have known this!
END_OF_FILE
if test 4831 -ne `wc -c <'unzip-5.12/vms/README'`; then
echo shar: \"'unzip-5.12/vms/README'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/README'
fi
if test -f 'unzip-5.12/vms/cvthelp.tpu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/cvthelp.tpu'\"
else
echo shar: Extracting \"'unzip-5.12/vms/cvthelp.tpu'\" \(4377 characters\)
sed "s/^X//" >'unzip-5.12/vms/cvthelp.tpu' <<'END_OF_FILE'
X! TITLE CVTHELP.TPU
X! IDENT 01-000
X!
X!++
X!
X! Program: CVTHELP.TPU
X!
X! Author: Hunter Goatley
X!
X! Date: January 12, 1992
X!
X! Purpose: Convert .HELP files to RUNOFF .RNH files. Substitutes
X! RUNOFF commands for tags imbedded in the .HELP file.
X!
X! Calling sequence:
X!
X! $ EDIT/TPU/NOJOURNAL/NODISPLAY/COMMAND=CVTHELP file.HELP
X!
X! Modified by:
X!
X! 01-000 Hunter Goatley 12-JAN-1992 15:15
X! Original version.
X!
X!--
XProcedure eve_convert_help
XLocal temp
X ,x
X ;
X
X qualifier_level := 0;
X hg$substitute_topic(current_buffer, "<MAIN>", ".indent-3", "1");
X hg$substitute_topic(current_buffer, "<QUALIFIER>", ".sk;.indent-3", "");
X hg$substitute_topic(current_buffer, "<TOPIC>", ".indent-3", "2");
X hg$substitute_topic(current_buffer, "<SUBTOPIC>", ".indent-3", "3");
X hg$substitute_topic(current_buffer, "<SUBSUBTOPIC>", ".indent-3", "4");
X hg$substitute_comment(current_buffer,"<QUALIFIERS>",".indent-3;2 Qualifiers");
X hg$substitute_comment(current_buffer,"<PARAMETER>",".indent-2");
X hg$substitute_comment(current_buffer,"<PTEXT>",".lm+3");
X hg$substitute_comment(current_buffer,"<TXETP>",".lm-3");
X hg$substitute_comment(current_buffer,"<ETEXT>",".lm+4");
X hg$substitute_comment(current_buffer,"<TXETE>",".lm-4");
X hg$substitute_comment(current_buffer,"<INIT>",".noflags;.lm3;.rm70");
X hg$substitute_comment(current_buffer,"<LITERAL>",".lm+4;.literal");
X hg$substitute_comment(current_buffer,"<LARETIL>",".end literal;.lm-4");
X hg$substitute_comment(current_buffer,"<DOT1LIST>",'.list 1,"o"');
X hg$substitute_comment(current_buffer,"<DOT0LIST>",'.list 0,"o"');
X hg$substitute_comment(current_buffer,"<ENTRY>",".le");
X hg$substitute_comment(current_buffer,"<TSIL>",".end list");
X hg$substitute_comment(current_buffer,"<CENTER>",".center");
X hg$substitute_comment(current_buffer,"<FORMAT>",".sk;.indent2");
X hg$substitute_comment(current_buffer,"<NOTE>",".note");
X hg$substitute_comment(current_buffer,"<ETON>",".end note");
X hg$substitute_comment(current_buffer, LINE_BEGIN & LINE_END,".sk");
X hg$substitute_comment(current_buffer, LINE_BEGIN & "|", "");
X
XEndProcedure; ! eve_convert_help
X
XProcedure hg$substitute_comment (the_buffer, target, new)
XLocal temp
X ,save_pos
X ,x
X ;
X on_error;
X endon_error;
X
X save_pos := mark(none);
X position(beginning_of(the_buffer));
X loop
X x := search(target, forward);
X exitif x = 0;
X position (x);
X erase_character(length(x));
X copy_text(new);
X endloop;
X
X position(save_pos);
X
XEndProcedure; ! hg$substitute_comment
X
XProcedure hg$substitute_topic (the_buffer, target, new, level)
XLocal temp
X ,save_pos
X ,x
X ;
X on_error;
X endon_error;
X
X save_pos := mark(none);
X position(beginning_of(the_buffer));
X loop
X x := search(target, forward);
X exitif x = 0;
X position (x);
X erase_character(length(x));
X move_vertical(-1);
X if (length(current_line) = 0)
X then copy_text("|");
X endif;
X move_vertical(1);
X copy_text(".!------------------------------------------------------");
X split_line;
X copy_text(new);
X move_horizontal(-current_offset);
X move_vertical(1);
X if level <> "" then
X copy_text(level + " ");
X! else
X! if qualifier_level = 0
X! then
X! copy_text("2 Qualifiers");
X! split_line; split_line;
X! copy_text(new); split_line;
X! qualifier_level := 1;
X! endif;
X endif;
X move_horizontal(-current_offset);
X move_vertical(1);
X if length(current_line) = 0
X then
X if (target = "<MAIN>") OR (target = "<TOPIC>")
X OR (target = "<SUBTOPIC>") or (target = "<SUBSUBTOPIC>")
X then copy_text(".br");
X else copy_text(".sk");
X endif;
X endif;
X endloop;
X
X position(save_pos);
X
XEndProcedure; ! hg$substitute_topic
X
X!===============================================================================
XProcedure tpu$init_procedure
XLocal temp
X ,orig_filespec
X ,f
X ;
X
X on_error
X endon_error;
X
X !Prompt user for information
X
X orig_filespec := get_info(command_line, "file_name");
X if orig_filespec = ""
X then
X message("No .HELP file given");
X quit;
X endif;
X f := file_parse(orig_filespec, ".HELP"); !Add .LIS ending
X
X ! Create a buffer and window for editing
X
X main_buf := create_buffer ("MAIN",f);
X set (eob_text, main_buf, "[End of buffer]");
X
X position (beginning_of(main_buf));
X
X eve_convert_help;
X
X f := file_parse(orig_filespec,"","",NAME);
X
X write_file (main_buf, f+".RNH");
X
X quit;
XEndProcedure; !TPU$INIT_PROCEDURE
X
Xtpu$init_procedure;
END_OF_FILE
if test 4377 -ne `wc -c <'unzip-5.12/vms/cvthelp.tpu'`; then
echo shar: \"'unzip-5.12/vms/cvthelp.tpu'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/cvthelp.tpu'
fi
if test -f 'unzip-5.12/vms/descrip.mms' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/descrip.mms'\"
else
echo shar: Extracting \"'unzip-5.12/vms/descrip.mms'\" \(5400 characters\)
sed "s/^X//" >'unzip-5.12/vms/descrip.mms' <<'END_OF_FILE'
X!==========================================================================
X! MMS description file for UnZip/UnZipSFX 5.12 26 Aug 94
X!==========================================================================
X!
X! To build UnZip that uses shared libraries, edit the USER CUSTOMIZATION
X! lines below to taste, then do
X! mms
X! or
X! mmk
X! if you use Matt's Make (free MMS-compatible make utility).
X!
X! (One-time users will find it easier to use the MAKE.COM command file,
X! which generates both UnZip and UnZipSFX. Just type "@[.VMS]MAKE", or
X! "@[.VMS]MAKE GCC" if you want to use GNU C.)
X
X! To build UnZip without shared libraries,
X! mms noshare
X
X! To delete all .OBJ, .EXE and .HLP files,
X! mms clean
X
XDO_THE_BUILD :
X @ decc = f$search("SYS$SYSTEM:DECC$COMPILER.EXE").nes.""
X @ axp = f$getsyi("HW_MODEL").ge.1024
X @ macro = ""
X @ if axp.or.decc then macro = "/MACRO=("
X @ if decc then macro = macro + "__DECC__=1,"
X @ if axp then macro = macro + "__ALPHA__=1,"
X @ if macro.nes."" then macro = f$extract(0,f$length(macro)-1,macro)+ ")"
X $(MMS)$(MMSQUALIFIERS)'macro' default
X
X.IFDEF EXE
X.ELSE
XEXE = .EXE
XOBJ = .OBJ
XOLB = .OLB
X.ENDIF
X
X!!!!!!!!!!!!!!!!!!!!!!!!!!! USER CUSTOMIZATION !!!!!!!!!!!!!!!!!!!!!!!!!!!!
X! uncomment the following line if you want the VMS CLI$ interface:
X!VMSCLI = VMSCLI,
X
X! add VMSWILD, RETURN_CODES, RETURN_SEVERITY, and/or any other optional
X! macros (except VMSCLI, above) to the following line for a custom version:
XCOMMON_DEFS =
X!!!!!!!!!!!!!!!!!!!!!!!! END OF USER CUSTOMIZATION !!!!!!!!!!!!!!!!!!!!!!!!
X
XCC = cc
X
X.IFDEF __ALPHA__
XCC_OPTIONS = /STANDARD=VAXC/ANSI/NOWARNINGS/INCLUDE=[]
XCC_DEFS = MODERN,
XOPTFILE =
XOPTIONS =
X.ELSE
X.IFDEF __DECC__
XCC_OPTIONS = /STANDARD=VAXC/ANSI/NOWARNINGS/INCLUDE=[]
XCC_DEFS = MODERN,
X.ELSE
XCC_OPTIONS = /INCLUDE=[]
XCC_DEFS =
X.ENDIF
XOPTFILE = ,[.vms]vmsshare.opt
XOPTIONS = $(OPTFILE)/OPTIONS
X.ENDIF
X
X.IFDEF __DEBUG__
XCDEB = /DEBUG/NOOPTIMIZE
XLDEB = /DEBUG
X.ELSE
XCDEB =
XLDEB = /NOTRACE
X.ENDIF
X
XCFLAGS_SFX = $(CFLAGS) $(CC_OPTIONS) $(CDEB) -
X /def=($(CC_DEFS) $(COMMON_DEFS) $(VMSCLI) SFX, VMS)
XCFLAGS = $(CFLAGS) $(CC_OPTIONS) $(CDEB) -
X /def=($(CC_DEFS) $(COMMON_DEFS) $(VMSCLI) VMS)
X
XLINKFLAGS = $(LDEB)
X
X
XCOMMON_OBJS = unzip$(OBJ),-
X crypt$(OBJ),-
X envargs$(OBJ),-
X explode$(OBJ),-
X extract$(OBJ),-
X file_io$(OBJ),-
X inflate$(OBJ),-
X match$(OBJ),-
X unreduce$(OBJ),-
X unshrink$(OBJ),-
X zipinfo$(OBJ),-
X VMS=[.vms]vms$(OBJ)
X
X.IFDEF VMSCLI
XOBJS = $(COMMON_OBJS),-
X VMS_UNZIP_CLD=[.vms]unz_cld$(OBJ),-
X VMS_UNZIP_CMDLINE=[.vms]cmdline$(OBJ)
XOBJX = UNZIP=unzipsfx$(OBJ),-
X VMS_UNZIP_CLD=[.vms]unz_cld$(OBJ),-
X VMS_UNZIP_CMDLINE=cmdline_$(OBJ),-
X crypt$(OBJ),-
X EXTRACT=extract_$(OBJ),-
X file_io$(OBJ),-
X inflate$(OBJ),-
X match$(OBJ),-
X VMS=[.vms]vms_$(OBJ)
X.ELSE
XOBJS = $(COMMON_OBJS)
XOBJX = UNZIP=unzipsfx$(OBJ),-
X crypt$(OBJ),-
X EXTRACT=extract_$(OBJ),-
X file_io$(OBJ),-
X inflate$(OBJ),-
X match$(OBJ),-
X VMS=[.vms]vms_$(OBJ)
X.ENDIF
X
Xdefault : unzip$(EXE) unzipsfx$(EXE) unzip.hlp
X @ ! Do nothing.
X
Xunzip$(EXE) : UNZIP$(OLB)($(OBJS))$(OPTFILE)
X $(LINK)$(LINKFLAGS) UNZIP$(OLB)/INCLUDE=UNZIP/LIBRARY$(OPTIONS), -
X [.vms]unzip.opt/OPT
X
Xunzipsfx$(EXE) : UNZIPSFX$(OLB)($(OBJX))$(OPTFILE)
X $(LINK)$(LINKFLAGS) UNZIPSFX$(OLB)/INCLUDE=UNZIP/LIBRARY$(OPTIONS), -
X [.vms]unzipsfx.opt/OPT
X
Xnoshare : $(OBJS)
X $(LINK) /EXE=$(MMS$TARGET) $(OBJS),SYS$LIBRARY:VAXCRTL.OLB/LIB, -
X [.vms]unzip.opt/OPT
X
Xclean :
X ! delete *.obj;*, *.olb;*, unzip$(exe);*, unzipsfx$(exe);*, -
X ! unzip.hlp;*, [.vms]*.obj;*, [.vms]unzip.rnh;*
X @[.vms]clean "$(OBJS)"
X @[.vms]clean "$(OBJX)"
X @[.vms]clean unzip$(olb),unzipsfx$(olb)
X @[.vms]clean unzip$(exe),unzipsfx$(exe)
X @[.vms]clean unzip.hlp,[.vms]unzip.rnh
X
Xcrypt$(OBJ) : crypt.c unzip.h zip.h crypt.h


Xenvargs$(OBJ) : envargs.c unzip.h
Xexplode$(OBJ) : explode.c unzip.h
Xextract$(OBJ) : extract.c unzip.h crypt.h
Xfile_io$(OBJ) : file_io.c unzip.h crypt.h tables.h

Xinflate$(OBJ) : inflate.c inflate.h unzip.h


Xmatch$(OBJ) : match.c unzip.h
Xunreduce$(OBJ) : unreduce.c unzip.h
Xunshrink$(OBJ) : unshrink.c unzip.h
Xunzip$(OBJ) : unzip.c unzip.h crypt.h version.h

Xunzip.hlp : [.vms]unzip.rnh
Xzipinfo$(OBJ) : zipinfo.c unzip.h
X[.vms]cmdline$(OBJ) : [.vms]cmdline.c version.h
X[.vms]unz_cld$(OBJ) : [.vms]unz_cld.cld
X
Xcmdline_$(OBJ) : [.vms]cmdline.c version.h
X $(CC) $(CFLAGS_SFX) /INCLUDE=SYS$DISK:[] /OBJ=$(MMS$TARGET) [.vms]cmdline.c


X
Xextract_$(OBJ) : extract.c unzip.h crypt.h

X $(CC) $(CFLAGS_SFX) /OBJ=$(MMS$TARGET) extract.c
X
Xunzipsfx$(OBJ) : unzip.c unzip.h crypt.h version.h
X $(CC) $(CFLAGS_SFX) /OBJ=$(MMS$TARGET) unzip.c
X
X[.vms]vms$(OBJ) : [.vms]vms.c [.vms]vms.h unzip.h
X @ x = ""
X @ if f$search("SYS$LIBRARY:SYS$LIB_C.TLB").nes."" then x = "+SYS$LIBRARY:SYS$LIB_C.TLB/LIBRARY"
X $(CC) $(CFLAGS) /INCLUDE=SYS$DISK:[] /OBJ=$(MMS$TARGET) [.vms]vms.c'x'
X
X[.vms]vms_$(OBJ) : [.vms]vms.c [.vms]vms.h unzip.h
X @ x = ""
X @ if f$search("SYS$LIBRARY:SYS$LIB_C.TLB").nes."" then x = "+SYS$LIBRARY:SYS$LIB_C.TLB/LIBRARY"
X $(CC) $(CFLAGS_SFX) /INCLUDE=SYS$DISK:[] /OBJ=$(MMS$TARGET) [.vms]vms.c'x'
X
X
X.IFDEF VMSCLI
X
X[.vms]unzip.rnh : [.vms]unzip_cli.help
X @ set default [.vms]
X edit/tpu/nosection/nodisplay/command=cvthelp.tpu unzip_cli.help
X rename unzip_cli.rnh unzip.rnh
X @ set default [-]
X
X.ELSE
X
X[.vms]unzip.rnh : [.vms]unzip_def.rnh
X copy [.vms]unzip_def.rnh [.vms]unzip.rnh
X
X.ENDIF
END_OF_FILE
if test 5400 -ne `wc -c <'unzip-5.12/vms/descrip.mms'`; then
echo shar: \"'unzip-5.12/vms/descrip.mms'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/descrip.mms'
fi
if test -f 'unzip-5.12/vms/unzip_def.rnh' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unzip_def.rnh'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unzip_def.rnh'\" \(5977 characters\)
sed "s/^X//" >'unzip-5.12/vms/unzip_def.rnh' <<'END_OF_FILE'
X.!
X.! File: UNZIP_DEF.RNH


X.!
X.! Author: Hunter Goatley
X.!

X.! Date: October 23, 1991
X.!
X.! Description:
X.!
X.! RUNOFF source file for VMS on-line help for portable UnZip.
X.! Adapted from UNZIP.MAN (now UNZIP.DOC).
X.!
X.! To build: $ REN UNZIP_DEF.RNH UNZIP.RNH
X.! $ RUNOFF UNZIP.RNH
X.! $ LIBR/HELP/INSERT libr UNZIP


X.!
X.! Modification history:
X.!

X.! 01-001 Hunter Goatley 23-OCT-1991 09:21
X.! Genesis.
X.! 01-002 Cave Newt 16-MAR-1992 22:37
X.! Updated for UnZip 4.2.
X.! 01-003 Igor Mandrichenko 23-MAY-1992 22:14
X.! Added -X option to command syntax.
X.! 01-004 Cave Newt 24-MAY-1992 13:30
X.! Added UNZIP_OPTS environment variable help.
X.! 01-005 Igor Mandrichenko 14-DEC-1993 18:55
X.! Modified for UnZip V5.1
X.! 01-006 Cave Newt 21-DEC-1993 12:38
X.! Added -x option and cleaned up.
X.! 01-007 Cave Newt 14-JUL-1994 09:45
X.! Added -Z, -C and -L options, removed -U, minor clean-up.
X.! 01-008 Cave Newt 28-JUL-1994 08:57
X.! Removed semi-colons from comments.
X.!
X.noflags
X.lm4 .rm72
X.indent -4
X1 UNZIP
X.br


XUnZip is used to extract files compressed and packaged by Zip (see HELP ZIP
Xfor information on ZIP).

X.sk


XFor a brief help on Zip and Unzip, run each without specifying any
Xparameters on the command line.

X.sk


XUNZIP will list, test, or extract from a ZIP archive. ZIP archives are commonly
Xfound on MS-DOS systems; a VMS version of ZIP can also be found here.

X.sk


XArchive member extraction is implied by the absence of the -c, -p, -t, -l, -v or
X-z options. All archive members are processed unless a filespec is provided to
Xspecify a subset of the archive members.

XFormat:
X.sk;.lm+1;.literal
XUNZIP [-cflptuvxz[ajnoqCLVX]] file[.zip] [list] [-x xlist] [-d out_dir]
X.end literal;.lm-1
X.!------------------------------------------------------------------------------
X.indent -4
X2 Parameters
X.sk;.indent -4
Xfile[.zip]
X.sk


XFile specification for the ZIP archive(s) with optional wildcards. UnZip will
Xperform actions specified for every zipfile matching the specification.

XDefault file specification is SYS$DISK:[].ZIP.


XNote that self-extracting ZIP files are supported; just specify the .EXE
Xsuffix yourself.

X.sk;.indent -4
X[list]
X.sk
XAn optional list of archive members to be processed; if no list is given, all
Xarchive members are processed. Expressions may be
Xused to match multiple members. Expressions should be enclosed in double-quotes
Xto prevent interpretation by DCL. Multiple filenames should be separated by
Xblanks. Each file specification is similar to a Unix egrep expression and may
Xcontain:
X.sk
X.literal


X * matches a sequence of 0 or more characters
X ? matches exactly 1 character
X [...] matches any single character found inside the brackets;
X ranges are specified by a beginning character,
X a hyphen, and an ending character. If a '!' or '^'
X immediately follows the left bracket, then any character
X not in the given range is matched.

X.end literal
X.sk
X.sk;.indent -4
X[-x xlist]
X.sk
XAn optional list of archive members to be excluded from processing. The xlist
Xoverrides any files included in the normal list.
X.sk;.indent -4
X[-d out_dir]
X.sk
XOptional directory specification to be used as target root directory
Xfor files to be extracted. Directory should be specified in "[.foo]"
Xformat rather than "foo.dir" or "foo/" format.
X.!------------------------------------------------------------------------------
X.indent -4
X2 Options
X.br


XThe default action of UnZip is to extract all zipfile entries. The following
Xoptions and modifiers can be provided:

X.sk;.literal


X -Z ZipInfo mode
X -c extract files to SYS$OUTPUT (terminal)
X -f freshen existing files (replace if newer); create none
X -l list archive files (short format)
X -p extract files to SYS$OUTPUT; no informational messages
X -t test archive files
X -u update existing files; create new ones if needed
X -v list archive files (verbose format)
X -z display only the archive comment

X.end literal;.sk;.literal
X MODIFIERS
X -a extract text files in standard VMS text file format


X -aa extract all files as text
X -j junk paths (don't recreate archive's directory structure)
X -n never overwrite existing files; don't prompt
X -o OK to overwrite files without prompting
X -q perform operations quietly (-qq => even quieter)
X -C match filenames case-insensitively

X -L convert filenames to lowercase if created under DOS, VMS, etc.


X -V retain (VMS) file version numbers
X -X restore owner/protection info (may require privileges)

X.end literal;.sk
XNote that uppercase options (-C, -L, -V and -X) must be specified in quotes.
XFor example:
X.sk;.literal
X unzip "-VX" -a zipfile
X.end literal;.sk


X.![this should probably be a separate section]:
XIn addition, default options may be specified via the UNZIP_OPTS logical.

XFor example, the following will cause UnZip to restore owner/protection
Xinformation and perform all operations at quiet-level 1 by default:
X.sk;.literal
X define UNZIP_OPTS "-qX"
X.end literal;.sk


XNote that the quotation marks here are required to preserve lowercase options
X(opposite of the command-line behavior).

XTo negate a default option on the command line, add one or more minus
Xsigns before the option letter, in addition to the leading switch character
X`-':
X.sk;.literal
X unzip --ql zipfile
X.end literal
Xor
X.literal
X unzip -l-q zipfile
X.end literal;.sk


XAt present it is not possible to decrement an option below zero--that is,
Xmore than a few minuses have no effect.

X.sk


XUNZIP_OPTS may be defined as a symbol rather than a logical, but if both
Xare defined, the logical is used.

X.!-----------------------------------------------------------------------------
X.indent -4
X2 Authors
X.br


XInfo-ZIP; currently maintained by Greg Roelofs. VMS support maintained
Xby Igor Mandrichenko and Hunter Goatley. Originally based on a program
Xby Samuel H. Smith.

X.sk


XVMS on-line help ported from UNZIP.DOC by Hunter Goatley.

END_OF_FILE
if test 5977 -ne `wc -c <'unzip-5.12/vms/unzip_def.rnh'`; then
echo shar: \"'unzip-5.12/vms/unzip_def.rnh'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unzip_def.rnh'
fi
echo shar: End of archive 18 \(of 20\).
cp /dev/null ark18isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:17:07 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 84
Archive-name: unzip/part19

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/Contents unzip-5.12/ToDo
# unzip-5.12/amiga/Contents unzip-5.12/amiga/amiga.h
# unzip-5.12/amiga/crc_68.a unzip-5.12/amiga/z-stat.h
# unzip-5.12/crypt.h unzip-5.12/funzip.doc
# unzip-5.12/human68k/Contents unzip-5.12/human68k/Makefile.gcc
# unzip-5.12/inflate.h unzip-5.12/mac/Contents
# unzip-5.12/mac/macdir.h unzip-5.12/mac/macstat.h
# unzip-5.12/msdos/Borland.fix unzip-5.12/msdos/Contents
# unzip-5.12/msdos/makefile.bc unzip-5.12/msdos/makefile.msc
# unzip-5.12/msdos/makefile.tc unzip-5.12/nt/Makefile
# unzip-5.12/os2/Contents unzip-5.12/os2/zipgrep.cmd
# unzip-5.12/unix/Contents unzip-5.12/vms/Contents
# unzip-5.12/vms/clean.com unzip-5.12/vms/make.com
# unzip-5.12/vms/unz_cld.cld unzip-5.12/zip.h
# Wrapped by kent@sparky on Sat Sep 17 23:33:50 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 19 (of 20)."'
if test -f 'unzip-5.12/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/Contents'\" \(2790 characters\)
sed "s/^X//" >'unzip-5.12/Contents' <<'END_OF_FILE'
XContents of the UnZip 5.11 archive (the OS-specific subdirectories at the
Xend contain their own Contents listings):


X
X Contents this file

X README what UnZip is; general information
X INSTALL how to compile and install UnZip and related utilities
X Where where Zip/UnZip and encryption/decryption support can be found
X History.511 new features and fixes in this release
X ZipPorts Info-ZIP rules and guidelines on contributions to the cause
X ToDo rough priority list of new features to be added in next release
X BUGS known bugs, problems, and (possible) other features to be added
X unzip.doc UnZip manual page, human-readable format
X unzipsfx.doc UnZipSFX manual page, human-readable format
X zipinfo.doc ZipInfo manual page, human-readable format
X funzip.doc fUnZip manual page, human-readable format
X CONTRIBS list of contributors to UnZip
X COPYING copyrights and distribution policy
X file_id.diz BBS-oriented file describing this archive
X crypt.c dummy decryption routines (required*)
X crypt.h dummy decryption header file (required*)
X envargs.c code to read options from UNZIP environment var. (required)
X explode.c code for exploding (required)
X extract.c high-level extraction and decryption code (required)
X file_io.c file manipulation and password code (required)
X funzip.c filter unzip: extracts from stdin to stdout (pipes)
X inflate.c code for inflating (required*)
X inflate.h header file for inflating (required*)
X match.c pattern-matching code for filename wildcards (required)
X tables.h static lookup tables used in file_io.c and funzip.c (required*)
X unreduce.c code for unreducing (required)
X unshrink.c code for unshrinking (required)
X unzip.c main UnZip driver code (required)
X unzip.h main UnZip header file (required*)
X version.h header with UnZip/UnZipSFX and ZipInfo version info (required)
X zip.h dummy header for use with crypt.c (required*)
X zipinfo.c UnZip listing routines, mainly for ZipInfo mode (required)
X amiga/ support files for compiling under AmigaDOS
X atari/ support files for compiling under Atari TOS
X human68k/ support files for compiling under X68000/Human68K
X mac/ support files for compiling under Macintosh OS
X msdos/ support files for compiling under MS-DOS
X nt/ support files for compiling under Windows NT
X os2/ support files for compiling under OS/2
X tops20/ support files for compiling under TOPS-20
X unix/ support files for compiling under Unix
X vms/ support files for compiling under VMS
X
XFiles marked "required*" are also needed to compile fUnZip. The normal
Xunzip makefile targets now make both unzipsfx and funzip, except in a few
Xcases; zipinfo is now incorporated into unzip (and invoked with unzip's
X-Z option or by linking/renaming the executable to "zipinfo[.exe]" or
X"ii[.exe]").
END_OF_FILE
if test 2790 -ne `wc -c <'unzip-5.12/Contents'`; then
echo shar: \"'unzip-5.12/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/Contents'
fi
if test -f 'unzip-5.12/ToDo' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/ToDo'\"
else
echo shar: Extracting \"'unzip-5.12/ToDo'\" \(2854 characters\)
sed "s/^X//" >'unzip-5.12/ToDo' <<'END_OF_FILE'
X================================
XFor UnZip 5.1/5.2/6.0/who knows:
X================================
X
XThe Big Plan [original 26 Jan 93]:
X
X o extract-to-dir capability
X
X DONE.
X
X o add wildcard zipfiles
X
X DONE.
X
X o incorporate zipinfo
X
X DONE.
X
X o clean up unzip.h
X
X DONE.
X
X o rewrite to use fwrite/no outbuf
X
X DONE.
X
X o replace EOL conversion code and make text/binary conversion automatic
X
X DONE.
X
X o add self-extracting unzip: deflated/stored only, suppress "extra bytes"
X message, use argv[0] with path search, remove do_wild, etc.
X
X DONE.
X
X o move all strings to far memory under small-memory OS's, copying
X back to local memory (slide[] buffer?) only when ready to print
X
X DONE, except for possible use of slide[]; os2.c; crypt.c;
X inflate.c (incomplete trees messages); other decompression
X routines?; etc.
X
X o add -C option for case-insensitivity of filename matching
X
X DONE.
X
Xfor 5.2:
X o enable CHECK_EOF and RETURN_SEVERITY by default
X
X immediately! (start testing...)
X
X o incorporate Scott Maxwell OS/2 DLL mods
X
X next
X
X o add Unix extra field (GMT modification and status-change times)
X
X next
X
X o rename all nt/NT stuff to win32/WIN32 (works with Chicago, too...)
X
X soon
X
X o rewrite to use fread/fseek/no ReadByte/etc. [eventually: test
X write(bytes) vs. fwrite(words), especially on Crays/Alphas]
X
X soon; ReadByte gone already.
X
X o incorporate new backfill version of inflate()
X
X next after fread/fseek/ReadByte
X
X o add multi-part zipfile handling
X
X next after that
X
X o check NEXTBYTE for EOF in crypt.c, funzip.c and explode.c, too
X
X soon
X
X o use (simple!) configure script in combination with Unix Makefile
X
X someday
X
X o add option to force completely non-interactive operation (no queries
X for overwrite/rename, password, etc.); also allow some sort of non-
X interactive password provision? (file? command-line? env. variable?)
X
X someday?
X
X o add ONLY_ZIPINFO compilation for 16-bit compiles
X
X later, possibly never
X
X o add testing of extra fields (if have CRC)
X
X later
X
X o change all output so goes through configurable routines (msg(),
X warn(), err()) for simpler GUI interfacing
X
X later
X
X o rewrite to allow use as a filter
X
X way, way later...
X
X o add option to search zipfile contents for a string and print the
X results? ("zipgrep" option--e.g., unzip -g or unzip -S) (easy for
X fixed strings, hard for wildcards/true regex's)
X
X way, way later, if at all...
X
X o add -y "display symlinks" option to zipinfo? various sorting options?
X (-St date/time, -Sn name)?
X
X who knows
X
X o add "in-depth" option to zipinfo? (check local headers against
X central, etc.)--make it a better debugging tool (or just create
X zipfix)
X
X who knows
X
X o ports underway: Acorn/RISCos, AOS/VS, ...
X
X
X- allow multiple dir creation with -d option? (Bob Maynard)
X
END_OF_FILE
if test 2854 -ne `wc -c <'unzip-5.12/ToDo'`; then
echo shar: \"'unzip-5.12/ToDo'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/ToDo'
fi
if test -f 'unzip-5.12/amiga/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/Contents'\" \(2025 characters\)
sed "s/^X//" >'unzip-5.12/amiga/Contents' <<'END_OF_FILE'
XContents of the "amiga" sub-archive for UnZip 5.11 and later:
X
X Contents this file
X amiga.c Amiga-specific file I/O routines
X amiga.h Amiga-specific header file
X filedate.c SetFileDate() clone for OS 1.3, based on Paul Wells' utime()
X
X SMakeFile SAS/C makefile for UnZip and fUnZip
X
X makefile.azt Aztec C makefile for UnZip and fUnZip
X stat.c stat() emulation for Aztec
X z-stat.h "real" stat.h header file for Aztec
X flate.a assembler version of inflate_codes() (define ASM_INFLATECODES)
X crc_68.a assembler version of crc_32_tab loop (define ASM_CRC, REGARGS)
X
XNotes:
X
X Both the routines, flate.a and crc_68.a, require arg passing via registers.
X
X To include flate.a, unzip must be built using 16-bit integers.
X (currently not possible with SAS/C)
X
X The DICE makefile has been removed since no one is supporting that
X compiler anymore.
X
X It was discovered on release of UnZip 5.1 that the latest SAS compiler
X revision (6.50 or 6.51) changed the timezone handling. The result is
X that UnZip can extract files with the wrong times, usually off by an
X offset of a few hours which is a function of the how the TZ environment
X variable is set. Now the TZ variable needs to be set according to the
X timezone you are in, because the tzname() function operates correctly
X now (it didn't used to). If you do not set TZ to your current timezone,
X files will be restored with times corrsponding to CST6, which is US/Central
X time, the SAS/C default. On the Amiga, the TZ variable cannot utilize
X the daylight savings time extentions, so don't use them. For example,
X specify "EST5" instead of "EST5EDT". The latter form will confuse the
X SAS/C libraries. To set the TZ environment variable, place the following
X line in your startup sequence:
X
X setenv TZ XXXN
X
X where XXX is the 3-character timezone notation
X N is the offset from Greenwich mean time
X
X example:
X
X setenv TZ PST8 ; for California time
END_OF_FILE
if test 2025 -ne `wc -c <'unzip-5.12/amiga/Contents'`; then
echo shar: \"'unzip-5.12/amiga/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/Contents'
fi
if test -f 'unzip-5.12/amiga/amiga.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/amiga.h'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/amiga.h'\" \(1126 characters\)
sed "s/^X//" >'unzip-5.12/amiga/amiga.h' <<'END_OF_FILE'
X/* amiga.h
X *
X * Globular definitions that affect all of AmigaDom.
X *
X * Originally included in unzip.h, extracted for simplicity and eeze of
X * maintenance by John Bush.
X *
X * THIS FILE IS #INCLUDE'd by unzip.h

X *
X */
X

X#include <time.h>
X
X
X#ifdef AZTEC_C /* Manx Aztec C, 5.0 or newer only */
X# include <clib/dos_protos.h>
X# include <pragmas/dos_lib.h>
X# define MODERN
X# define O_BINARY 0
X# include "amiga/z-stat.h"
X# define dirent direct
X# ifdef ASM_CRC
X# pragma regcall(CalcCRC(a0,d0,a1,d1))
X# endif


X#endif /* AZTEC_C */
X
X

X#if defined(LATTICE) || defined(__SASC) || defined(__SASC_60)
X# include <sys/types.h>
X# include <sys/stat.h>
X# include <sys/dir.h>
X# include <dos.h>
X# include <proto/dos.h> /* needed? */
X# if ( (!defined(O_BINARY)) && defined(O_RAW))
X# define O_BINARY O_RAW


X# endif
X# ifdef ASM_CRC

X /* PUT SOMETHING HERE TO PASS ARGS IN REGISTERS TO CalcCRC() */
X# endif
X#endif /* LATTICE */
X
X/* Funkshine Prough Toe Taipes */
X
Xint cmptime (struct tm *, struct tm *);
Xtime_t invlocal (struct tm *);
XLONG FileDate (char *, time_t[]);
X
X#define dup /* needed? */
END_OF_FILE
if test 1126 -ne `wc -c <'unzip-5.12/amiga/amiga.h'`; then
echo shar: \"'unzip-5.12/amiga/amiga.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/amiga.h'
fi
if test -f 'unzip-5.12/amiga/crc_68.a' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/crc_68.a'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/crc_68.a'\" \(1758 characters\)
sed "s/^X//" >'unzip-5.12/amiga/crc_68.a' <<'END_OF_FILE'
X; Not copyrighted by Paul Kienitz, 18 Jun 94.
X;
X; Return an updated 32 bit CRC value, given the old value and a block of data.
X; This substitutes for the following lines at the top of flush() in file_io.c
X; in UnZip, or a similar loop in updcrc() in util.c in Zip:
X;


X; register ulg crcval = crc32val;
X; register ulg n = size;

X; register uch *p=rawbuf;


X; while (n--)
X; crcval = crc_32_tab[((uch)crcval ^ (*p++)) & 0xff] ^ (crcval >> 8);
X; crc32val = crcval;

X;
X; Those lines are replace with this call:
X;


X; crc32val = CalcCRC(crc_32_tab, crc32val, rawbuf, size);

X;
X; We have here the CalcCRC() code for Amiga. Define REGARGS if you can cause
X; your compiler to put the four args in the registers A0, D0, A1, D1. I'm not
X; sure, but I think you should define ATSIGN when using the SAS/C assembler.
X; I wrote this because I found that, at least with the Aztec compiler, this loop
X; was occupying about a quarter of the CPU time with UnZip -t commands.
X
X xdef _CalcCRC
X
Xtemp equr d2
X
Xcrc_table equr a0 array of unsigned long
Xcrcval equr d0 unsigned long initial value
Xrawbuf equr a1 array of unsigned char
Xrawbufsize equr d1 unsigned long (count of bytes in rawbuf)
X
X
X IFD REGARGS
X IFD ATSIGN
X xdef @CalcCRC
X@CalcCRC:
X ELSE
X_CalcCRC: ; args already in registers as named above
X ENDC
X ELSE ; !REGARGS
X_CalcCRC:
X move.l 4(sp),crc_table
X move.l 8(sp),crcval
X move.l 12(sp),rawbuf
X move.l 16(sp),rawbufsize
X ENDC
X
X move.l temp,-(sp)
Xloop:
X subq.l #1,rawbufsize
X blt.s done ; we treat it as signed
X moveq #0,temp
X move.b (rawbuf)+,temp
X eor.b crcval,temp
X lsl.w #2,temp
X move.l 0(crc_table,temp.w),temp
X lsr.l #8,crcval
X eor.l temp,crcval
X bra.s loop
Xdone:
X;;; move.l crcval,d0 ; crcval already is d0
X move.l (sp)+,temp
X rts
END_OF_FILE
if test 1758 -ne `wc -c <'unzip-5.12/amiga/crc_68.a'`; then
echo shar: \"'unzip-5.12/amiga/crc_68.a'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/crc_68.a'
fi
if test -f 'unzip-5.12/amiga/z-stat.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/amiga/z-stat.h'\"
else
echo shar: Extracting \"'unzip-5.12/amiga/z-stat.h'\" \(2562 characters\)
sed "s/^X//" >'unzip-5.12/amiga/z-stat.h' <<'END_OF_FILE'
X#ifndef __Z_STAT_H
X#define __Z_STAT_H
X#define __STAT_H
X
X/* Since older versions of the Lattice C compiler for Amiga, and all current */
X/* versions of the Manx Aztec C compiler for Amiga, either provide no stat() */
X/* function or provide one inadequate for unzip (Aztec's has no st_mode */
X/* field), we provide our own stat() function in stat.c by Paul Wells, and */
X/* this fake stat.h file by Paul Kienitz. Paul Wells originally used the */
X/* Lattice stat.h but that does not work for Aztec and is not distributable */
X/* with this package, so I made a separate one. This has to be pulled into */
X/* unzip.h when compiling an Amiga version, as "amiga/z-stat.h". */
X
X/* We also provide here a "struct direct" for use with opendir() & readdir() */
X/* functions included in amiga/stat.c. If you use amiga/stat.c, this must */
X/* be included wherever you use either readdir() or stat(). */
X
X/* This include file should ONLY be loaded if AZTEC_C is defined, and
X * you are using the substitute version of stat() from amiga/stat.c.
X * Bit definitions are based on those in headers for SAS/C v6.0
X */
X
X#include <time.h>
X
Xstruct stat {
X unsigned short st_mode;
X time_t st_ctime, st_atime, st_mtime;
X long st_size;
X long st_ino;
X long st_blocks;
X short st_attr, st_dev, st_nlink, st_uid, st_gid, st_rdev;
X};
X
X#define S_IFDIR (1<<11)
X#define S_IFREG (1<<10)
X
X#if 0
X /* these values here are totally random: */
X# define S_IFLNK (1<<14)
X# define S_IFSOCK (1<<13)
X# define S_IFCHR (1<<8)
X# define S_IFIFO (1<<7)
X# define S_IFMT (S_IFDIR|S_IFREG|S_IFCHR|S_IFLNK)
X#else
X# define S_IFMT (S_IFDIR|S_IFREG)
X#endif
X
X#define S_IHIDDEN (1<<7)
X#define S_ISCRIPT (1<<6)
X#define S_IPURE (1<<5)
X#define S_IARCHIVE (1<<4)
X#define S_IREAD (1<<3)
X#define S_IWRITE (1<<2)
X#define S_IEXECUTE (1<<1)
X#define S_IDELETE (1<<0)
X
Xint stat(char *name, struct stat *buf);
X
X
X#include <libraries/dos.h>
X
Xtypedef struct direct {
X struct direct *d_cleanuplink,
X **d_cleanupparent;
X BPTR d_parentlock;
X struct FileInfoBlock d_fib;
X} DIR;
X#define d_name d_fib.fib_FileName
X
Xextern unsigned short disk_not_mounted; /* flag set by opendir() */
X
XDIR *opendir(char *);
Xvoid closedir(DIR *);
Xvoid close_leftover_open_dirs(void); /* call this if aborted in mid-run */
XDIR *readdir(DIR *);
X
Xint rmdir(char *);
X
X# ifdef AZTEC_C
Xvoid tzset(void);
Xint chmod(char *filename, int bits);
X# endif
X
X#endif /* __Z_STAT_H */
END_OF_FILE
if test 2562 -ne `wc -c <'unzip-5.12/amiga/z-stat.h'`; then
echo shar: \"'unzip-5.12/amiga/z-stat.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/amiga/z-stat.h'
fi
if test -f 'unzip-5.12/crypt.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/crypt.h'\"
else
echo shar: Extracting \"'unzip-5.12/crypt.h'\" \(708 characters\)
sed "s/^X//" >'unzip-5.12/crypt.h' <<'END_OF_FILE'
X/*
X crypt.h (dummy version) by Info-ZIP. Last revised: 18 Apr 94
X
X This is a non-functional version of Info-ZIP's crypt.h encryption/
X decryption header file for Zip, ZipCloak, UnZip and fUnZip. This
X file is not copyrighted and may be distributed without restriction.
X See the "Where" file for sites from which to obtain the full crypt
X sources (zcrypt21.zip or later).
X */
X
X#ifndef __crypt_h /* don't include more than once */
X#define __crypt_h
X
X#ifdef CRYPT
X# undef CRYPT /* dummy version */
X#endif
X
X#define RAND_HEAD_LEN 12 /* needed to compile funzip */
X
X#define zencode
X#define zdecode
X
X#define zfwrite fwrite
X
X#define echoff(f)
X#define echon()
X
X#endif /* !__crypt_h */
END_OF_FILE
if test 708 -ne `wc -c <'unzip-5.12/crypt.h'`; then
echo shar: \"'unzip-5.12/crypt.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/crypt.h'
fi
if test -f 'unzip-5.12/funzip.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/funzip.doc'\"
else
echo shar: Extracting \"'unzip-5.12/funzip.doc'\" \(3592 characters\)
sed "s/^X//" >'unzip-5.12/funzip.doc' <<'END_OF_FILE'
X
XFUNZIP(1) USER COMMANDS FUNZIP(1)
X
XNAME
X funzip - filter for extracting from a ZIP archive in a pipe
X
XSYNOPSIS
X [...] | funzip [-password] | [...]
X
X funzip [-password] input.zip | [...]
X
XARGUMENTS
X [-password]
X Optional password to be used if ZIP archive is
X encrypted. Decryption may not be supported at some
X sites. See DESCRIPTION for more details.
X
XDESCRIPTION
X funzip acts as a filter; that is, it assumes that a ZIP
X archive is being piped into standard input, and it extracts
X the first member from the archive to stdout. If there is an
X argument, then the input comes from the specified file
X instead of from stdin. A password for encrypted zip files
X can be specified on the command line (preceding the file
X name, if any) by prefixing the password with a dash. Note
X that this constitutes a security risk on many systems;
X currently running processes are often visible via simple
X commands (e.g., ps(1) under Unix), and command-line his-
X tories can be read. If the first entry of the zip file is
X encrypted and no password is specified on the command line,
X then the user is prompted for a password and the password is
X not echoed on the console.
X
X Given the limitation on single-member extraction, funzip is
X most useful in conjunction with a secondary archiver program
X such as tar(1). The following section includes an example
X illustrating this usage in the case of disk backups to tape.
X
XEXAMPLES
X To use funzip to extract the first member file of the
X archive test.zip and to pipe it into more(1):
X
X funzip test.zip | more
X
X To use funzip to test the first member file of test.zip (any
X errors will be reported on standard error):
X
X funzip test.zip > /dev/null
X
X To use zip and funzip in place of compress(1) and zcat(1)
X (or gzip(1L) and gzcat(1L)) for tape backups:
X
X tar cf - . | zip -7 | dd of=/dev/nrst0 obs=8k
X dd if=/dev/nrst0 ibs=8k | funzip | tar xf -
X
XInfo-ZIP Last change: 28 Aug 94 (v3.83) 1
X
XFUNZIP(1) USER COMMANDS FUNZIP(1)
X
X (where, for example, nrst0 is a SCSI tape drive).
X
XBUGS
X When piping an encrypted file into more and allowing funzip
X to prompt for password, the terminal may sometimes be reset
X to a non-echo mode. This is apparently due to a race condi-
X tion between the two programs; funzip changes the terminal
X mode to non-echo before more reads its state, and more then
X ``restores'' the terminal to this mode before exiting. To
X recover, run funzip on the same file but redirect to
X /dev/null rather than piping into more; after prompting
X again for the password, funzip will reset the terminal prop-
X erly.
X
X There is presently no way to extract any member but the
X first from a ZIP archive. This would be useful in the case
X where a ZIP archive is included within another archive. In
X the case where the first member is a directory, funzip sim-
X ply creates the directory and exits.
X
X The functionality of funzip should be incorporated into
X unzip itself (future release).
X
XSEE ALSO
X gzip(1L), unzip(1L), unzipsfx(1L), zip(1L), zipcloak(1L),


X zipinfo(1L), zipnote(1L), zipsplit(1L)
X
XAUTHOR

X Mark Adler (Info-ZIP)
X
XInfo-ZIP Last change: 28 Aug 94 (v3.83) 2
X
END_OF_FILE
if test 3592 -ne `wc -c <'unzip-5.12/funzip.doc'`; then
echo shar: \"'unzip-5.12/funzip.doc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/funzip.doc'
fi
if test -f 'unzip-5.12/human68k/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/human68k/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/human68k/Contents'\" \(411 characters\)
sed "s/^X//" >'unzip-5.12/human68k/Contents' <<'END_OF_FILE'
XContents of the "human68k" sub-archive for UnZip 5.1 and later:


X
X Contents this file

X Makefile.gcc (shorter) makefile for GNU C on X68000
X human68k.c Human68K-specific routines for UnZip
X options.s TwentyOne option checker (assembler routines) for Human68K
X
XNote that options.s contains high-order ASCII characters; it must be
Xtreated as a binary file when e-mailing or posting via Usenet.
END_OF_FILE
if test 411 -ne `wc -c <'unzip-5.12/human68k/Contents'`; then
echo shar: \"'unzip-5.12/human68k/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/human68k/Contents'
fi
if test -f 'unzip-5.12/human68k/Makefile.gcc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/human68k/Makefile.gcc'\"
else
echo shar: Extracting \"'unzip-5.12/human68k/Makefile.gcc'\" \(2235 characters\)
sed "s/^X//" >'unzip-5.12/human68k/Makefile.gcc' <<'END_OF_FILE'
X# Makefile for UnZip 5.11 and later: Human68K with gcc NIIMI Satoshi
X#
X# The original Makefile maybe works fine, but X68000 is too slow
X# to process it. So I split out needed part.
X#
X# Last revised: 10 Jul 94
X
XVPATH = HUMAN68K
X
XCC = gcc
XCFLAGS = -Wall -O -I. -fomit-frame-pointer -fstrength-reduce
XLDFLAGS = -s
X
XLIBS = -lsignal -ldos -lmb


X
X# UnZipSFX flags
XXC = -DSFX

X
X# fUnZip flags
XFC = -DFUNZIP
X

X# object files
XOBJS = unzip.o crypt.o envargs.o explode.o extract.o file_io.o inflate.o \
X match.o unreduce.o unshrink.o zipinfo.o human68k.o options.o
XOBJX = unzipsfx.o crypt.o extract_.o file_io.o inflate.o match.o human68_.o
XOBJF = funzip.o crypt_.o inflate_.o
X
XUNZIPS = unzip.x unzipsfx.x funzip.x
X
X.c.o:
X $(CC) $(CFLAGS) -I. -c $< -o $@
X
X# for debugging
X.c.s:
X $(CC) $(CFLAGS) -c $< -o $@


X
Xall: unzips
Xunzips: $(UNZIPS)
Xdocs: $(DOCS)
Xunzipsman: unzips docs
Xunzipsdocs: unzips docs
X

Xclean:
X rm -f $(OBJS) $(OBJF) $(OBJX) $(UNZIPS)
X

Xunzip.x: $(OBJS)
X $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
X
Xunzipsfx.x: $(OBJX)
X $(CC) $(LDFLAGS) -o $@ $(OBJX) $(LIBS)
X
Xfunzip.x: $(OBJF)
X $(CC) $(LDFLAGS) -o $@ $(OBJF) $(LIBS)
X


Xcrypt.o: crypt.c unzip.h zip.h crypt.h
Xenvargs.o: envargs.c unzip.h
Xexplode.o: explode.c unzip.h
Xextract.o: extract.c unzip.h crypt.h
Xfile_io.o: file_io.c unzip.h crypt.h tables.h
Xfunzip.o: funzip.c unzip.h crypt.h tables.h
Xinflate.o: inflate.c inflate.h unzip.h
Xmatch.o: match.c unzip.h

Xunreduce.o: unreduce.c unzip.h
Xunshrink.o: unshrink.c unzip.h

Xunzip.o: unzip.c unzip.h crypt.h version.h
Xzipinfo.o: zipinfo.c unzip.h
X
Xcrypt_.o: crypt.c unzip.h zip.h crypt.h # used by funzip
X $(CC) $(CFLAGS) $(FC) -c $< -o $@
X
Xextract_.o: extract.c unzip.h crypt.h # used by unzipsfx
X $(CC) $(CFLAGS) $(XC) -c $< -o $@
X
Xhuman68k.o: human68k/human68k.c unzip.h
X $(CC) $(CFLAGS) -I. -c human68k/human68k.c -o $@
X
Xhuman68_.o: human68k/human68k.c unzip.h # used by unzipsfx
X $(CC) $(CFLAGS) $(XC) -I. -c human68k/human68k.c -o $@
X
Xinflate_.o: inflate.c inflate.h unzip.h crypt.h # used by funzip
X $(CC) $(CFLAGS) $(FC) -c $< -o $@
X
Xunzipsfx.o: unzip.c unzip.h crypt.h version.h # used by unzipsfx
X $(CC) $(CFLAGS) $(XC) -c $< -o $@
X
Xdiff:
X -(cd ..; diff -cNr unz51f unz51f-x68k -x GNUmakefile -x "*.[ox]" > unzip68k.dif)
END_OF_FILE
if test 2235 -ne `wc -c <'unzip-5.12/human68k/Makefile.gcc'`; then
echo shar: \"'unzip-5.12/human68k/Makefile.gcc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/human68k/Makefile.gcc'
fi
if test -f 'unzip-5.12/inflate.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/inflate.h'\"
else
echo shar: Extracting \"'unzip-5.12/inflate.h'\" \(887 characters\)
sed "s/^X//" >'unzip-5.12/inflate.h' <<'END_OF_FILE'
X/* inflate.h for UnZip -- put in the public domain by Mark Adler
X version c14e, 29 September 1993 */


X
X
X/* You can do whatever you like with this source file, though I would
X prefer that if you modify it and redistribute it that you include
X comments to that effect with your name and the date. Thank you.
X
X History:
X vers date who what
X ---- --------- -------------- ------------------------------------

X c14 12 Mar 93 M. Adler made inflate.c standalone with the
X introduction of inflate.h.

X c14d 28 Aug 93 G. Roelofs replaced flush/FlushOutput with new version
X c14e 29 Sep 93 G. Roelofs moved everything into unzip.h; added crypt.h
X */
X
X#include "unzip.h" /* provides slide[], typedefs and macros */
X#ifdef FUNZIP
X# include "crypt.h" /* provides NEXTBYTE macro for crypt version of funzip */
X#endif
END_OF_FILE
if test 887 -ne `wc -c <'unzip-5.12/inflate.h'`; then
echo shar: \"'unzip-5.12/inflate.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/inflate.h'
fi
if test -f 'unzip-5.12/mac/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/mac/Contents'\" \(1060 characters\)
sed "s/^X//" >'unzip-5.12/mac/Contents' <<'END_OF_FILE'
XContents of the "mac" sub-archive for UnZip 5.1 and later:


X
X Contents this file

X mac.c Mac-specific filesystem code
X macdir.c Macintosh Unix-style directory emulation
X macdir.h header file for directory emulation
X macscreen.c Macintosh window handling routines
X macstat.c Macintosh stat() emulation
X macstat.h header file for stat() emulation
X macunzip.c Macintosh standalone version main program
X rsrc.hqx resource file for Macintosh unzip (BinHex)
X thinkc.hqx Think C project file (BinHex)
X
XThe resource file and the Think C project file are in BinHex form because
Xthey contain Macintosh resource forks (only) and as such can not be simply
Xstored a normal file on a non-Macintosh system. BinHex form is the
Xtraditional way for transferring such files via non-Macintosh systems. It's
Xalso the safest since it uses only printable characters. Both of the ".hqx"
Xfiles must be converted with BinHex 4.0 (or equivalent) on a Macintosh
Xsystem prior to attempted use.
END_OF_FILE
if test 1060 -ne `wc -c <'unzip-5.12/mac/Contents'`; then
echo shar: \"'unzip-5.12/mac/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/Contents'
fi
if test -f 'unzip-5.12/mac/macdir.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macdir.h'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macdir.h'\" \(780 characters\)
sed "s/^X//" >'unzip-5.12/mac/macdir.h' <<'END_OF_FILE'
X/*****************************************************************
X *
X * dirent.h
X *
X *****************************************************************/
X
X#ifndef __DIRENT_H
X#define __DIRENT_H
X
X#include <errno.h>
X
X#ifndef ENOTDIR
X#define ENOTDIR 20
X#endif
X
X#ifndef NAME_MAX
X#define NAME_MAX 31
X#endif
X
Xstruct dirent {
X unsigned long d_fileno;
X short d_reclen;
X short d_namlen;
X char d_name[NAME_MAX + 1];
X};
X
Xtypedef struct {
X short ioFDirIndex;
X short ioVRefNum;
X long ioDrDirID;
X short flags;
X struct dirent currEntry;
X} DIR;
X
X#define direct dirent
X
XDIR *opendir(char *);
Xstruct dirent *readdir(DIR *);
Xvoid rewinddir(DIR *);
Xint closedir(DIR *);
X#endif
END_OF_FILE
if test 780 -ne `wc -c <'unzip-5.12/mac/macdir.h'`; then
echo shar: \"'unzip-5.12/mac/macdir.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macdir.h'
fi
if test -f 'unzip-5.12/mac/macstat.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/mac/macstat.h'\"
else
echo shar: Extracting \"'unzip-5.12/mac/macstat.h'\" \(974 characters\)
sed "s/^X//" >'unzip-5.12/mac/macstat.h' <<'END_OF_FILE'
X/*****************************************************************
X *
X * stat.h
X *
X *****************************************************************/
X
X#include <time.h>
Xextern int macstat(char *path, struct stat *buf, short nVRefNum, long lDirID );
Xtypedef long dev_t;
Xtypedef long ino_t;
Xtypedef long off_t;
X
Xstruct stat {
X dev_t st_dev;
X ino_t st_ino;
X unsigned short st_mode;
X short st_nlink;
X short st_uid;
X short st_gid;
X dev_t st_rdev;
X off_t st_size;
X time_t st_atime, st_mtime, st_ctime;
X long st_blksize;
X long st_blocks;
X};
X
X#define S_IFMT 0xF000
X#define S_IFIFO 0x1000
X#define S_IFCHR 0x2000
X#define S_IFDIR 0x4000
X#define S_IFBLK 0x6000
X#define S_IFREG 0x8000
X#define S_IFLNK 0xA000
X#define S_IFSOCK 0xC000
X#define S_ISUID 0x800
X#define S_ISGID 0x400
X#define S_ISVTX 0x200
X#define S_IREAD 0x100
X#define S_IWRITE 0x80
X#define S_IEXEC 0x40
END_OF_FILE
if test 974 -ne `wc -c <'unzip-5.12/mac/macstat.h'`; then
echo shar: \"'unzip-5.12/mac/macstat.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/mac/macstat.h'
fi
if test -f 'unzip-5.12/msdos/Borland.fix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/Borland.fix'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/Borland.fix'\" \(3818 characters\)
sed "s/^X//" >'unzip-5.12/msdos/Borland.fix' <<'END_OF_FILE'
XNotes on patching Borland (binary) executables so they'll understand Unix-
Xstyle, LF-delimited ASCII files (from Onno van der Linden, c/o Frank van
Xder Linden, vdli...@fwi.uva.nl).
X
X
X1. The CPP used by TC 2.0 can't handle unix-style (LF-terminated) lines.
X The CPP used by BC++ 2.0 can.
X The CPP used by BC++ 3.0 can't handle #if statements with unix-style lines.
X Fixes for both these problems below (GRR: offset, new byte, old byte).
X
X Comparing files \TC\CPP.EXE and \TC\CPP.OLD
X 00004F25: 0D 0A
X 00005E3D: 0D 0A
X 00007916: 0D 0A
X 000079D6: 0D 0A
X 00007AC1: 0A 0D
X 0000D8EE: EC F7
X 0000D8F1: F7 EC
X 0000D9EE: EC F7
X 0000D9F1: F7 EC
X 0000DC80: 0A 0D
X 0000DC90: 0A 0D
X
X Comparing files \BORLANDC\BIN\CPP.EXE and \BORLANDC\BIN\CPP.OLD
X 0001D150: 89 75
X 0001D151: 36 08
X 0001D152: 30 89
X 0001D153: 23 36
X 0001D154: 75 30
X 0001D155: 04 23
X 0001D288: 9A 89
X 0001D289: FF 36
X 0001D28A: FF 30
X 0001D28B: 00 23
X 0001D28C: 00 9A
X 0001D28E: 0E FF
X 0001D28F: 30 00
X 0001D290: 23 00
X 0001E5A7: 89 8D
X
X
X2. The compilers (tcc 2.0 and bcc 3.0) are both one-pass compilers; i.e.,
X cpp.exe isn't used when compiling with tcc or bcc. The earlier statements
X about both cpp's are the same for the builtin preprocesser in the compilers.
X To fix the unix-style line stuff for the compilers, apply the fixes below.
X I do have something called bpatch.c which reads in the output of fc /b and
X changes the executable. If anyone is too lazy to write it himself, just
X send out a mail.
X
X Comparing files TCC.EXE and TCC.OLD
X 00005E06: BF 88
X 00005E07: 02 01
X 00005E0C: 88 BF
X 00005E0D: 01 02
X 00006E7C: 0A 0D
X 00011FF9: 0A 0D
X 00012059: 0A 0D
X 00017E6C: 0A 0D
X 00018181: 0A 0D
X 000181F6: 0A 0D
X 00018AC1: 0A 0D
X 00018B27: 0D 0A
X 00018BBE: 0A 0D
X 00018C12: 0A 0D
X 00018C6A: 0A 0D
X 0001948A: 0A 0D
X 000194B7: 0D 0A
X 00019507: 0A 0D
X 0001C093: 0A 0D
X 0001C495: 3C 89
X 0001C496: 0D 46
X 0001C497: 74 FC
X 0001C498: DF 3D
X 0001C499: FF 0D
X 0001C49A: 0E 00
X 0001C49B: 34 75
X 0001C49C: 50 03
X 0001C49D: 3C E9
X 0001C49E: 0A F6
X 0001C49F: 75 FB
X 0001C4A0: 03 FF
X 0001C4A1: E9 0E
X 0001C4A2: F2 34
X 0001C4A3: FB 50
X 0001C4D0: 0A 0D
X 0001CFA7: 0A 0D
X 0001CFBA: 0D 0A
X 0001D007: 0A 0D
X 0002A13C: 0A 0D
X 0002A14C: 0A 0D
X 0002A2B6: EC F7
X 0002A2B9: F7 EC
X 0002A3B6: EC F7
X 0002A3B9: F7 EC
X 0002A4B6: EC F7
X 0002A4B9: F7 EC
X 0002BDC3: 20 21
X 0002BDC6: 21 20
X
X Comparing files BCC.EXE and BCC.OLD
X 0002B877: 89 75
X 0002B878: 36 08
X 0002B879: 5C 89
X 0002B87A: 5F 36
X 0002B87B: 75 5C
X 0002B87C: 04 5F
X 0002B9AF: 0E 89
X 0002B9B0: E8 36
X 0002B9B1: 56 5C
X 0002B9B2: DC 5F
X 0002B9B3: FF 90
X 0002B9B5: 5C E8
X 0002B9B6: 5F 51
X 0002B9B7: 90 DC
X
X Just an addition: the first one was for the cpp.exe's, the recent one is for
X the compilers (bcc.exe, tcc.exe). The first one is a bit redundant because
X cpp.exe is hardly ever used. See it as an attempt to make things complete.
X
X
X3. For those of you who are using NDMAKE45 under MSDOS:
X version 4.5 predefines the macro's MAKE and MFLAGS as readonly's.
X So there was no way you could use $(MAKE) with ndmake45.
X Here are the fc /b's that make things work:
X
X Comparing files MAKE45.EXE and MAKE45.OLD
X 000019C0: 00 03 # MFLAG
X 000019DC: 00 03 # MAKE
X 00007BEA: 0A 7E # output of make -p
X 00007BEB: 00 0A #
X
X Comparing files MAKE45L.EXE and MAKE45L.OLD
X 0000277E: 00 03 # MFLAG
X 0000279D: 00 03 # MAKE
X 0000A6A8: 0A 7E # output of make -p
X 0000A6A9: 00 0A
X
END_OF_FILE
if test 3818 -ne `wc -c <'unzip-5.12/msdos/Borland.fix'`; then
echo shar: \"'unzip-5.12/msdos/Borland.fix'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/Borland.fix'
fi
if test -f 'unzip-5.12/msdos/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/Contents'\" \(2323 characters\)
sed "s/^X//" >'unzip-5.12/msdos/Contents' <<'END_OF_FILE'
XContents of the "msdos" sub-archive for UnZip 5.11 and later:
X
X Contents this file
X README notes about quirks in MS-DOS executables and compilers
X msdos.c OS-dependent UnZip routines for MS-DOS
X makefile.bc makefile for Borland C++ and Turbo C++
X makefile.msc makefile for Microsoft C and make or nmake
X makefile.tc makefile for Turbo C and make
X Borland.fix patches to fix Borland executables for grokking Unix EOLs
X
XNotes:
X
X(1) As of UnZip 5.1, Borland project files are no longer included. They
X were not as flexible as the makefiles, and the binary ones caused prob-
X lems for both the comp.sources.misc moderator and the UnZip maintainer.
X By way of compensation, what used to be called simply "makefile" has
X been split into makefile.msc and makefile.tc (the latter for old Turbo C
X compilers).
X
X(2) As of UnZip 5.11, makefile.gcc (for djgpp/GNU make) is no longer provided.
X Instead use the gcc_dos target in the Unix makefile (unix/Makefile) after
X copying it to the main UnZip directory. Note that, because of bugs in
X the MS-DOS port of GNU make, the gcc_dos target does not make use of the
X MAKE variable; therefore users of other makes (e.g., nmake) will have to
X edit the target or rename their make utility to "make".
X
X(3) The Unix makefile also has an msc_dos target which can be used for MSC 6.0
X or later, but such use is discouraged and the target may disappear in the
X future--use makefile.msc instead.
X
X(4) For DOS emx+gcc use the gccdos target in the OS/2 makefile.os2. This
X target has only been tested in cross-compilation from OS/2 to MS-DOS,
X but it should work under plain MS-DOS with a proper make utility. The
X resulting executables require emx.exe to run (akin to djgpp's go32.exe).
X
X(5) The binary patches in Borland.fix are NOT required; they may be useful
X if you regularly deal with Unix sources, but casual users should probably
X make use of an external utility like Rahul Dhesi's FLIP to convert between
X Unix and DOS/OS2 end-of-line characters. If you know how to patch binary
X executables, you should be able to figure out how to use these patches.
X Presumably they don't work for more recent versions of the executables
X anyway; they'll probably be removed in the next version.
END_OF_FILE
if test 2323 -ne `wc -c <'unzip-5.12/msdos/Contents'`; then
echo shar: \"'unzip-5.12/msdos/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/Contents'
fi
if test -f 'unzip-5.12/msdos/makefile.bc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/makefile.bc'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/makefile.bc'\" \(3487 characters\)
sed "s/^X//" >'unzip-5.12/msdos/makefile.bc' <<'END_OF_FILE'
X# Makefile for UnZip(SFX) and fUnZip for Borland C++ 2.x/3.0 and Turbo C++ 1.0
X# Version: 5.12 and later Alvin Koh, Jim Knoble, Christian Spieler, etc.
X#
X# Last revised: 11 Aug 94
X
X
X# for Borland C++ uncomment this and comment out the tcc line:
XCC = bcc
X
X# for Turbo C++ uncomment this and comment out the bcc line:
X#CC = tcc
X
X#TASM = tasm # not used
X
X#UNMODEL = s # small model for UnZip and ZipInfo, now that strings moved
XUNMODEL = l # large model for UnZip (M. Lawler/BC 4.0: _text > 64K w/ "s")
XFUMODEL = s # always use small model for fUnZip
X
X# GNU make doesn't like the return value from "rem"
X#STRIP=rem
XSTRIP=echo Ignore this line.
X# If you don't have LZEXE or PKLITE, get one of them. Then define:
X#STRIP=lzexe
X# or
X#STRIP=pklite
X# This makes a big difference in .exe size (and possibly load time).
X
X
X# Optional nonstandard preprocessor flags (as -DCHECK_EOF or -DDOS_WILD)
X# should be added to the environment via "set LOCAL_UNZIP=-DFOO" or added
X# to the declaration of LOC here:
XLOC = $(LOCAL_UNZIP)
X
X
X# compiler flags
X
XCFLAGS = -O -ff- -k- -P-.C -I. $(LOC)
XUNFLAGS = -m$(UNMODEL) $(CFLAGS)
XFUFLAGS = -m$(FUMODEL) $(CFLAGS) -K -d
XLDFLAGS = -lxncd -l-P # for bcc
X#LDFLAGS = -lxncd # for tcc
X
X# implicit rules
X
X.c.obj:
X $(CC) -c $(UNFLAGS) {$< }
X
X# list macros
X
Xunzip_dependencies = \
X unzip.obj \
X crypt.obj \
X envargs.obj \
X explode.obj \
X extract.obj \
X file_io.obj \
X inflate.obj \
X match.obj \
X unreduce.obj \
X unshrink.obj \
X zipinfo.obj \
X msdos.obj
X
Xfunzip_dependencies = \
X funzip.obj \
X crypt_.obj \
X inflate_.obj
X
Xunzipsfx_dependencies = \
X unzip_.obj \
X crypt.obj \
X extract_.obj \
X file_io.obj \
X inflate.obj \
X match.obj \
X msdos_.obj
X
X# explicit rules


X
Xall: unzip.exe funzip.exe unzipsfx.exe
X

Xunzip.exe: $(unzip_dependencies)
X $(CC) -m$(UNMODEL) $(LDFLAGS) -eunzip.exe @&&|
Xunzip.obj
Xcrypt.obj
Xenvargs.obj
Xexplode.obj
Xextract.obj
Xfile_io.obj
Xinflate.obj
Xmatch.obj
Xunreduce.obj
Xunshrink.obj
Xzipinfo.obj
Xmsdos.obj
X|
X $(STRIP) unzip.exe
X
Xfunzip.exe: $(funzip_dependencies)
X $(CC) -m$(FUMODEL) $(LDFLAGS) -efunzip.exe @&&|
Xfunzip.obj
Xcrypt_.obj
Xinflate_.obj
X|
X $(STRIP) funzip.exe
X
Xunzipsfx.exe: $(unzipsfx_dependencies)
X $(CC) -m$(UNMODEL) $(LDFLAGS) -eunzipsfx.exe @&&|
Xunzip_.obj
Xcrypt.obj
Xextract_.obj
Xfile_io.obj
Xinflate.obj
Xmatch.obj
Xmsdos_.obj
X|
X $(STRIP) unzipsfx.exe
X
X# individual file dependencies
X
Xcrypt.obj: crypt.c unzip.h zip.h crypt.h
Xenvargs.obj: envargs.c unzip.h
Xexplode.obj: explode.c unzip.h
Xextract.obj: extract.c unzip.h crypt.h
Xfile_io.obj: file_io.c unzip.h crypt.h tables.h
Xinflate.obj: inflate.c inflate.h unzip.h
Xmatch.obj: match.c unzip.h
Xunreduce.obj: unreduce.c unzip.h
Xunshrink.obj: unshrink.c unzip.h
Xunzip.obj: unzip.c unzip.h crypt.h version.h
Xzipinfo.obj: zipinfo.c unzip.h
X
Xmsdos.obj: msdos/msdos.c unzip.h
X $(CC) -c $(UNFLAGS) msdos/msdos.c
X
Xfunzip.obj: funzip.c unzip.h crypt.h tables.h
X $(CC) -c $(FUFLAGS) funzip.c
X
Xcrypt_.obj: crypt.c unzip.h zip.h crypt.h
X $(CC) -c $(FUFLAGS) -DFUNZIP -ocrypt_.obj crypt.c
X
Xinflate_.obj: inflate.c inflate.h unzip.h crypt.h
X $(CC) -c $(FUFLAGS) -DFUNZIP -oinflate_.obj inflate.c
X
Xunzip_.obj: unzip.c unzip.h crypt.h version.h
X $(CC) -c $(UNFLAGS) -DSFX -ounzip_.obj unzip.c
X
Xextract_.obj: extract.c unzip.h crypt.h
X $(CC) -c $(UNFLAGS) -DSFX -oextract_.obj extract.c
X
Xmsdos_.obj: msdos/msdos.c unzip.h
X $(CC) -c $(UNFLAGS) -DSFX -omsdos_.obj msdos/msdos.c
END_OF_FILE
if test 3487 -ne `wc -c <'unzip-5.12/msdos/makefile.bc'`; then
echo shar: \"'unzip-5.12/msdos/makefile.bc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/makefile.bc'
fi
if test -f 'unzip-5.12/msdos/makefile.msc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/makefile.msc'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/makefile.msc'\" \(3972 characters\)
sed "s/^X//" >'unzip-5.12/msdos/makefile.msc' <<'END_OF_FILE'
X#------------------------------------------------------------------------------
X# Makefile for UnZip 5.11 and later Greg Roelofs and others
X# Version: Microsoft C (5.x and later) 11 August 1994
X#------------------------------------------------------------------------------
X
X# Users of MSC 6/7 and NMAKE can use the Unix Makefile (target msc_dos),
X# if desired. This makefile works just fine, too, however. OS/2 users
X# can cross-compile using os2/makefile.os2 (target mscdos). Note that
X# there is possibly a bug in MSC 6 which screws up funzip (goes into
X# infinite loop? --this has not been confirmed in over a year...). There
X# is definitely a bug (internal compiler error) in MSC 6.00 while com-
X# piling explode.c (fixed in 6.0a, 6.0ax, 6.0ax2, 7.*, 8.*).
X
X
X# GNU make doesn't like the return value from "rem"
X#STRIP=rem
XSTRIP=echo Ignore this line.
X# If you don't have LZEXE or PKLITE, get one of them. Then define:
X#STRIP=lzexe
X# or
X#STRIP=pklite
X# and remove /e from LDFLAGS. This makes a big difference in
X# .exe size (and possibly load time).
X
X# Optional nonstandard preprocessor flags (as -DCHECK_EOF or -DDOS_WILD)
X# should be added to the environment via "set LOCAL_UNZIP=-DFOO" or added
X# to the declaration of LOC here:
XLOC = $(LOCAL_UNZIP)
X
X# small model (should work now, but if problems, use L)
XMODEL=S
X
XCC = cl # -Ox does not work for inflate.c
X# add -G2(3,4) for 286 (386, 486) and/or -FPi87 for 80x87:
XCFLAGS = -nologo -DMSC $(LOC) -Oait -Gs -I.
X
XLD = link
XLDFLAGS = /nologo/noi/e/st:0x0c00 # remove /e if you have LZEXE or PKLITE
XLDFLAGS2 = ,$*;
X
XOBJS1 = unzip.obj crypt.obj envargs.obj explode.obj extract.obj file_io.obj
XOBJS2 = inflate.obj match.obj unreduce.obj unshrink.obj zipinfo.obj
XOBJS3 = msdos.obj
XOBJS = $(OBJS1) $(OBJS2) $(OBJS3)
X
XOBJX = unzip_.obj crypt.obj extract_.obj file_io.obj inflate.obj match.obj\
X msdos_.obj
X
XOBJF = funzip.obj crypt_.obj inflate_.obj
X
X
Xdefault: unzip.exe funzip.exe unzipsfx.exe
X
X.c.obj:
X $(CC) -c -A$(MODEL) $(CFLAGS) $*.c
X
Xcrypt.obj: crypt.c unzip.h crypt.h zip.h
X
Xcrypt_.obj: crypt.c unzip.h crypt.h zip.h
X $(CC) -c -AS $(CFLAGS) -DFUNZIP -Focrypt_.obj crypt.c
X
Xenvargs.obj: envargs.c unzip.h
X
Xexplode.obj: explode.c unzip.h
X
Xextract.obj: extract.c unzip.h crypt.h
X
Xextract_.obj: extract.c unzip.h crypt.h
X $(CC) -c -A$(MODEL) $(CFLAGS) -DSFX -Foextract_.obj extract.c
X
Xfile_io.obj: file_io.c unzip.h crypt.h tables.h
X
Xfunzip.obj: funzip.c unzip.h crypt.h tables.h
X $(CC) -c -AS $(CFLAGS) funzip.c
X
Xinflate.obj: inflate.c unzip.h
X
Xinflate_.obj: inflate.c inflate.h unzip.h crypt.h
X $(CC) -c -AS $(CFLAGS) -DFUNZIP -Foinflate_.obj inflate.c
X
Xmatch.obj: match.c unzip.h
X
Xmsdos.obj: msdos/msdos.c unzip.h
X $(CC) -c -A$(MODEL) $(CFLAGS) msdos/msdos.c
X
Xmsdos_.obj: msdos/msdos.c unzip.h
X $(CC) -c -A$(MODEL) $(CFLAGS) -DSFX -Fomsdos_.obj msdos/msdos.c
X
Xunreduce.obj: unreduce.c unzip.h
X
Xunshrink.obj: unshrink.c unzip.h
X
Xunzip.obj: unzip.c unzip.h crypt.h version.h
X
Xunzip_.obj: unzip.c unzip.h crypt.h version.h
X $(CC) -c -A$(MODEL) $(CFLAGS) -DSFX -Founzip_.obj unzip.c
X
Xzipinfo.obj: zipinfo.c unzip.h
X
X
X# MS make:
X# -------
Xunzip.exe: $(OBJS)
X echo $(OBJS1)+ > unzip.rsp
X echo $(OBJS2)+ >> unzip.rsp
X echo $(OBJS3); >> unzip.rsp
X $(LD) $(LDFLAGS) @unzip.rsp
X del unzip.rsp
X $(STRIP) unzip.exe
X
X# better makes which know how to deal with 128 char limit on command line:
X# -----------------------------------------------------------------------
X#unzip.exe: $(OBJS)
X# $(LD) $(LDFLAGS) $(OBJS) $(LDFLAGS2)
X# $(STRIP) unzip.exe
X
X# both makes:
X# ----------
Xfunzip.exe: $(OBJF)
X $(LD) $(LDFLAGS) $(OBJF) $(LDFLAGS2)
X $(STRIP) funzip.exe
X
Xunzipsfx.exe: $(OBJX)
X echo $(OBJX), $@; > unzipsfx.rsp
X $(LD) $(LDFLAGS) @unzipsfx.rsp
X del unzipsfx.rsp
X $(STRIP) unzipsfx.exe
END_OF_FILE
if test 3972 -ne `wc -c <'unzip-5.12/msdos/makefile.msc'`; then
echo shar: \"'unzip-5.12/msdos/makefile.msc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/makefile.msc'
fi
if test -f 'unzip-5.12/msdos/makefile.tc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/msdos/makefile.tc'\"
else
echo shar: Extracting \"'unzip-5.12/msdos/makefile.tc'\" \(3520 characters\)
sed "s/^X//" >'unzip-5.12/msdos/makefile.tc' <<'END_OF_FILE'
X#-----------------------------------------------------------------------------
X# Makefile for UnZip 5.11 and later Jean-loup Gailly
X# Version: Turbo C (edit and use makefile.bc for Turbo C++) 10 July 1994
X#-----------------------------------------------------------------------------
X
X# GNU make doesn't like the return value from "rem"
X#STRIP=rem
XSTRIP=echo Ignore this line.
X# If you don't have LZEXE or PKLITE, get one of them. Then define:
X#STRIP=lzexe
X# or
X#STRIP=pklite
X# This makes a big difference in .exe size (and possibly load time).
X
X# memory model for UnZip (conflicting reports on whether Turbo C can or
X# cannot put strings into far memory; for now assume it can and use small
X# model *with* ZipInfo enabled...if fails, either define NO_ZIPINFO or
X# use large model) [GRR 940712: sigh, no go--inflate fails. Back to
X# large model...]
X#MODEL = s
XMODEL = l
X
XCC = tcc
XLD = $(CC)
X
XUCFLAGS = -m$(MODEL) -O -Z -I. -DFar=
XULDFLAGS = -m$(MODEL)
X
X# funzip is always small-model
XFCFLAGS = -ms -O -Z -I.
XFLDFLAGS = -ms
X
XLDFLAGS2 =
X
XOBJS = unzip.obj crypt.obj envargs.obj explode.obj extract.obj file_io.obj \
X inflate.obj match.obj unreduce.obj unshrink.obj zipinfo.obj msdos.obj
X
XOBJX = unzip_.obj crypt.obj extract_.obj file_io.obj inflate.obj match.obj \
X msdos_.obj
X
XOBJF = funzip.obj crypt_.obj inflate_.obj
X
Xdefault: unzip.exe funzip.exe unzipsfx.exe
X
Xclean:
X rem Ignore any errors in the following...
X del *.ob
X del *.obj
X del unzip.exe
X del funzip.exe
X
X.c.obj:
X $(CC) -c $(UCFLAGS) $*.c
X
Xcrypt.obj: crypt.c unzip.h crypt.h zip.h
X
Xcrypt_.obj: crypt.c unzip.h crypt.h zip.h
X $(CC) -c $(FCFLAGS) -DFUNZIP -ocrypt_.obj crypt.c
X
Xenvargs.obj: envargs.c unzip.h
X
Xexplode.obj: explode.c unzip.h
X
Xextract.obj: extract.c unzip.h crypt.h
X
Xextract_.obj: extract.c unzip.h crypt.h
X $(CC) -c $(UCFLAGS) -DSFX -oextract_.obj extract.c
X
Xfile_io.obj: file_io.c unzip.h crypt.h tables.h
X
Xfunzip.obj: funzip.c unzip.h crypt.h tables.h
X $(CC) -c $(FCFLAGS) funzip.c
X
Xinflate_.obj: inflate.c inflate.h unzip.h crypt.h
X $(CC) -c $(FCFLAGS) -DFUNZIP -oinflate_.obj inflate.c
X
Xinflate.obj: inflate.c inflate.h unzip.h
X
Xmatch.obj: match.c unzip.h
X
Xmsdos.obj: msdos/msdos.c unzip.h
X $(CC) -c $(UCFLAGS) msdos/msdos.c
X
Xmsdos_.obj: msdos/msdos.c unzip.h
X $(CC) -c $(UCFLAGS) -DSFX -omsdos_.obj msdos/msdos.c
X
Xunreduce.obj: unreduce.c unzip.h
X
Xunshrink.obj: unshrink.c unzip.h
X
Xunzip.obj: unzip.c unzip.h crypt.h version.h
X
Xunzip_.obj: unzip.c unzip.h crypt.h version.h
X $(CC) -c $(UCFLAGS) -DSFX -ounzip_.obj unzip.c
X
Xzipinfo.obj: zipinfo.c unzip.h
X
X
X# Turbo Make which cannot deal with the MS-DOS 128 byte limit:
X# -----------------------------------------------------------
Xunzip.exe: $(OBJS)
X rem Ignore any warnings in the following commands:
X del funzip.ob
X ren funzip.obj *.ob
X del crypt_.ob
X ren crypt_.obj *.ob
X del inflate_.ob
X ren inflate_.obj *.ob
X $(LD) $(ULDFLAGS) -eunzip.exe *.obj
X ren *.ob *.obj
X $(STRIP) unzip.exe
X
X# better makes which know how to deal with 128 char limit on command line:
X# -----------------------------------------------------------------------
X#unzip.exe: $(OBJS)
X# $(LD) $(ULDFLAGS) $(OBJS) $(LDFLAGS2)
X# $(STRIP) unzip.exe
X
X# both makes:
X# ----------
Xfunzip.exe: $(OBJF)
X $(LD) $(FLDFLAGS) $(OBJF) $(LDFLAGS2)
X $(STRIP) funzip.exe
X
Xunzipsfx.exe: $(OBJX)
X $(LD) $(ULDFLAGS) $(OBJX) $(LDFLAGS2)
X rename unzip_.exe unzipsfx.exe
X $(STRIP) unzipsfx.exe
END_OF_FILE
if test 3520 -ne `wc -c <'unzip-5.12/msdos/makefile.tc'`; then
echo shar: \"'unzip-5.12/msdos/makefile.tc'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/msdos/makefile.tc'
fi
if test -f 'unzip-5.12/nt/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/nt/Makefile'\"
else
echo shar: Extracting \"'unzip-5.12/nt/Makefile'\" \(2794 characters\)
sed "s/^X//" >'unzip-5.12/nt/Makefile' <<'END_OF_FILE'
X# NMAKE Makefile for Windows NT
X# D. Feinleib 7/92 t-da...@microsoft.com
X# H. Gessau 9/93 <hen...@kullmar.kullmar.se>
X#
X# Last revised: 10 Jul 94
X#
X# Tested with NT SDK, VC++ 1.0 for NT, and DEC C/C++ beta.
X#
X# For DEC C/C++, comment out the "cdebug = -Ogityb2" line (or
X# define debug?). [Jack Stansbury]
X
X# Nmake macros for building Windows NT applications
X# To build with debug info use 'nmake debug=1'
X!IFNDEF debug
XNODEBUG=1
X!ENDIF
X!include <ntwin32.mak>
X
X# object files
XOBJS1 = unzip.obj crypt.obj envargs.obj explode.obj extract.obj file_io.obj
XOBJS2 = inflate.obj match.obj unreduce.obj unshrink.obj zipinfo.obj nt.obj
XOBJS = $(OBJS1) $(OBJS2)
XOBJX1 = unzipsfx.obj crypt.obj extract_.obj file_io.obj inflate.obj match.obj
XOBJX2 = nt_.obj
XOBJX = $(OBJX1) $(OBJX2)
XOBJF = funzip.obj crypt_.obj inflate_.obj
X
X# cvars = $(cvars) -nologo -DMSDOS -DNO_ASM -J
Xcvars = $(cvars) -nologo -DNO_ASM -J
X
X# Some optimization (if not debugging)
X!IFDEF NODEBUG
Xcdebug = -Ogityb2
X!ENDIF
X
X# How to compile sources
X.c.obj:
X $(cc) $(cdebug) $(cflags) $(cvars) $<
X
X# How to link
X.obj.exe:
X $(link) $(ldebug) $(conflags) $(conlibs) $** -out:$@
X
X
X# Default target is all the executables
Xunzips : unzip.exe funzip.exe unzipsfx.exe
X
X
Xunzip.exe: $(OBJS)
Xunzipsfx.exe: $(OBJX)
Xfunzip.exe: $(OBJF)
X
Xcrypt.obj: crypt.c unzip.h zip.h crypt.h
Xenvargs.obj: envargs.c unzip.h
Xexplode.obj: explode.c unzip.h
Xextract.obj: extract.c unzip.h crypt.h
Xfile_io.obj: file_io.c unzip.h crypt.h tables.h
Xfunzip.obj: funzip.c unzip.h crypt.h tables.h
Xinflate.obj: inflate.c inflate.h unzip.h
Xmatch.obj: match.c unzip.h
Xunreduce.obj: unreduce.c unzip.h
Xunshrink.obj: unshrink.c unzip.h
Xunzip.obj: unzip.c unzip.h crypt.h version.h
Xzipinfo.obj: zipinfo.c unzip.h
X
Xnt.obj: nt\nt.c unzip.h
X $(cc) $(cdebug) $(cflags) $(cvars) -I. nt\nt.c
X
Xnt_.obj: nt\nt.c unzip.h # unzipsfx only
X copy nt\nt.c nt_.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DSFX nt_.c
X del nt_.c
X
Xcrypt_.obj: crypt.c unzip.h zip.h crypt.h # funzip only
X copy crypt.c crypt_.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DFUNZIP crypt_.c
X del crypt_.c
X
Xextract_.obj: extract.c unzip.h crypt.h # unzipsfx only
X copy extract.c extract_.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DSFX extract_.c
X del extract_.c
X
Xinflate_.obj: inflate.c inflate.h unzip.h crypt.h # funzip only
X copy inflate.c inflate_.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DFUNZIP inflate_.c
X del inflate_.c
X
Xunzipsfx.obj: unzip.c unzip.h crypt.h version.h # unzipsfx only
X copy unzip.c unzipsfx.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DSFX unzipsfx.c
X del unzipsfx.c
X
Xzipinfo_.obj: zipinfo.c unzip.h # unzipsfx only
X copy zipinfo.c zipinfo_.c
X $(cc) $(cdebug) $(cflags) $(cvars) -DSFX zipinfo_.c
X del zipinfo_.c
X
Xclean:
X del /q $(OBJS) unzip.exe $(OBJF) funzip.exe $(OBJX) unzipsfx.exe
END_OF_FILE
if test 2794 -ne `wc -c <'unzip-5.12/nt/Makefile'`; then
echo shar: \"'unzip-5.12/nt/Makefile'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/nt/Makefile'
fi
if test -f 'unzip-5.12/os2/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/os2/Contents'\" \(613 characters\)
sed "s/^X//" >'unzip-5.12/os2/Contents' <<'END_OF_FILE'
XContents of the "os2" sub-archive for UnZip 5.12 and later:


X
X Contents this file

X makefile.os2 makefile for almost every compiler available under OS/2
X os2.c OS/2-specific support routines
X unzip16.def OS/2 linker definition file (16-bit)
X unzip.def OS/2 linker definition file (32-bit)
X zipgrep.cmd really cool REXX script to search for strings in a zipfile
X wat_met.dif patch for Watcom C DOS/OS2-1.x versions and Metaware High C++
X
XThere is no support for the Zortech or GCC/2 (Michael Johnson/Colin
XJensen) compilers. emx+gcc is supported. New makefile targets are
Xwelcome...
END_OF_FILE
if test 613 -ne `wc -c <'unzip-5.12/os2/Contents'`; then
echo shar: \"'unzip-5.12/os2/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/Contents'
fi
if test -f 'unzip-5.12/os2/zipgrep.cmd' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/zipgrep.cmd'\"
else
echo shar: Extracting \"'unzip-5.12/os2/zipgrep.cmd'\" \(1601 characters\)
sed "s/^X//" >'unzip-5.12/os2/zipgrep.cmd' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X zipgrep.cmd (ye olde REXX procedure for OS/2)
X
X Script to search members of a zipfile for a string or regular expression
X and print the names of any such members (and, optionally, the matching
X text). The search is case-insensitive by default.
X
X History:
X original Bourne shell version by Jean-loup Gailly
X modified by Greg Roelofs for Ultrix (no egrep -i) and zipinfo -1
X OS/2 REXX script by Greg Roelofs
X
X Last modified: 19 Jul 93
X
X ---------------------------------------------------------------------------*/
X
XPARSE ARG string zipfile members
X
Xif (string == '') then do
X say 'usage: zipgrep search_string zipfile [members...]'
X say ' Displays the names of zipfile members containing a given string,'
X say ' in addition to the matching text. This procedure requires unzip'
X say ' and egrep in the current path, and it is quite slow....'
X exit 1
Xend
X
X/* doesn't seem to work...
Xnewq = RXQUEUE("Create",zipgrep_pipe)
Xoldq = RXQUEUE("Set",newq)
X */
X
X/* flush the queue before starting */
Xdo QUEUED()
X PULL junk
Xend
X
X/* GRR: can also add "2>&1" before pipe in following external command */
X'@unzip -Z1' zipfile members '| rxqueue'
X
Xdo while QUEUED() > 0
X PARSE PULL file
X '@unzip -p' zipfile file '| egrep -is' string
X if rc == 0 then do
X SAY file':'
X /* can comment out following line if just want filenames */
X '@unzip -p' zipfile file '| egrep -i' string
X end
Xend
X
X/*
Xcall RXQUEUE "Delete",newq
Xcall RXQUEUE "Set",oldq
X */
X
Xexit 0
END_OF_FILE
if test 1601 -ne `wc -c <'unzip-5.12/os2/zipgrep.cmd'`; then
echo shar: \"'unzip-5.12/os2/zipgrep.cmd'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/zipgrep.cmd'
fi
if test -f 'unzip-5.12/unix/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/unix/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/unix/Contents'\" \(640 characters\)
sed "s/^X//" >'unzip-5.12/unix/Contents' <<'END_OF_FILE'
XContents of the "unix" sub-archive for UnZip 5.11 and later:
X
X Contents this file
X Makefile makefile for UnZip for various architectures and OS's
X unix.c Unix-specific support routines
X unzip.1 UnZip manual page, nroff format
X unzipsfx.1 UnZipSFX manual page, nroff format
X zipinfo.1 ZipInfo manual page, nroff format
X funzip.1 fUnZip manual page, nroff format
X
XType "make" or "make help" to get general compile instructions (beyond
Xthose in the INSTALL file), or "make list" for a list of makefile targets.
XNote that there are some MS-DOS and cross-compilation targets thrown in
Xjust to make things more exciting.
END_OF_FILE
if test 640 -ne `wc -c <'unzip-5.12/unix/Contents'`; then
echo shar: \"'unzip-5.12/unix/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/unix/Contents'
fi
if test -f 'unzip-5.12/vms/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/vms/Contents'\" \(1682 characters\)
sed "s/^X//" >'unzip-5.12/vms/Contents' <<'END_OF_FILE'
XContents of the "vms" sub-archive for UnZip 5.12 and later:


X
X Contents this file

X README general VMS info about using UnZip and zipfiles
X unzip_def.rnh UnZip default help page, RUNOFF format
X unzip_cli.help UnZip VMSCLI help page, TPU format
X unzipsfx.hlp UnZipSFX pre-formatted help page
X cvthelp.tpu TPU macro file to convert .help file to RUNOFF format
X cmdline.c VMS-style command-line-interface code (if VMSCLI defined)
X unz_cld.cld more VMS-command-line stuff (if VMSCLI defined)
X vms.c VMS file manipulation code
X vms.h VMS header file for UnZip
X make.com command file to make UnZip with GNU or DEC C on VAX or AXP
X descrip.mms MMK/MMS makefile for UnZip/ZipInfo and UnZipSFX
X vmsshare.opt options file used by descrip.mms
X unzip.opt options file used by descrip.mms and make.com
X unzipsfx.opt options file used by descrip.mms and make.com
X clean.com command file to remove .obj and .exe files; used with MMS
X makesfx.com command file to create self-extracting archives
X
XMAKE/VMS is no longer supported since MMK (MMS clone by Matt Madison/MadGoat
XEnterprises, compatible with descrip.mms) is both free and becoming quite
Xpopular. MMK is available by anonymous ftp from ftp.spc.edu/ftp.wku.edu and
Xby mailserver at wkuvx1.wku.edu. Check VMS newsgroups for announcements and
Xexact location.
X
XThe MAKE.COM command file accepts compilation options in a LOCAL_UNZIP
Xsymbol or logical; the format is "VMSCLI,RETURN_SEVERITY" (for example).
XDESCRIP.MMS must be edited in order to use special options.
END_OF_FILE
if test 1682 -ne `wc -c <'unzip-5.12/vms/Contents'`; then
echo shar: \"'unzip-5.12/vms/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/Contents'
fi
if test -f 'unzip-5.12/vms/clean.com' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/clean.com'\"
else
echo shar: Extracting \"'unzip-5.12/vms/clean.com'\" \(803 characters\)
sed "s/^X//" >'unzip-5.12/vms/clean.com' <<'END_OF_FILE'
X$!
X$! Clean.com -- procedure to delete files. It always returns success
X$! status despite any error or warnings. Also it extracts
X$! filename from MMS "module=file" format.
X$!
X$ on control_y then goto ctly
X$ if p1.eqs."" then exit 1
X$ i = -1
X$scan_list:
X$ i = i+1
X$ item = f$elem(i,",",p1)
X$ if item.eqs."" then goto scan_list
X$ if item.eqs."," then goto done ! End of list
X$ item = f$edit(item,"trim") ! Clean of blanks
X$ wild = f$elem(1,"=",item)
X$ show sym wild
X$ if wild.eqs."=" then wild = f$elem(0,"=",item)
X$ vers = f$parse(wild,,,"version","syntax_only")
X$ if vers.eqs.";" then wild = wild - ";" + ";*"
X$scan:
X$ f = f$search(wild)
X$ if f.eqs."" then goto scan_list
X$ on error then goto err
X$ on warning then goto warn
X$ delete/log 'f'
X$warn:
X$err:
X$ goto scan
X$done:
X$ctly:
X$ exit 1
END_OF_FILE
if test 803 -ne `wc -c <'unzip-5.12/vms/clean.com'`; then
echo shar: \"'unzip-5.12/vms/clean.com'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/clean.com'
fi
if test -f 'unzip-5.12/vms/make.com' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/make.com'\"
else
echo shar: Extracting \"'unzip-5.12/vms/make.com'\" \(3756 characters\)
sed "s/^X//" >'unzip-5.12/vms/make.com' <<'END_OF_FILE'
X$ !
X$ ! "Makefile" for VMS versions of UnZip/ZipInfo and UnZipSFX
X$ !
X$ ! To define additional options, define the global symbol
X$ ! LOCAL_UNZIP prior to executing MAKE.COM:
X$ !
X$ ! $ LOCAL_UNZIP == "VMSCLI,RETURN_SEVERITY,"
X$ ! $ @MAKE
X$ !
X$ ! The trailing "," may be omitted. Valid VMS-specific options
X$ ! include VMSCLI, VMSWILD, RETURN_SEVERITY and RETURN_CODES; see
X$ ! the INSTALL file for other options (e.g., CHECK_EOF).
X$ !
X$ !
X$ ! Find out current disk, directory, compiler and options
X$ !
X$ my_name = f$env("procedure")
X$ here = f$parse(my_name,,,"device") + f$parse(my_name,,,"directory")
X$ if f$type(LOCAL_UNZIP).eqs.""
X$ then
X$ local_unzip = ""
X$ else ! Trim blanks and append comma if missing
X$ local_unzip = f$edit(local_unzip, "TRIM")
X$ if f$extract(f$length(local_unzip)-1, 1, local_unzip).nes."," then -
X local_unzip = local_unzip + ","
X$ endif
X$ axp = f$getsyi("HW_MODEL").ge.1024
X$ if axp
X$ then
X$ cc = "cc/standard=vaxc/ansi/nowarnings/include=[]"
X$ defs = "''local_unzip'MODERN"
X$ opts = ""
X$ else
X$ defs = "''local_unzip'VMS"
X$ opts = ",[.VMS]VMSSHARE.OPT/OPTIONS"
X$ if (f$search("SYS$SYSTEM:VAXC.EXE").eqs."" .and. -
X f$trnlnm("GNU_CC").nes."") .or. (p1.eqs."GCC")
X$ then
X$ cc = "gcc"
X$ opts = "''opts',GNU_CC:[000000]GCCLIB.OLB/LIB"
X$ else
X$ cc = "cc"
X$ endif
X$ endif
X$ def = "/define=(''defs')"
X$ old_ver = f$ver(1) ! Turn echo on to see what's happening
X$ on error then goto error
X$ on control_y then goto error
X$ !
X$ x = ""
X$ if f$search("SYS$LIBRARY:SYS$LIB_C.TLB").nes."" then -
X x = "+SYS$LIBRARY:SYS$LIB_C.TLB/LIBRARY"
X$ 'CC'/NOLIST'DEF' /OBJ=UNZIP.OBJ UNZIP.C
X$ 'CC'/NOLIST'DEF' /OBJ=CRYPT.OBJ CRYPT.C
X$ 'CC'/NOLIST'DEF' /OBJ=ENVARGS.OBJ ENVARGS.C
X$ 'CC'/NOLIST'DEF' /OBJ=EXPLODE.OBJ EXPLODE.C
X$ 'CC'/NOLIST'DEF' /OBJ=EXTRACT.OBJ EXTRACT.C
X$ 'CC'/NOLIST'DEF' /OBJ=FILE_IO.OBJ FILE_IO.C
X$ 'CC'/NOLIST'DEF' /OBJ=INFLATE.OBJ INFLATE.C
X$ 'CC'/NOLIST'DEF' /OBJ=MATCH.OBJ MATCH.C
X$ 'CC'/NOLIST'DEF' /OBJ=UNREDUCE.OBJ UNREDUCE.C
X$ 'CC'/NOLIST'DEF' /OBJ=UNSHRINK.OBJ UNSHRINK.C
X$ 'CC'/NOLIST'DEF' /OBJ=ZIPINFO.OBJ ZIPINFO.C
X$ 'CC'/INCLUDE=SYS$DISK:[]'DEF' /OBJ=[.VMS]VMS.OBJ; [.VMS]VMS.C'x'
X$ !
X$ local_unzip = f$edit(local_unzip,"UPCASE,TRIM")
X$ if f$locate("VMSCLI",local_unzip).ne.f$length(local_unzip)
X$ then
X$ 'CC'/INCLUDE=SYS$DISK:[]'DEF' /OBJ=[.VMS]CMDLINE.OBJ; [.VMS]CMDLINE.C'x'
X$ 'CC'/INCLUDE=SYS$DISK:[]/DEF=('DEFS',SFX) /OBJ=[.VMS]CMDLINE_.OBJ; -
X [.VMS]CMDLINE.C'x'
X$ set command/obj=[.vms]unz_cld.obj [.vms]unz_cld.cld
X$ cliobjs = ",[.vms]cmdline.obj, [.vms]unz_cld.obj"
X$ cliobjx = ",[.vms]cmdline_.obj, [.vms]unz_cld.obj"
X$ set default [.vms]
X$ edit/tpu/nosection/nodisplay/command=cvthelp.tpu unzip_cli.help
X$ set default [-]
X$ runoff/out=unzip.hlp [.vms]unzip_cli.rnh
X$ else
X$ cliobjs = ""
X$ cliobjx = ""
X$ runoff/out=unzip.hlp [.vms]unzip_def.rnh
X$ endif
X$ !
X$ LINK /NOTRACE/EXE=UNZIP.EXE unzip.obj;, crypt.obj;, envargs.obj;, -
X explode.obj;, extract.obj;, file_io.obj;, inflate.obj;, match.obj;, -
X unreduce.obj;, unshrink.obj;, zipinfo.obj;, [.VMS]vms.obj; -
X 'cliobjs' 'opts', [.VMS]unzip.opt/opt
X$ !
X$ 'CC'/DEF=('DEFS',SFX)/NOLIST /OBJ=UNZIPSFX.OBJ UNZIP.C
X$ 'CC'/DEF=('DEFS',SFX)/NOLIST /OBJ=EXTRACT_.OBJ EXTRACT.C
X$ 'CC'/DEF=('DEFS',SFX)/INCLUDE=SYS$DISK:[] /OBJ=[.VMS]VMS_.OBJ; [.VMS]VMS.C'x'
X$ LINK /NOTRACE/EXE=UNZIPSFX.EXE unzipsfx.obj;, crypt.obj;, extract_.obj;, -
X file_io.obj;, inflate.obj;, match.obj;, [.VMS]vms_.obj; -
X 'cliobjx' 'opts', [.VMS]unzipsfx.opt/opt
X$ !
X$ ! Next line: put similar lines (full pathname for unzip.exe) in
X$ ! login.com. Remember to include the leading "$" before disk name.
X$ !
X$! unzip == "$''here'unzip.exe" ! set up symbol to use unzip
X$! zipinfo == "$''here'unzip.exe ""-Z""" ! set up symbol to use zipinfo
X$ !
X$error:
X$ tmp = f$ver(old_ver)
X$ exit
END_OF_FILE
if test 3756 -ne `wc -c <'unzip-5.12/vms/make.com'`; then
echo shar: \"'unzip-5.12/vms/make.com'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/make.com'
fi
if test -f 'unzip-5.12/vms/unz_cld.cld' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unz_cld.cld'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unz_cld.cld'\" \(1711 characters\)
sed "s/^X//" >'unzip-5.12/vms/unz_cld.cld' <<'END_OF_FILE'
X Module VMS_UNZIP_CLD
X Ident "01-000"
X
XDefine Verb UNZIP
X Parameter P1, Label=ZIPFILE, Prompt="Zip file"
X Parameter P2, Label=INFILE, VALUE(LIST), Prompt="Files to UnZip"
X Qualifier TEXT, Negatable
X Qualifier AUTOTEXT, Negatable
X Qualifier SCREEN, Negatable
X Qualifier DIRECTORY, VALUE(REQUIRED,TYPE=$FILE), Nonnegatable
X Qualifier FRESHEN, Negatable
X Qualifier JUNK, Negatable
X Qualifier LIST, Nonnegatable
X Qualifier BRIEF, Nonnegatable, Default
X Qualifier FULL, Nonnegatable
X Qualifier OVERWRITE, Negatable
X Qualifier QUIET, Nonnegatable
X Qualifier SUPER_QUIET, Nonnegatable
X Qualifier TEST, Negatable
X Qualifier TYPE, Nonnegatable
X Qualifier PIPE, Nonnegatable
X Qualifier UPPERCASE, Negatable
X Qualifier UPDATE, Negatable
X Qualifier VERSION, Negatable
X Qualifier VERBOSE, Nonnegatable
X Qualifier RESTORE, Negatable
X Qualifier COMMENT, Negatable
X Qualifier EXCLUDE, VALUE(LIST), Nonnegatable
X Qualifier CASE_INSENSITIVE, Negatable
X Qualifier LOWERCASE, Negatable
X Qualifier YYZ, NonNegatable, Default
X Qualifier ZIPINFO, Syntax=INFORMATION, NonNegatable
X DisAllow BRIEF and FULL
X DisAllow DIRECTORY and SCREEN
X
XDefine Type COMMENTS_KEYWORDS
X Keyword ZIP_FILE, DEFAULT
X Keyword FILES
X
XDefine Syntax INFORMATION
X Parameter P1, Label=ZIPFILE, Prompt="Zip file"
X Parameter P2, Label=INFILE, VALUE(LIST), Prompt="Files to display"
X Qualifier ZIPINFO, NonNegatable, Default
X Qualifier SHORT, Nonnegatable
X Qualifier MEDIUM, Nonnegatable
X Qualifier LONG, Nonnegatable
X Qualifier VERBOSE, Nonnegatable
X Qualifier HEADER, Nonnegatable
X Qualifier COMMENT, Nonnegatable
X Qualifier TOTALS, Nonnegatable
X Qualifier TIMES, Nonnegatable
X Qualifier EXCLUDE, VALUE(LIST), Nonnegatable
X Qualifier ONE_LINE, Nonnegatable
END_OF_FILE
if test 1711 -ne `wc -c <'unzip-5.12/vms/unz_cld.cld'`; then
echo shar: \"'unzip-5.12/vms/unz_cld.cld'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unz_cld.cld'
fi
if test -f 'unzip-5.12/zip.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/zip.h'\"
else
echo shar: Extracting \"'unzip-5.12/zip.h'\" \(442 characters\)
sed "s/^X//" >'unzip-5.12/zip.h' <<'END_OF_FILE'
X/* This is a dummy zip.h to allow crypt.c from Zip to compile for UnZip */
X
X#ifndef __zip_h /* don't include more than once */
X#define __zip_h
X
X#include "unzip.h"
X
X#define decrypt_member decrypt /* for compatibility with zcrypt20 */
X#define local static
X#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))


X
X#ifdef FUNZIP
X extern ulg near crc_32_tab[];
X#else
X extern ulg *crc_32_tab;
X#endif
X

X#endif /* !__zip_h */
END_OF_FILE
if test 442 -ne `wc -c <'unzip-5.12/zip.h'`; then
echo shar: \"'unzip-5.12/zip.h'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/zip.h'
fi
echo shar: End of archive 19 \(of 20\).
cp /dev/null ark19isdone

Info-ZIP group

unread,
Sep 19, 1994, 12:17:17 AM9/19/94
to
Submitted-by: zip-...@wkuvx1.wku.edu (Info-ZIP group)
Posting-number: Volume 44, Issue 85
Archive-name: unzip/part20

Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
Supersedes: unzip50: Volume 31, Issue 104-117

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: unzip-5.12/atari/Contents unzip-5.12/crypt.c
# unzip-5.12/file_id.diz unzip-5.12/os2/unzip.def
# unzip-5.12/tops20/Contents unzip-5.12/tops20/rename.mic
# unzip-5.12/vms/unzip.opt unzip-5.12/vms/unzipsfx.opt
# unzip-5.12/vms/vmsshare.opt
# Wrapped by kent@sparky on Sat Sep 17 23:33:50 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 20 (of 20)."'
if test -f 'unzip-5.12/atari/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/atari/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/atari/Contents'\" \(260 characters\)
sed "s/^X//" >'unzip-5.12/atari/Contents' <<'END_OF_FILE'
XContents of the "atari" sub-archive for UnZip 5.1 and later:


X
X Contents this file

X README notes on compiling UnZip, from author of Atari port
X Makefile makefile for GNU C compiler and MiNT libraries
X atari.c Atari-specific routines
X
END_OF_FILE
if test 260 -ne `wc -c <'unzip-5.12/atari/Contents'`; then
echo shar: \"'unzip-5.12/atari/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/atari/Contents'
fi
if test -f 'unzip-5.12/crypt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/crypt.c'\"
else
echo shar: Extracting \"'unzip-5.12/crypt.c'\" \(395 characters\)
sed "s/^X//" >'unzip-5.12/crypt.c' <<'END_OF_FILE'
X/*
X crypt.c (dummy version) by Info-ZIP. Last revised: 6 Feb 94
X
X This is a non-functional version of Info-ZIP's crypt.c encryption/
X decryption code for Zip, ZipCloak, UnZip and fUnZip. This file is
X not copyrighted and may be distributed freely. :-) See the "Where"
X file for sites from which to obtain the full encryption/decryption


X sources (zcrypt21.zip or later).
X */

END_OF_FILE
if test 395 -ne `wc -c <'unzip-5.12/crypt.c'`; then
echo shar: \"'unzip-5.12/crypt.c'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/crypt.c'
fi
if test -f 'unzip-5.12/file_id.diz' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/file_id.diz'\"
else
echo shar: Extracting \"'unzip-5.12/file_id.diz'\" \(344 characters\)
sed "s/^X//" >'unzip-5.12/file_id.diz' <<'END_OF_FILE'
XInfo-ZIP's UnZip 5.12: generic C sources
X Complete C source code for Info-ZIP's
X PKUNZIP-compatible unarchiver, for all
X supported compilers and platforms (Unix,
X OS/2, MS-DOS, NT, VMS, Amiga, Atari, Mac,
X etc.), plus lots of cool documentation.
XThis is FREE (but copyrighted) software.
XSee COPYING for details on distribution
Xand reuse.
END_OF_FILE
if test 344 -ne `wc -c <'unzip-5.12/file_id.diz'`; then
echo shar: \"'unzip-5.12/file_id.diz'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/file_id.diz'
fi
if test -f 'unzip-5.12/os2/unzip.def' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/os2/unzip.def'\"
else
echo shar: Extracting \"'unzip-5.12/os2/unzip.def'\" \(114 characters\)
sed "s/^X//" >'unzip-5.12/os2/unzip.def' <<'END_OF_FILE'


XDESCRIPTION 'The world-famous Info-ZIP unarchiving utilities'

XSTACKSIZE 0x50000
XSEGMENTS
X _MSGSEG32 CLASS 'CODE'
END_OF_FILE
if test 114 -ne `wc -c <'unzip-5.12/os2/unzip.def'`; then
echo shar: \"'unzip-5.12/os2/unzip.def'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/os2/unzip.def'
fi
if test -f 'unzip-5.12/tops20/Contents' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/tops20/Contents'\"
else
echo shar: Extracting \"'unzip-5.12/tops20/Contents'\" \(281 characters\)
sed "s/^X//" >'unzip-5.12/tops20/Contents' <<'END_OF_FILE'
XContents of the "tops20" sub-archive for UnZip 5.1 and later:


X
X Contents this file

X make.mic command file to make UnZip and ZipInfo with KCC
X rename.mic command file to rename Info-ZIP filenames to KCC format
X tops20.c TOPS20-specific routines for UnZip
X
END_OF_FILE
if test 281 -ne `wc -c <'unzip-5.12/tops20/Contents'`; then
echo shar: \"'unzip-5.12/tops20/Contents'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/tops20/Contents'
fi
if test -f 'unzip-5.12/tops20/rename.mic' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/tops20/rename.mic'\"
else
echo shar: Extracting \"'unzip-5.12/tops20/rename.mic'\" \(224 characters\)
sed "s/^X//" >'unzip-5.12/tops20/rename.mic' <<'END_OF_FILE'
X@rename envargs.c envarg.c
X@rename explode.c explod.c
X@rename extract.c extrac.c
X@rename file_io.c fileio.c
X@rename inflate.c inflat.c
X@rename unreduce.c unredu.c
X@rename unshrink.c unshri.c
X@rename zipinfo.c zipinf.c
X@kmic
END_OF_FILE
if test 224 -ne `wc -c <'unzip-5.12/tops20/rename.mic'`; then
echo shar: \"'unzip-5.12/tops20/rename.mic'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/tops20/rename.mic'
fi
if test -f 'unzip-5.12/vms/unzip.opt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unzip.opt'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unzip.opt'\" \(21 characters\)
sed "s/^X//" >'unzip-5.12/vms/unzip.opt' <<'END_OF_FILE'
XIdent = "UnZip 5.12"
END_OF_FILE
if test 21 -ne `wc -c <'unzip-5.12/vms/unzip.opt'`; then
echo shar: \"'unzip-5.12/vms/unzip.opt'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unzip.opt'
fi
if test -f 'unzip-5.12/vms/unzipsfx.opt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/unzipsfx.opt'\"
else
echo shar: Extracting \"'unzip-5.12/vms/unzipsfx.opt'\" \(24 characters\)
sed "s/^X//" >'unzip-5.12/vms/unzipsfx.opt' <<'END_OF_FILE'
XIdent = "UnZipSFX 5.12"
END_OF_FILE
if test 24 -ne `wc -c <'unzip-5.12/vms/unzipsfx.opt'`; then
echo shar: \"'unzip-5.12/vms/unzipsfx.opt'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/unzipsfx.opt'
fi
if test -f 'unzip-5.12/vms/vmsshare.opt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unzip-5.12/vms/vmsshare.opt'\"
else
echo shar: Extracting \"'unzip-5.12/vms/vmsshare.opt'\" \(30 characters\)
sed "s/^X//" >'unzip-5.12/vms/vmsshare.opt' <<'END_OF_FILE'
Xsys$library:vaxcrtl.exe/share
END_OF_FILE
if test 30 -ne `wc -c <'unzip-5.12/vms/vmsshare.opt'`; then
echo shar: \"'unzip-5.12/vms/vmsshare.opt'\" unpacked with wrong size!
fi
# end of 'unzip-5.12/vms/vmsshare.opt'
fi
echo shar: End of archive 20 \(of 20\).
cp /dev/null ark20isdone

0 new messages