home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-23 | 58.3 KB | 1,540 lines |
- Newsgroups: comp.sources.misc
- Path: sparky!kent
- From: zip-bugs@cs.ucla.edu (Info-ZIP group)
- Subject: v31i105: unzip50 - Info-ZIP portable UnZip, version 5.0, Part02/14
- Message-ID: <1992Aug24.025225.24144@sparky.imd.sterling.com>
- Followup-To: comp.sources.d
- X-Md4-Signature: 67455a16af9b9121c5ef733b92dfe9e3
- Sender: kent@sparky.imd.sterling.com (Kent Landfield)
- Organization: Sterling Software
- References: <csm-v31i104=unzip50.215137@sparky.IMD.Sterling.COM>
- Date: Mon, 24 Aug 1992 02:52:25 GMT
- Approved: kent@sparky.imd.sterling.com
- Lines: 1525
-
- Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
- Posting-number: Volume 31, Issue 105
- Archive-name: unzip50/part02
- Supersedes: unzip: Volume 29, Issue 31-42
- Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT AMIGA?, !ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun
-
- #! /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".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: MAC/aztec.make.UU extract.c mapname.c
- # Wrapped by kent@sparky on Sun Aug 23 21:09:31 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 14)."'
- if test -f 'MAC/aztec.make.UU' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MAC/aztec.make.UU'\"
- else
- echo shar: Extracting \"'MAC/aztec.make.UU'\" \(1805 characters\)
- sed "s/^X//" >'MAC/aztec.make.UU' <<'END_OF_FILE'
- Xbegin 666 MAC/aztec.make
- XM(R @(%1H:7,@35!7(&UA:V5F:6QE(&ES(&1E<VEG;F5D('1O(&)E('5S960@
- XM=&\@8V]M<&EL92!A;B!-4%<@=F5R<VEO;@HC(" @;V8@=6YZ:7 @=7-I;F<@
- XM=&AE($%Z=&5C($,@8V]M<&EL97(L('9E<G-I;VX@-2XR82X@4VEM<&QY(')E
- XM;F%M90HC(" @=&AI<R!F:6QE(&%S('5N>FEP+FUA:V4@86YD(&1O(&%N($U0
- XM5R!B=6EL9"X*"@HC(" @1FEL93H@(" @(" @=6YZ:7 N;6%K90HC(" @5&%R
- XM9V5T.B @(" @56YZ:7 *(R @(%-O=7)C97,Z(" @('5N>FEP+F,*(R @(" @
- XM(" @(" @(" @(&-R>7!T+F,*(R @(" @(" @(" @(" @(&5N=F%R9W,N8PHC
- XM(" @(" @(" @(" @(" @97AP;&]D92YC"B,@(" @(" @(" @(" @("!E>'1R
- XM86-T+F,*(R @(" @(" @(" @(" @(&9I;&5?:6\N8PHC(" @(" @(" @(" @
- XM(" @:6YF;&%T92YC"B,@(" @(" @(" @(" @("!M86-F:6QE+F,*(R @(" @
- XM(" @(" @(" @(&UA8W-T870N8PHC(" @(" @(" @(" @(" @;6%P;F%M92YC
- XM"B,@(" @(" @(" @(" @("!M871C:"YC"B,@(" @(" @(" @(" @("!M:7-C
- XM+F,*(R @(" @(" @(" @(" @('5N<F5D=6-E+F,*(R @(" @(" @(" @(" @
- XM('5N<VAR:6YK+F,*(R @($-R96%T960Z(" @(%1U97-D87DL($UA>2 U+" Q
- XM.3DR(#<Z,#4Z,# @4$T*"@I#1DQ!1U,@/2 M9"!-4%<@(R M9"!#4EE05 H*
- XM3$9,04=3(#T@+6T*"@HN;R#$("YC('5N>FEP+F@@=6YZ:7 N;6%K90H@(" @
- XM(" @($,@>T-&3$%'4WT@+6\@>T1E9F%U;'1]+F\@>T1E9F%U;'1]+F,*"BYO
- XM(,0@+F%S;0H@(" @(" @(&%S("UO('M$969A=6QT?2YO('M$969A=6QT?2YA
- XM<VT*"D]"2D5#5%,@/2"V"B @(" @(" @=6YZ:7 N;R"V"B,@(" @(" @8W)Y
- XM<'0N;R"V"B @(" @(" @96YV87)G<RYO(+8*(" @(" @("!E>'!L;V1E+F\@
- XMM@H@(" @(" @(&5X=')A8W0N;R"V"B @(" @(" @9FEL95]I;RYO(+8*(" @
- XM(" @("!I;F9L871E+F\@M@H@(" @(" @(&UA8V9I;&4N;R"V"B @(" @(" @
- XM;6%C<W1A="YO(+8*(" @(" @("!M87!N86UE+F\@M@H@(" @(" @(&UA=&-H
- XM+F\@M@H@(" @(" @(&UI<V,N;R"V"B @(" @(" @=6YR961U8V4N;R"V"B @
- XM(" @(" @=6YS:')I;FLN;PH*56YZ:7 @Q"C"B @(" @(" @9&5R97H@=6YZ
- X9:7 N=&AI;FMC+G)S<F,@/B!U;GII<"YR"G)C
- X
- Xend
- END_OF_FILE
- if test 1805 -ne `wc -c <'MAC/aztec.make.UU'`; then
- echo shar: \"'MAC/aztec.make.UU'\" unpacked with wrong size!
- else
- echo shar: Uudecoding \"'MAC/aztec.make'\" \(1285 characters\)
- cat MAC/aztec.make.UU | uudecode
- if test 1285 -ne `wc -c <'MAC/aztec.make'`; then
- echo shar: \"'MAC/aztec.make'\" uudecoded with wrong size!
- else
- rm MAC/aztec.make.UU
- fi
- fi
- # end of 'MAC/aztec.make.UU'
- fi
- if test -f 'extract.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'extract.c'\"
- else
- echo shar: Extracting \"'extract.c'\" \(37529 characters\)
- sed "s/^X//" >'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 inflate.c, unimplod.c, unreduce.c and unshrink.c.
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X#include "unzip.h"
- X#ifdef MSWIN
- X# include "wizunzip.h"
- X# include "replace.h"
- X#endif /* MSWIN */
- X
- X
- X/************************************/
- X/* Extract Local Prototypes, etc. */
- X/************************************/
- X
- Xstatic int store_info __((void));
- Xstatic int extract_or_test_member __((void));
- X#ifdef CRYPT
- X static int decrypt_member __((void));
- X static int testp __((byte *hdr));
- X#endif
- X
- Xstatic byte *mem_i_buffer;
- Xstatic byte *mem_o_buffer;
- Xstatic ULONG mem_i_size, mem_i_offset;
- Xstatic ULONG mem_o_size, mem_o_offset;
- X
- Xstatic char *VersionMsg =
- X " skipping: %-22s need %s compat. v%u.%u (can do v%u.%u)\n";
- Xstatic char *ComprMsg =
- X " skipping: %-22s compression method %d\n";
- Xstatic char *FilNamMsg =
- X "%s: bad filename length (%s)\n";
- Xstatic char *ExtFieldMsg =
- X "%s: bad extra field length (%s)\n";
- Xstatic char *OffsetMsg =
- X "file #%d: bad zipfile offset (%s)\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 char **fnamev;
- X byte *cd_inptr;
- X int cd_incnt, error, error_in_archive=0;
- X int renamed, query, len, filnum=(-1), blknum=0;
- X#ifdef OS2
- X extern int longname; /* from os2unzip.c */
- X#endif
- X UWORD i, j, members_remaining, num_skipped=0, num_bad_pwd=0;
- X longint cd_bufstart, bufstart, inbuf_offset, request;
- X 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 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 pInfo = info;
- X members_remaining = ecrec.total_entries_central_dir;
- X
- X while (members_remaining) {
- X j = 0;
- X
- X /*
- X * Loop through files in central directory, storing offsets, file
- X * attributes, and case-conversion flags until block 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 = 51; /* 51: unexpected 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, CentSigMsg, j); /* sig not found */
- X fprintf(stderr, ReportMsg); /* check binary transfers */
- X error_in_archive = 3; /* 3: error in zipfile */
- 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()) != 0) {
- X error_in_archive = error; /* only 51 (EOF) defined */
- X members_remaining = 0; /* ...so no more left to do */
- X break;
- X }
- X if ((error = do_string(crec.filename_length, FILENAME)) != 0) {
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) { /* fatal: no more left to do */
- X fprintf(stderr, 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 > 1) { /* fatal */
- X fprintf(stderr, ExtFieldMsg, filename, "central");
- X members_remaining = 0;
- X break;
- X }
- X }
- X if ((error = do_string(crec.file_comment_length, SKIP)) != 0) {
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) { /* fatal */
- X fprintf(stderr, "\n%s: bad file comment length\n",
- X filename);
- X members_remaining = 0;
- X break;
- X }
- X }
- X if (process_all_files) {
- X if (store_info())
- X ++num_skipped;
- X else
- X ++j; /* file is OK: save info[] and continue with next */
- X } else {
- X fnamev = fnv; /* don't destroy permanent filename pointer */
- X for (--fnamev; *++fnamev;)
- X if (match(filename, *fnamev)) {
- X if (store_info())
- X ++num_skipped;
- X else
- X ++j; /* file is OK */
- X break; /* found match for filename, so stop looping */
- X } /* end if (match), for-loop (fnamev) */
- X } /* end if (process_all_files) */
- 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 if (request < 0) {
- X fprintf(stderr, SeekMsg, ReportMsg);
- X error_in_archive = 3; /* 3: severe error in zipfile, */
- X continue; /* but can still go on */
- X } else if (bufstart != cur_zipfile_bufstart) {
- X cur_zipfile_bufstart = lseek(zipfd, bufstart, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) <= 0) {
- X fprintf(stderr, OffsetMsg, filnum, "lseek");
- X error_in_archive = 3; /* 3: error in zipfile, but */
- 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, OffsetMsg, filnum, "EOF");
- X error_in_archive = 3; /* 3: error in zipfile */
- X continue; /* but can still try next one */
- X }
- X if (strncmp(sig, local_hdr_sig, 4)) {
- X fprintf(stderr, OffsetMsg, filnum,
- X "can't find local header sig"); /* bad offset */
- X error_in_archive = 3;
- X continue;
- X }
- X if ((error = process_local_file_hdr()) != 0) {
- X fprintf(stderr, "\nfile #%d: bad local header\n", filnum);
- X error_in_archive = error; /* only 51 (EOF) defined */
- X continue; /* can still try next one */
- X }
- X if ((error = do_string(lrec.filename_length, FILENAME)) != 0) {
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) {
- X fprintf(stderr, FilNamMsg, filename, "local");
- X continue; /* go on to next one */
- X }
- X }
- X if (extra_field != (byte *)NULL)
- X free(extra_field);
- X extra_field = (byte *)NULL;
- X if ((error = do_string(lrec.extra_field_length, EXTRA_FIELD)) != 0)
- X {
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) {
- X fprintf(stderr, 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#ifdef OS2
- X longname = FALSE; /* no long name has yet been stored */
- X#endif
- 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(!fflag || renamed)) > 1) { /* skip */
- X if ((error > 2) && (error_in_archive < 2))
- X error_in_archive = 2; /* (weak) error in zipfile */
- 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/*#ifndef VMS*/ /* VMS creates higher version number instead of overwriting
- X * (will have to modify for VMS-style names with specific
- X * version numbers: just check V_flag? don't use stat?) */
- 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; /* sorry for a goto */
- 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,
- X "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ",
- X filename);
- X FFLUSH /* for Amiga and Mac MPW */
- X fgets(answerbuf, 9, stdin);
- 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, "new name: ");
- X FFLUSH /* for AMIGA and Mac MPW */
- 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, "error: invalid response [%c]\n",
- X *answerbuf); /* warn the user */
- X goto reprompt; /* why not another goto? */
- X } /* end switch (*answerbuf) */
- X#endif /* ?MSWIN */
- X } /* end if (query) */
- X/*#endif*/ /* !VMS */
- X } /* end if (extracting to disk) */
- X
- X#ifdef CRYPT
- X if (pInfo->encrypted && ((error = decrypt_member()) != 0)) {
- X if (error == 10) {
- X if (error > error_in_archive)
- X error_in_archive = error;
- X fprintf(stderr,
- X " skipping: %-22s unable to get password\n", filename);
- X } else { /* (error == 1) */
- X fprintf(stderr,
- X " skipping: %-22s incorrect password\n", 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()) != 0) {
- X if (error > error_in_archive)
- X error_in_archive = error; /* ...and keep going */
- X if (disk_full > 1)
- X return error_in_archive; /* (unless disk full) */
- 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, 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 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 readbuf(sig, 4);
- X if (strncmp(sig, end_central_sig, 4)) { /* just to make sure again */
- X fprintf(stderr, EndSigMsg); /* didn't find end-of-central-dir sig */
- X fprintf(stderr, ReportMsg); /* check binary transfers */
- X if (!error_in_archive) /* don't overwrite stronger error */
- X error_in_archive = 1; /* 1: warning error */
- X }
- X if (tflag && (quietflg == 1)) {
- X int num=filnum+1 - num_bad_pwd;
- X
- X if (error_in_archive)
- X printf("At least one error was detected in %s.\n", zipfn);
- X else if (num == 0)
- X printf("Caution: zero files tested in %s.\n", zipfn);
- X else if (process_all_files && (num_skipped+num_bad_pwd == 0))
- X printf("No errors detected in %s.\n", zipfn);
- X else
- X printf("No errors detected in %s for the %d file%s tested.\n",
- X zipfn, num, (num==1)? "":"s");
- X if (num_skipped > 0)
- X printf("%d file%s skipped because of unsupported compression or\
- X encoding.\n",
- X num_skipped, (num_skipped==1)? "":"s");
- X#ifdef CRYPT
- X if (num_bad_pwd > 0)
- X printf("%d file%s skipped because of incorrect password.\n",
- X num_bad_pwd, (num_bad_pwd==1)? "":"s");
- X#endif /* CRYPT */
- X }
- X if ((num_skipped > 0) && !error_in_archive) /* files not tested or */
- X error_in_archive = 1; /* extracted: warning */
- X#ifdef CRYPT
- X if ((num_bad_pwd > 0) && !error_in_archive) /* files not tested or */
- X error_in_archive = 1; /* extracted: warning */
- 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 store_info() */
- X/***************************/
- X
- Xstatic int store_info() /* return 1 if skipping, 0 if OK */
- X{
- X ULONG tmp;
- X
- X#define UNKN_COMPR \
- X (crec.compression_method>IMPLODED && crec.compression_method!=DEFLATED)
- X#if 0 /* old */
- X# define UNKN_COMPR (crec.compression_method>IMPLODED)
- X#endif
- X
- 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 */
- X pInfo->text = crec.internal_file_attributes & 1; /* bit field */
- X pInfo->crc = crec.crc32;
- X pInfo->compr_size = crec.compressed_size;
- X
- X if (crec.version_needed_to_extract[1] == VMS_) {
- X if (crec.version_needed_to_extract[0] > VMS_VERSION) {
- X fprintf(stderr, VersionMsg, filename, "VMS",
- X crec.version_needed_to_extract[0] / 10,
- X crec.version_needed_to_extract[0] % 10,
- X VMS_VERSION / 10, VMS_VERSION % 10);
- X return 1;
- 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,
- X "\n%s: stored in VMS format. Extract anyway? (y/n) ",
- X filename);
- X FFLUSH /* for Amiga and Mac MPW */
- X fgets(answerbuf, 9, stdin);
- X if ((*answerbuf != 'y') && (*answerbuf != 'Y'))
- X return 1;
- 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 fprintf(stderr, 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 1;
- X }
- X
- X if UNKN_COMPR {
- X fprintf(stderr, ComprMsg, filename, crec.compression_method);
- X return 1;
- X }
- X#ifndef CRYPT
- X if (pInfo->encrypted) {
- X fprintf(stderr, " skipping: %-22s encrypted (not supported)\n",
- X filename);
- X return 1;
- X }
- X#endif /* !CRYPT */
- X
- X/*---------------------------------------------------------------------------
- X Store some central-directory information (encryption, file attributes,
- X offsets) for later use.
- X ---------------------------------------------------------------------------*/
- X
- X tmp = crec.external_file_attributes;
- X
- X pInfo->dos_attr = 32; /* set archive bit: file is not backed up */
- X switch (pInfo->hostnum) {
- X case UNIX_:
- X case VMS_:
- X pInfo->unix_attr = (unsigned) (tmp >> 16);
- X break;
- X case DOS_OS2_FAT_:
- X case OS2_HPFS_:
- X pInfo->dos_attr = (unsigned) tmp;
- X tmp = (!(tmp & 1)) << 1; /* read-only bit */
- X pInfo->unix_attr = (unsigned) (0444 | (tmp<<6) | (tmp<<3) | tmp);
- X#ifdef UNIX
- X umask( (int)(tmp=umask(0)) );
- X pInfo->unix_attr &= ~tmp;
- X#endif
- X break;
- X case MAC_:
- X pInfo->unix_attr = (unsigned) (tmp & 1); /* read-only bit */
- X break;
- X default:
- X pInfo->unix_attr = 0666;
- X break;
- X } /* end switch (host-OS-created-by) */
- X
- X pInfo->offset = (longint) crec.relative_offset_local_header;
- X return 0;
- 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#ifdef S_IFLNK
- X int symlnk=FALSE;
- X#endif /* S_IFLNK */
- X int error=0;
- X UWORD b;
- X
- X
- X
- X/*---------------------------------------------------------------------------
- X Initialize variables, buffers, etc.
- X ---------------------------------------------------------------------------*/
- X
- X bits_left = 0;
- X bitbuf = 0L;
- X outpos = 0L;
- X outcnt = 0;
- X outptr = outbuf;
- X zipeof = 0;
- X crc32val = 0xFFFFFFFFL;
- X
- X#ifdef S_IFLNK
- X if ((pInfo->unix_attr & S_IFMT) == S_IFLNK && (pInfo->hostnum == UNIX_)
- X && !tflag && !cflag)
- X symlnk = TRUE;
- X#endif /* S_IFLNK */
- X
- X memset(outbuf, 0xaa, OUTBUFSIZ);
- X#if (!defined(DOS_OS2) || defined(MSWIN))
- X if (aflag) /* if we have a scratchpad, clear it out */
- X#ifdef MSWIN
- X _fmemset(outout, 0xaa, OUTBUFSIZ);
- X#else /* !MSWIN */
- X memset(outout, 0xaa, OUTBUFSIZ);
- X#endif /* ?MSWIN */
- X#endif /* !DOS_OS2 || MSWIN */
- X
- X if (tflag) {
- X if (!quietflg) {
- X fprintf(stdout, " Testing: %-22s ", filename);
- X fflush(stdout);
- X }
- X } else {
- X if (cflag) { /* output to stdout (copy of it) */
- X#if (defined(MACOS) || defined(AMIGA))
- X outfd = 1;
- X#else /* !(MACOS || AMIGA) */
- X outfd = dup(1); /* GRR: change this to #define for Mac/Amiga */
- X#endif /* ?(MACOS || AMIGA) */
- X#ifdef DOS_OS2
- X if (!aflag)
- X setmode(outfd, O_BINARY);
- X#endif /* DOS_OS2 */
- X#ifdef VMS
- X if (create_output_file()) /* VMS version required for stdout! */
- X return 50; /* 50: disk full (?) */
- X#endif
- X } else
- X#ifdef S_IFLNK
- X if (!symlnk) /* symlink() takes care of file creation */
- X#endif /* !S_IFLNK */
- X {
- X if (create_output_file())
- X return 50; /* 50: disk full (?) */
- X }
- X } /* endif (!tflag) */
- X
- X/*---------------------------------------------------------------------------
- X Unpack the file.
- X ---------------------------------------------------------------------------*/
- X
- X switch (lrec.compression_method) {
- X
- X case STORED:
- X if (!tflag && (quietflg < 2)) {
- X fprintf(stdout, " Extracting: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X }
- X#ifdef S_IFLNK
- X /*
- X * If file came from Unix and is a symbolic link and we are extracting
- X * to disk, allocate a storage area, put the data in it, and create the
- X * link. Since we know it's a symbolic link to start with, shouldn't
- X * have to worry about overflowing unsigned ints with unsigned longs.
- X * (This doesn't do anything for compressed symlinks, but that can be
- X * added later...it also doesn't set the time or permissions of the
- X * link, but does anyone really care?)
- X */
- X if (symlnk) {
- X#if (defined(MTS) || defined(MACOS))
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X#else /* !(MTS || MACOS) */
- X char *orig = (char *)malloc((unsigned)lrec.uncompressed_size+1);
- X char *p = orig;
- X
- X while (ReadByte(&b))
- X *p++ = b;
- X *p = 0; /* terminate string */
- X UpdateCRC((unsigned char *)orig, p-orig);
- X if (symlink(orig, filename))
- X if ((errno == EEXIST) && overwrite_all) { /* OK to overwrite */
- X unlink(filename);
- X if (symlink(orig, filename))
- X perror("symlink error");
- X } else
- X perror("symlink error");
- X free(orig);
- X#endif /* ?(MTS || MACOS) */
- X } else
- X#endif /* S_IFLNK */
- X while (ReadByte(&b) && !disk_full)
- X OUTB(b)
- X break;
- X
- X case SHRUNK:
- X if (!tflag && (quietflg < 2)) {
- X fprintf(stdout, "UnShrinking: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X }
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) {
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X }
- X#endif /* S_IFLNK */
- X unShrink();
- X break;
- X
- X case REDUCED1:
- X case REDUCED2:
- X case REDUCED3:
- X case REDUCED4:
- X if (!tflag && (quietflg < 2)) {
- X fprintf(stdout, " Expanding: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X }
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) {
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X }
- X#endif /* S_IFLNK */
- X unReduce();
- X break;
- X
- X case IMPLODED:
- X if (!tflag && (quietflg < 2)) {
- X fprintf(stdout, " Exploding: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X }
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) {
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X }
- X#endif /* S_IFLNK */
- X explode(); /* ignore return code for now */
- X break;
- X
- X case DEFLATED:
- X if (!tflag && (quietflg < 2)) {
- X fprintf(stdout, " Inflating: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X }
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) {
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X }
- X#endif /* S_IFLNK */
- X inflate();
- X break;
- X
- X default: /* should never get to this point */
- X fprintf(stderr, "%s: unknown compression method\n", filename);
- X /* close and delete file before return? */
- X return 1; /* 1: warning error */
- X
- X } /* end switch (compression method) */
- X
- X if (disk_full) { /* set by FlushOutput()/OUTB() macro */
- X if (disk_full > 1)
- X return 50; /* 50: disk full */
- X error = 1; /* 1: warning error */
- X }
- X
- X/*---------------------------------------------------------------------------
- X Write the last partial buffer, if any; set the file date and time; and
- X close the file (not necessarily in that order). Then make sure CRC came
- X out OK and print result.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef S_IFLNK
- X if (!symlnk) {
- X#endif /* S_IFLNK */
- X if (!disk_full && FlushOutput())
- X if (disk_full > 1)
- X return 50; /* 50: disk full */
- X else { /* disk_full == 1 */
- X fprintf(stderr, "%s: probably corrupt\n", filename);
- X error = 1; /* 1: warning error */
- X }
- X
- X if (!tflag)
- X#ifdef VMS
- X CloseOutputFile();
- X#else /* !VMS */
- X#ifdef MTS /* MTS can't set file time */
- X close(outfd);
- X#else /* !MTS */
- X set_file_time_and_close();
- X#endif /* ?MTS */
- X#endif /* ?VMS */
- X
- X#ifdef S_IFLNK
- X } /* endif (!symlnk) */
- X#endif /* S_IFLNK */
- X
- X /* logical-AND crc32val for 64-bit machines */
- X if ((crc32val = ((~crc32val) & 0xFFFFFFFFL)) != lrec.crc32) {
- X /* if quietflg is set, we haven't output the filename yet: do it */
- X if (quietflg)
- X printf("%-22s: ", filename);
- X fprintf(stdout, " Bad CRC %08lx (should be %08lx)\n", crc32val,
- X lrec.crc32);
- X error = 1; /* 1: warning error */
- X } else if (tflag) {
- X if (!quietflg)
- X fprintf(stdout, " OK\n");
- X } else {
- X if ((quietflg < 2) && !error)
- X fprintf(stdout, "\n");
- X }
- X
- X return error;
- X
- X} /* end function extract_or_test_member() */
- X
- X
- X
- X
- X
- X#ifdef CRYPT
- X
- X/*******************************/
- X/* Function decrypt_member() */
- X/*******************************/
- X
- Xstatic int decrypt_member() /* return 10 if out of memory or can't get */
- X{ /* tty; 1 if password bad; 0 if password OK */
- X UWORD b;
- X int n, r;
- X static int nopwd=FALSE;
- X char *m, *prompt;
- X byte h[12];
- X
- X
- X /* get header once */
- X for (n = 0; n < 12; n++) {
- X ReadByte(&b);
- X h[n] = (byte) b;
- X }
- X
- X /* if have key already, test it; else allocate memory for it */
- X if (key) {
- X if (!testp(h))
- X return 0; /* existing password OK (else prompt for new) */
- X else if (nopwd)
- X return 1; /* user indicated no more prompting */
- X } else if ((key = (char *)malloc(PWLEN+1)) == (char *)NULL)
- X return 10;
- X
- X if ((prompt = (char *)malloc(FILNAMSIZ+15)) != (char *)NULL) {
- X sprintf(prompt, "%s password: ", filename);
- X m = prompt;
- X } else
- X m = "Enter password: ";
- X
- X /* try a few keys */
- X for (r = 0; r < 3; ++r) {
- X m = getp(m, key, PWLEN+1);
- X if (prompt != (char *)NULL) {
- X free(prompt);
- X prompt = (char *)NULL;
- X }
- X if (m == (char *)NULL)
- X return 10;
- X if (!testp(h))
- X return 0;
- X if (*key == '\0') {
- X nopwd = TRUE;
- X return 1;
- X }
- X m = "password incorrect--reenter: ";
- X }
- X return 1;
- X}
- X
- X
- X
- X
- X
- X/**********************/
- X/* Function testp() */
- X/**********************/
- X
- Xstatic int testp(h) /* return -1 if bad password; 0 if OK */
- X byte *h;
- X{
- X UWORD b, c;
- X int n, t;
- X byte *p;
- X
- X /* set keys */
- X init_keys(key);
- X
- X /* check password */
- X for (n = 0; n < 11; n++)
- X c = DECRYPT(h[n]);
- X b = DECRYPT(h[11]);
- X
- X#ifdef CRYPT_DEBUG
- X printf(" lrec.crc = %08lx crec.crc = %08lx pInfo->ExtLocHdr = %s\n",
- X lrec.crc32, pInfo->crc, pInfo->ExtLocHdr? "true":"false");
- X printf(" incnt = %d unzip offset into zipfile = %ld\n", incnt,
- X cur_zipfile_bufstart+(inptr-inbuf));
- X printf(" (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
- X (UWORD)(c | (b<<8)), (UWORD)(lrec.crc32 >> 16), lrec.last_mod_file_time);
- X#endif /* CRYPT_DEBUG */
- X
- X /* same test as in zipbare() in crypt.c: */
- X if ((UWORD)(c | (b<<8)) != (pInfo->ExtLocHdr? lrec.last_mod_file_time :
- X (UWORD)(lrec.crc32 >> 16)))
- X return -1; /* bad */
- X
- X /* password OK: decrypt current buffer contents before leaving */
- X for (n = (longint)incnt > csize ? (int)csize : incnt, p = inptr; n--; p++)
- X *p = (byte) DECRYPT(*p);
- X return 0; /* OK */
- X
- X} /* end function testp() */
- X
- X#endif /* CRYPT */
- X
- X
- X
- X
- X
- X/*******************************/
- X/* Function ReadMemoryByte() */
- X/*******************************/
- X
- Xint ReadMemoryByte(x) /* return PK-type error code */
- X UWORD *x;
- X{
- X if (mem_i_offset < mem_i_size) {
- X *x = (UWORD) mem_i_buffer[mem_i_offset++];
- X return 8;
- X } else
- X return 0;
- X}
- X
- X
- X
- X
- X
- X/****************************/
- X/* Function FlushMemory() */
- X/****************************/
- X
- Xint FlushMemory() /* return PK-type error code */
- X{
- X if (outcnt == 0)
- X return 0;
- X
- X if (mem_o_offset + outcnt <= mem_o_size) {
- X memcpy((char *)(mem_o_buffer+mem_o_offset), (char *)outbuf, outcnt);
- X mem_o_offset += outcnt;
- X return 0;
- X } else
- X return 50;
- X}
- X
- X
- X
- X
- X
- X/***************************/
- X/* Function memextract() */ /* extract compressed extra field block */
- X/***************************/
- X
- Xint memextract(tgt, tgtsize, src, srcsize) /* return 0 if success, 1 if not */
- X byte *tgt, *src;
- X ULONG tgtsize, srcsize;
- X{
- X UWORD method, error = 0;
- X ULONG crc, oldcrc;
- X
- X method = makeword(src);
- X crc = makelong(src+2);
- X
- X mem_i_buffer = src + 2 + 4; /* method and crc */
- X mem_i_size = srcsize - 2 - 4;
- X mem_i_offset = 0;
- X
- X mem_o_buffer = tgt;
- X mem_o_size = tgtsize;
- X mem_o_offset = 0;
- X
- X mem_mode = 1;
- X
- X bits_left = 0;
- X bitbuf = 0L;
- X outpos = 0L;
- X outcnt = 0;
- X outptr = outbuf;
- X zipeof = 0;
- X
- X switch (method) {
- X case STORED:
- X memcpy(tgt, src + 2 + 4, (extent) (srcsize - 2 - 4));
- X break;
- X case DEFLATED:
- X inflate();
- X FlushOutput();
- X break;
- X default:
- X fprintf(stderr,
- X "warning: unsupported extra field compression type--skipping\n");
- X error = 1; /* GRR: this should be passed on up via SetEAs() */
- X break;
- X }
- X
- X mem_mode = 0;
- X
- X if (!error) {
- X oldcrc = crc32val;
- X crc32val = 0xFFFFFFFFL;
- X UpdateCRC((unsigned char *) mem_o_buffer, (int) mem_o_size);
- X crc32val = (~crc32val) & 0xFFFFFFFFL;
- X
- X if (crc32val != crc) {
- X printf("(Bad extra field CRC %08lx, should be %08lx)\n", crc32val,
- X crc);
- X error = 1;
- X }
- X crc32val = oldcrc; /* grrr ... this ugly kludge should be fixed */
- X }
- X
- X return error;
- X}
- END_OF_FILE
- if test 37529 -ne `wc -c <'extract.c'`; then
- echo shar: \"'extract.c'\" unpacked with wrong size!
- fi
- # end of 'extract.c'
- fi
- if test -f 'mapname.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mapname.c'\"
- else
- echo shar: Extracting \"'mapname.c'\" \(15624 characters\)
- sed "s/^X//" >'mapname.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X mapname.c
- X
- X This routine changes DEC-20, VAX/VMS, and DOS-style filenames into normal
- X Unix names (and vice versa, in some cases); it also creates any necessary
- X directories, if the -d switch was specified.
- X
- X ---------------------------------------------------------------------------
- X
- X Notes:
- X
- X - This routine REALLY needs to be rewritten (different routines for
- X each output OS, with different rules for different parts of the path
- X name). If each zip program stores local-format names (like the VMS
- X one did at one time), it would probably be best to convert to an in-
- X termediate format first (assuming we're not extracting under the same
- X OS as that under which the zipfile was created), then from that to
- X the current operating system's format.
- X - The strcpy and strcat operations on both cdp and filename may over-
- X write memory, since they don't check lengths. With a kilobyte in
- X which to work, this is probably not that big a deal, but it could
- X cause problems eventually.
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X#include "unzip.h"
- X
- X
- X/*******************/
- X/* Mapname Defines */
- X/*******************/
- X
- X#ifdef VMS
- X# define PERMS 0
- X#else
- X# define PERMS 0777
- X#endif
- X
- X#ifndef NO_MKDIR
- X# if (defined(DOS_OS2) && !defined(__GO32__))
- X# if (_MSC_VER >= 600) /* have special MSC mkdir prototype */
- X# include <direct.h>
- X# else /* own prototype because dir.h conflicts? */
- X int mkdir(const char *path);
- X# endif /* ?(MSC 6.0 or later) */
- X# define MKDIR(path,mode) mkdir(path)
- X# else /* !DOS_OS2 || __GO32__ */
- X# ifdef MACOS
- X# define MKDIR(path,mode) macmkdir(path,gnVRefNum,glDirID)
- X# else /* !MACOS */
- X# define MKDIR(path,mode) mkdir(path,mode)
- X# endif /* ?MACOS */
- X# endif /* ?(DOS_OS2 && !__GO32__) */
- X#endif /* !NO_MKDIR */
- X
- X
- X
- X
- X/************************/
- X/* Function mapname() */
- X/************************/
- X
- Xint mapname(create_dirs) /* return 0 if no error, 1 if caution (filename */
- X int create_dirs; /* truncated), 2 if warning (skip file because */
- X{ /* dir doesn't exist), 3 if error (skip file) */
- X#ifdef NO_MKDIR
- X char command[FILNAMSIZ+40]; /* buffer for system() call */
- X#endif
- X#ifdef VMS
- X int stat_val; /* temp. holder for stat() return value */
- X char *dp, *xp; /* pointers to directory name */
- X char *np; /* pointer into filename */
- X#endif /* VMS */
- X#ifdef DOS_VMS
- X char *last_dot=NULL; /* last dot not converted to underscore */
- X#endif /* DOS_VMS */
- X#ifdef OS2
- X char *last;
- X extern char longfilename[]; /* AFTER file created and closed */
- X extern int longname; /* used also in file_io.c: set EAs */
- X int longdir;
- X#endif /* OS2 */
- X char name[FILNAMSIZ]; /* file name buffer */
- X char *pp, *cp, *cdp; /* character pointers */
- X char delim = '\0'; /* directory delimiter */
- X int quote = FALSE; /* flags */
- X int indir = FALSE;
- X int done = FALSE;
- X int created = FALSE;
- X register unsigned workch; /* hold the character being tested */
- X
- X
- X/*---------------------------------------------------------------------------
- X Initialize various pointers and counters and stuff.
- X ---------------------------------------------------------------------------*/
- X
- X#ifdef MAP_DEBUG
- X fprintf(stderr, "%s ", filename); /* echo name of this file */
- X#endif
- X cdp = (char *)NULL;
- X pp = name; /* point to translation buffer */
- X *name = '\0'; /* initialize buffer */
- X if (!jflag) { /* -j => junk pathnames */
- X cdp = (char *)malloc(strlen(filename) + 3); /* place for holding */
- X if (cdp == (char *)NULL) { /* directory name */
- X fprintf(stderr, "mapname: out of memory [%s]\n", filename);
- X return 3;
- X }
- X#ifdef VMS
- X *cdp++ = '[';
- X xp = cdp; /* always points to last non-NULL char */
- X *cdp++ = '.';
- X#endif /* VMS */
- X#ifdef MACOS
- X *cdp = ':'; /* the Mac uses ':' as a directory separator */
- X cdp[1] = '\0';
- X#else /* !MACOS */
- X *cdp = '\0';
- X#endif /* ?MACOS */
- X }
- X
- X/*---------------------------------------------------------------------------
- X Begin main loop through characters in filename.
- X ---------------------------------------------------------------------------*/
- X
- X for (cp = filename; (workch = (unsigned char) *cp++) != 0 && !done;) {
- X
- X if (quote) { /* if char quoted, */
- X *pp++ = (char) workch; /* include it literally */
- X quote = FALSE;
- X } else if (indir) { /* if in directory name, */
- X if (workch == (unsigned)delim) /* look for end delimiter */
- X indir = FALSE;
- X } else
- X switch (workch) {
- X case '<': /* discard DEC-20 directory name */
- X indir = TRUE;
- X delim = '>';
- X break;
- X case '[': /* discard VMS directory name */
- X indir = TRUE;
- X delim = ']';
- X break;
- X case '/': /* discard Unix path name */
- X case '\\': /* or MS-DOS path name... */
- X /* iff -j flag was given */
- X /*
- X * Special processing case: if -j flag was not specified on
- X * command line and create_dirs is TRUE, create any necessary
- X * directories included in the pathname. Creation of dirs is
- X * straightforward on BSD and MS-DOS machines but requires use
- X * of the system() command on SysV systems (or any others which
- X * don't have mkdir()). The stat() check is necessary with
- X * MSC because it doesn't have an EEXIST errno, and it saves
- X * the overhead of multiple system() calls on SysV machines.
- X */
- X
- X if (!jflag) {
- X *pp = '\0';
- X#ifdef VMS
- X dp = name;
- X while (*++xp = *dp++); /* copy name to cdp */
- X last_dot = NULL; /* dir name: no dots allowed */
- X strcpy(xp, ".dir"); /* add extension for stat check */
- X stat_val = stat(cdp, &statbuf);
- X *xp = '\0'; /* remove extension for all else */
- X if (stat_val) { /* doesn't exist, so create */
- X#else /* !VMS */
- X#ifdef MSDOS
- X if (last_dot != NULL) { /* one dot in dir name is legal */
- X *last_dot = '.';
- X last_dot = NULL;
- X }
- X#endif /* MSDOS */
- X strcat(cdp, name);
- X#ifdef OS2
- X if ((longdir = !IsFileNameValid(cdp)) != 0) {
- X last = strrchr(cdp, '/');
- X strcpy(longfilename, last ? last + 1 : cdp);
- X fprintf(stderr, "renaming directory \"%s\"", cdp);
- X ChangeNameForFAT(cdp);
- X fprintf(stderr, " to \"%s\"\n", cdp);
- X }
- X#endif /* OS2 */
- X if (stat(cdp, &statbuf)) { /* doesn't exist, so create */
- X#endif /* ?VMS */
- X if (!create_dirs) /* told not to create (freshening) */
- X return 2;
- X#ifdef NO_MKDIR
- X sprintf(command,
- X "IFS=\" \t\n\" /bin/mkdir %s 2>/dev/null", cdp);
- X if (system(command)) {
- X#else /* !NO_MKDIR */
- X if (MKDIR(cdp, PERMS) == -1) {
- X#endif /* ?NO_MKDIR */
- X perror(cdp);
- X free(cdp);
- X fprintf(stderr, "mapame: unable to process [%s]\n",
- X filename);
- X return 3;
- X }
- X created = TRUE;
- X#ifdef OS2
- X if (longdir)
- X SetLongNameEA(cdp, longfilename);
- X#endif /* OS2 */
- X } else if (!(statbuf.st_mode & S_IFDIR)) {
- X fprintf(stderr,
- X "mapname: %s exists but is not a directory\n", cdp);
- X free(cdp);
- X fprintf(stderr, "mapame: unable to process [%s]\n",
- X filename);
- X return 3;
- X }
- X#ifdef VMS
- X *xp = '/'; /* for now... (mkdir()) */
- X#else /* !VMS */
- X#ifdef MACOS
- X strcat(cdp, ":");
- X#else /* !MACOS */
- X strcat(cdp, "/");
- X#endif /* ?MACOS */
- X#endif /* ?VMS */
- X }
- X pp = name;
- X break;
- X case ':':
- X#ifdef UNIX /* colon is a valid character in Unix */
- X *pp++ = workch; /* filenames, so keep it; anywhere else, */
- X#else /* !UNIX */ /* change it to an underscore (should */
- X *pp++ = '_'; /* NOT have stored drive/node names!!) */
- X#endif /* ?UNIX */
- X /* pp = name; (OLD) discard DEC dev: or node:: name */
- X break;
- X case '.': /* DEC-20 generation number or */
- X#ifdef DOS_VMS /* MS-DOS or VMS separator */
- X last_dot = pp; /* point at last dot so far... */
- X *pp++ = '_'; /* convert dot to underscore */
- X#else /* !DOS_VMS */
- X *pp++ = workch;
- X#endif /* ?DOS_VMS */
- X break;
- X case ';': /* VMS generation or DEC-20 attrib */
- X#ifdef MACOS
- X if (V_flag || macflag)
- X#else /* !MACOS */
- X if (V_flag) /* if requested, save VMS ";##" */
- X#endif /* ?MACOS */ /* version info or Macintosh */
- X *pp++ = (char) workch; /* (?) info; otherwise discard */
- X else /* everything starting with */
- X done = TRUE; /* semicolon. (Worry about */
- X break; /* DEC-20 later.) */
- X case '\026': /* control-V quote for special chars */
- X quote = TRUE; /* set flag for next character */
- X break;
- X case ' ':
- X#if (defined(VMS) || defined(MTS))
- X *pp++ = '_'; /* change spaces to underscore */
- X#else /* !(VMS || MTS) */ /* under VMS and MTS, and under DOS */
- X#ifdef DOS_OS2 /* and OS/2 if -s not specified. */
- X if (!sflag)
- X *pp++ = '_';
- X else
- X#endif /* DOS_OS2 */
- X *pp++ = (char) workch; /* otherwise, leave as spaces */
- X#endif /* ?(VMS || MTS) */
- X break;
- X default:
- X#ifdef MACOS
- X if ((macflag && ((unsigned)workch > 0x1F)) || isprint(workch))
- X#else /* !MACOS */
- X#if (defined(DOS_OS2) || (defined(UNIX) && !defined(VMS))) /* allow non-US */
- X if (isprint(workch) || (128 <= workch && workch <= 254))
- X#else /* !(DOS_OS2 || UNIX) */
- X if (isprint(workch)) /* other printable, just keep */
- X#endif /* ?(DOS_OS2 || UNIX) */
- X#endif /* ?MACOS */
- X *pp++ = (char) workch;
- X } /* end switch */
- X } /* end for loop */
- X *pp = '\0'; /* done with name: terminate it */
- X#ifdef DOS_VMS /* and put a dot back in if VMS */
- X if (last_dot != NULL) /* or MS-DOS */
- X *last_dot = '.';
- X#endif /* DOS_VMS */
- X
- X/*---------------------------------------------------------------------------
- X We COULD check for existing names right now, create a "unique" name, etc.
- X At present, we do this in extract_or_test_files() (immediately after we
- X return from here). If conversion went bad, the name'll either be nulled
- X out (in which case we'll return non-0), or following procedures won't be
- X able to create the extracted file and other error msgs will result.
- X ---------------------------------------------------------------------------*/
- X
- X if (filename[strlen(filename) - 1] == '/') {
- X /* A directory was extracted. It had a trailing /,
- X * don't report the error below. */
- X if (created) {
- X printf(" Creating: %s", filename);
- X#ifdef OS2
- X SetPathInfo(filename, lrec.last_mod_file_date,
- X lrec.last_mod_file_time, -1);
- X if (extra_field)
- X SetEAs(filename, extra_field);
- X#endif
- X printf("\n");
- X }
- X return 2; /* but skip file */
- X }
- X
- X if (*name == '\0') {
- X fprintf(stderr, "mapname: conversion of [%s] failed\n", filename);
- X return 3;
- X }
- X
- X#ifdef OS2
- X if (!longname && ((longname = !IsFileNameValid(name)) != 0)) {
- X /* in case of second call after user renamed the file, skip this */
- X last = strrchr(name, '/'); /* THIS time, save for file_io */
- X last = last ? last + 1 : name; /* only last component */
- X strcpy(longfilename, last);
- X fprintf(stderr, "renaming \"%s\"", name);
- X ChangeNameForFAT(last);
- X fprintf(stderr, " to \"%s\"\n", name);
- X }
- X#endif /* OS2 */
- X
- X#ifdef VMS
- X /* convert filename to legal VMS one, substituting underscores for
- X * all invalid characters */
- X for (np = name; *np; ++np)
- X if (!(isdigit(*np) || isalpha(*np) || (*np == '$') ||
- X (*np == '-') || (*np == '_') || (*np == '.') || (*np == ';')))
- X *np = '_';
- X#endif /* VMS */
- X
- X if (!jflag) {
- X#ifdef VMS
- X *xp++ = ']'; /* proper end-of-dir-name delimiter */
- X if (xp == cdp) { /* no path-name stuff, so... */
- X strcpy(filename, name); /* copy file name into global */
- X cdp -= 2; /* prepare to free malloc'd space */
- X } else { /* we've added path-name stuff... */
- X *xp = '\0'; /* so terminate and convert to */
- X dp = cdp; /* VMS subdir separators (skip */
- X while (*++dp) /* first char: better not be */
- X if (*dp == '/') /* "/"): change all slashes */
- X *dp = '.'; /* to dots */
- X cdp -= 2; /* include leading bracket and dot */
- X strcpy(filename, cdp); /* copy VMS-style path name into global */
- X strcat(filename, name); /* concatenate file name to global */
- X }
- X#else /* !VMS */
- X strcpy(filename, cdp); /* either "" or slash-terminated path */
- X strcat(filename, name); /* append file name to path name */
- X#endif /* ?VMS */
- X free(cdp);
- X } else
- X strcpy(filename, name); /* copy converted name into global */
- X
- X#if PATH_MAX < (FILNAMSIZ - 1)
- X /* check the length of the file name and truncate if necessary */
- X if (PATH_MAX < strlen(filename)) {
- X fprintf(stderr, "caution: truncating filename\n");
- X filename[PATH_MAX] = '\0';
- X fprintf(stderr, "[ %s ]\n", filename);
- X return 1; /* 1: warning error */
- X }
- X#endif
- X
- X return 0;
- X}
- END_OF_FILE
- if test 15624 -ne `wc -c <'mapname.c'`; then
- echo shar: \"'mapname.c'\" unpacked with wrong size!
- fi
- # end of 'mapname.c'
- fi
- echo shar: End of archive 2 \(of 14\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 14 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...
-