home *** CD-ROM | disk | FTP | other *** search
- From: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
- Newsgroups: comp.sources.misc
- Subject: v44i071: unzip - Info-ZIP portable UnZip, version 5.12, Part06/20
- Date: 18 Sep 1994 23:14:56 -0500
- Organization: Sterling Software
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <35j380$qn8@sparky.sterling.com>
- X-Md4-Signature: 949d3d4c8937c422284df2c765b0012c
-
- Submitted-by: zip-bugs@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 <goathunter@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
- 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...
-