home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume44
/
unzip
/
part12
< prev
next >
Wrap
Internet Message Format
|
1994-09-19
|
72KB
From: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
Newsgroups: comp.sources.misc
Subject: v44i077: unzip - Info-ZIP portable UnZip, version 5.12, Part12/20
Date: 18 Sep 1994 23:16:01 -0500
Organization: Sterling Software
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-ID: <35j3a1$qpg@sparky.sterling.com>
X-Md4-Signature: 84e6e974cc4c02fa0169d55b28be519c
Submitted-by: zip-bugs@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 (cherborth@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 (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 /* 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 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#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/* 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 *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/* 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 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; /* 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
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 /* 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
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...