home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!elroy.jpl.nasa.gov!ames!network.ucsd.edu!mvb.saic.com!vmsnet-sources
- From: goathunter@wkuvx1.bitnet
- Newsgroups: vmsnet.sources
- Subject: Zip v1.9 & UnZip v5.0, part 02/22
- Message-ID: <8009582@MVB.SAIC.COM>
- Date: Tue, 01 Sep 1992 22:48:37 GMT
- Organization: Western Kentucky University, Bowling Green, KY
- Lines: 1377
- Approved: Mark.Berryman@Mvb.Saic.Com
-
- Submitted-by: goathunter@wkuvx1.bitnet
- Posting-number: Volume 3, Issue 124
- Archive-name: zip_unzip/part02
-
- -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
- X else /* do it slow to avoid memcpy() overlap */
- X#endif /* !NOMEMCPY */
- X do `7B
- X slide`5Bw++`5D = slide`5Bd++`5D;
- X `7D while (--e);
- X if (w == WSIZE)
- X `7B
- X flush(w);
- X w = u = 0;
- X `7D
- X `7D while (n);
- X `7D
- X `7D
- X
- X /* flush out slide */
- X flush(w);
- X return csize ? 5 : 0; /* should have read csize bytes */
- X`7D
- X
- X
- X
- Xint explode_nolit8(tl, td, bl, bd)
- Xstruct huft *tl, *td; /* length and distance decoder tables */
- Xint bl, bd; /* number of bits decoded by tl`5B`5D and td`5B`5D *
- V/
- X/* Decompress the imploded data using uncoded literals and an 8K sliding
- X window. */
- X`7B
- X longint s; /* bytes to decompress */
- X register unsigned e; /* table entry flag/number of extra bits */
- X unsigned n, d; /* length and index for copy */
- X unsigned w; /* current window position */
- X struct huft *t; /* pointer to table entry */
- X unsigned ml, md; /* masks for bl and bd bits */
- X register ULONG b; /* bit buffer */
- X register unsigned k; /* number of bits in bit buffer */
- X unsigned u; /* true if unflushed */
- X
- X
- X /* explode the coded data */
- X b = k = w = 0; /* initialize bit buffer, window */
- X u = 1; /* buffer unflushed */
- X ml = mask_bits`5Bbl`5D; /* precompute masks for speed */
- X md = mask_bits`5Bbd`5D;
- X s = ucsize;
- X while (s > 0) /* do until ucsize bytes uncompressed */
- X `7B
- X NEEDBITS(1)
- X if (b & 1) /* then literal--get eight bits */
- X `7B
- X DUMPBITS(1)
- X s--;
- X NEEDBITS(8)
- X slide`5Bw++`5D = (byte)b;
- X if (w == WSIZE)
- X `7B
- X flush(w);
- X w = u = 0;
- X `7D
- X DUMPBITS(8)
- X `7D
- X else /* else distance/length */
- X `7B
- X DUMPBITS(1)
- X NEEDBITS(7) /* get distance low bits */
- X d = (unsigned)b & 0x7f;
- X DUMPBITS(7)
- X NEEDBITS((unsigned)bd) /* get coded distance high bits */
- X if ((e = (t = td + ((`7E(unsigned)b) & md))->e) > 16)
- X do `7B
- X if (e == 99)
- X return 1;
- X DUMPBITS(t->b)
- X e -= 16;
- X NEEDBITS(e)
- X `7D while ((e = (t = t->v.t + ((`7E(unsigned)b) & mask_bits`5Be`5D))
- V->e) > 16);
- X DUMPBITS(t->b)
- X d = w - d - t->v.n; /* construct offset */
- X NEEDBITS((unsigned)bl) /* get coded length */
- X if ((e = (t = tl + ((`7E(unsigned)b) & ml))->e) > 16)
- X do `7B
- X if (e == 99)
- X return 1;
- X DUMPBITS(t->b)
- X e -= 16;
- X NEEDBITS(e)
- X `7D while ((e = (t = t->v.t + ((`7E(unsigned)b) & mask_bits`5Be`5D))
- V->e) > 16);
- X DUMPBITS(t->b)
- X n = t->v.n;
- X if (e) /* get length extra bits */
- X `7B
- X NEEDBITS(8)
- X n += (unsigned)b & 0xff;
- X DUMPBITS(8)
- X `7D
- X
- X /* do the copy */
- X s -= n;
- X do `7B
- X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
- X if (u && w <= d)
- X `7B
- X memset(slide + w, 0, e);
- X w += e;
- X d += e;
- X `7D
- X else
- X#ifndef NOMEMCPY
- X if (w - d >= e) /* (this test assumes unsigned comparison) *
- V/
- X `7B
- X memcpy(slide + w, slide + d, e);
- X w += e;
- X d += e;
- X `7D
- X else /* do it slow to avoid memcpy() overlap */
- X#endif /* !NOMEMCPY */
- X do `7B
- X slide`5Bw++`5D = slide`5Bd++`5D;
- X `7D while (--e);
- X if (w == WSIZE)
- X `7B
- X flush(w);
- X w = u = 0;
- X `7D
- X `7D while (n);
- X `7D
- X `7D
- X
- X /* flush out slide */
- X flush(w);
- X return csize ? 5 : 0; /* should have read csize bytes */
- X`7D
- X
- X
- X
- Xint explode_nolit4(tl, td, bl, bd)
- Xstruct huft *tl, *td; /* length and distance decoder tables */
- Xint bl, bd; /* number of bits decoded by tl`5B`5D and td`5B`5D *
- V/
- X/* Decompress the imploded data using uncoded literals and a 4K sliding
- X window. */
- X`7B
- X longint s; /* bytes to decompress */
- X register unsigned e; /* table entry flag/number of extra bits */
- X unsigned n, d; /* length and index for copy */
- X unsigned w; /* current window position */
- X struct huft *t; /* pointer to table entry */
- X unsigned ml, md; /* masks for bl and bd bits */
- X register ULONG b; /* bit buffer */
- X register unsigned k; /* number of bits in bit buffer */
- X unsigned u; /* true if unflushed */
- X
- X
- X /* explode the coded data */
- X b = k = w = 0; /* initialize bit buffer, window */
- X u = 1; /* buffer unflushed */
- X ml = mask_bits`5Bbl`5D; /* precompute masks for speed */
- X md = mask_bits`5Bbd`5D;
- X s = ucsize;
- X while (s > 0) /* do until ucsize bytes uncompressed */
- X `7B
- X NEEDBITS(1)
- X if (b & 1) /* then literal--get eight bits */
- X `7B
- X DUMPBITS(1)
- X s--;
- X NEEDBITS(8)
- X slide`5Bw++`5D = (byte)b;
- X if (w == WSIZE)
- X `7B
- X flush(w);
- X w = u = 0;
- X `7D
- X DUMPBITS(8)
- X `7D
- X else /* else distance/length */
- X `7B
- X DUMPBITS(1)
- X NEEDBITS(6) /* get distance low bits */
- X d = (unsigned)b & 0x3f;
- X DUMPBITS(6)
- X NEEDBITS((unsigned)bd) /* get coded distance high bits */
- X if ((e = (t = td + ((`7E(unsigned)b) & md))->e) > 16)
- X do `7B
- X if (e == 99)
- X return 1;
- X DUMPBITS(t->b)
- X e -= 16;
- X NEEDBITS(e)
- X `7D while ((e = (t = t->v.t + ((`7E(unsigned)b) & mask_bits`5Be`5D))
- V->e) > 16);
- X DUMPBITS(t->b)
- X d = w - d - t->v.n; /* construct offset */
- X NEEDBITS((unsigned)bl) /* get coded length */
- X if ((e = (t = tl + ((`7E(unsigned)b) & ml))->e) > 16)
- X do `7B
- X if (e == 99)
- X return 1;
- X DUMPBITS(t->b)
- X e -= 16;
- X NEEDBITS(e)
- X `7D while ((e = (t = t->v.t + ((`7E(unsigned)b) & mask_bits`5Be`5D))
- V->e) > 16);
- X DUMPBITS(t->b)
- X n = t->v.n;
- X if (e) /* get length extra bits */
- X `7B
- X NEEDBITS(8)
- X n += (unsigned)b & 0xff;
- X DUMPBITS(8)
- X `7D
- X
- X /* do the copy */
- X s -= n;
- X do `7B
- X n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
- X if (u && w <= d)
- X `7B
- X memset(slide + w, 0, e);
- X w += e;
- X d += e;
- X `7D
- X else
- X#ifndef NOMEMCPY
- X if (w - d >= e) /* (this test assumes unsigned comparison) *
- V/
- X `7B
- X memcpy(slide + w, slide + d, e);
- X w += e;
- X d += e;
- X `7D
- X else /* do it slow to avoid memcpy() overlap */
- X#endif /* !NOMEMCPY */
- X do `7B
- X slide`5Bw++`5D = slide`5Bd++`5D;
- X `7D while (--e);
- X if (w == WSIZE)
- X `7B
- X flush(w);
- X w = u = 0;
- X `7D
- X `7D while (n);
- X `7D
- X `7D
- X
- X /* flush out slide */
- X flush(w);
- X return csize ? 5 : 0; /* should have read csize bytes */
- X`7D
- X
- X
- X
- Xint explode()
- X/* Explode an imploded compressed stream. Based on the general purpose
- X bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding
- X window. Construct the literal (if any), length, and distance codes and
- X the tables needed to decode them (using huft_build() from inflate.c),
- X and call the appropriate routine for the type of data in the remainder
- X of the stream. The four routines are nearly identical, differing only
- X in whether the literal is decoded or simply read in, and in how many
- X bits are read in, uncoded, for the low distance bits. */
- X`7B
- X unsigned r; /* return codes */
- X struct huft *tb; /* literal code table */
- X struct huft *tl; /* length code table */
- X struct huft *td; /* distance code table */
- X int bb; /* bits for tb */
- X int bl; /* bits for tl */
- X int bd; /* bits for td */
- X unsigned l`5B256`5D; /* bit lengths for codes */
- X
- X
- X /* Tune base table sizes. Note: I thought that to truly optimize speed,
- X I would have to select different bl, bd, and bb values for different
- X compressed file sizes. I was suprised to find out the the values of
- X 7, 7, and 9 worked best over a very wide range of sizes, except that
- X bd = 8 worked marginally better for large compressed sizes. */
- X bl = 7;
- X bd = csize > 200000L ? 8 : 7;
- X
- X
- X /* With literal tree--minimum match length is 3 */
- X hufts = 0; /* initialze huft's malloc'ed */
- X if (lrec.general_purpose_bit_flag & 4)
- X `7B
- X bb = 9; /* base table size for literals */
- X if ((r = get_tree(l, 256)) != 0)
- X return r;
- X if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(tb);
- X return r;
- X `7D
- X if ((r = get_tree(l, 64)) != 0)
- X return r;
- X if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(tl);
- X huft_free(tb);
- X return r;
- X `7D
- X if ((r = get_tree(l, 64)) != 0)
- X return r;
- X if (lrec.general_purpose_bit_flag & 2) /* true if 8K */
- X `7B
- X if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(td);
- X huft_free(tl);
- X huft_free(tb);
- X return r;
- X `7D
- X r = explode_lit8(tb, tl, td, bb, bl, bd);
- X `7D
- X else /* else 4K */
- X `7B
- X if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(td);
- X huft_free(tl);
- X huft_free(tb);
- X return r;
- X `7D
- X r = explode_lit4(tb, tl, td, bb, bl, bd);
- X `7D
- X huft_free(td);
- X huft_free(tl);
- X huft_free(tb);
- X `7D
- X else
- X
- X
- X /* No literal tree--minimum match length is 2 */
- X `7B
- X if ((r = get_tree(l, 64)) != 0)
- X return r;
- X if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(tl);
- X return r;
- X `7D
- X if ((r = get_tree(l, 64)) != 0)
- X return r;
- X if (lrec.general_purpose_bit_flag & 2) /* true if 8K */
- X `7B
- X if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(td);
- X huft_free(tl);
- X return r;
- X `7D
- X r = explode_nolit8(tl, td, bl, bd);
- X `7D
- X else /* else 4K */
- X `7B
- X if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
- X `7B
- X if (r == 1)
- X huft_free(td);
- X huft_free(tl);
- X return r;
- X `7D
- X r = explode_nolit4(tl, td, bl, bd);
- X `7D
- X huft_free(td);
- X huft_free(tl);
- X `7D
- X#ifdef DEBUG
- X fprintf(stderr, "<%u > ", hufts);
- X#endif /* DEBUG */
- X return r;
- X`7D
- $ CALL UNPACK [.UNZIP50]EXPLODE.C;1 811679058
- $ create 'f'
- X/*--------------------------------------------------------------------------
- V-
- 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 file
- Vs
- X inflate.c, unimplod.c, unreduce.c and unshrink.c.
- X
- X --------------------------------------------------------------------------
- V-*/
- 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`7B
- 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`5BDIR_BLKSIZ`5D;
- X
- X
- X/*--------------------------------------------------------------------------
- V-
- 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
- V-
- 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 --------------------------------------------------------------------------
- V-*/
- X
- X pInfo = info;
- X members_remaining = ecrec.total_entries_central_dir;
- X
- X while (members_remaining) `7B
- 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
- V.
- X */
- X
- X while (members_remaining && (j < DIR_BLKSIZ)) `7B
- X --members_remaining;
- X pInfo = &info`5Bj`5D;
- X
- X if (readbuf(sig, 4) <= 0) `7B
- X error_in_archive = 51; /* 51: unexpected EOF */
- X members_remaining = 0; /* ...so no more left to do */
- X break;
- X `7D
- X if (strncmp(sig, central_hdr_sig, 4)) `7B /* just to make sure
- V */
- 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 `7D
- X /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
- X if ((error = process_cdir_file_hdr()) != 0) `7B
- X error_in_archive = error; /* only 51 (EOF) defined */
- X members_remaining = 0; /* ...so no more left to do */
- X break;
- X `7D
- X if ((error = do_string(crec.filename_length, FILENAME)) != 0) `7
- VB
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) `7B /* fatal: no more left to do */
- X fprintf(stderr, FilNamMsg, filename, "central");
- X members_remaining = 0;
- X break;
- X `7D
- X `7D
- X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) !=
- V 0)
- X `7B
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) `7B /* fatal */
- X fprintf(stderr, ExtFieldMsg, filename, "central");
- X members_remaining = 0;
- X break;
- X `7D
- X `7D
- X if ((error = do_string(crec.file_comment_length, SKIP)) != 0) `7
- VB
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) `7B /* fatal */
- X fprintf(stderr, "\n%s: bad file comment length\n",
- X filename);
- X members_remaining = 0;
- X break;
- X `7D
- X `7D
- X if (process_all_files) `7B
- X if (store_info())
- X ++num_skipped;
- X else
- X ++j; /* file is OK: save info`5B`5D and continue with n
- Vext */
- X `7D else `7B
- X fnamev = fnv; /* don't destroy permanent filename pointer
- V */
- X for (--fnamev; *++fnamev;)
- X if (match(filename, *fnamev)) `7B
- X if (store_info())
- X ++num_skipped;
- X else
- X ++j; /* file is OK */
- X break; /* found match for filename, so stop looping
- V */
- X `7D /* end if (match), for-loop (fnamev) */
- X `7D /* end if (process_all_files) */
- X
- X `7D /* 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 /*----------------------------------------------------------------------
- V-
- X Second loop: process files in current block, extracting or testing
- X each one.
- X ----------------------------------------------------------------------
- V-*/
- X
- X for (i = 0; i < j; ++i) `7B
- X filnum = i + blknum*DIR_BLKSIZ;
- X pInfo = &info`5Bi`5D;
- 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
- V-
- 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) `7B
- X fprintf(stderr, SeekMsg, ReportMsg);
- X error_in_archive = 3; /* 3: severe error in zipfile,
- V */
- X continue; /* but can still go on */
- X `7D else if (bufstart != cur_zipfile_bufstart) `7B
- X cur_zipfile_bufstart = lseek(zipfd, bufstart, SEEK_SET);
- X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) <= 0) `7B
- X fprintf(stderr, OffsetMsg, filnum, "lseek");
- X error_in_archive = 3; /* 3: error in zipfile, but */
- X continue; /* can still do next file */
- X `7D
- X inptr = inbuf + (int)inbuf_offset;
- X incnt -= (int)inbuf_offset;
- X `7D else `7B
- X incnt += (inptr-inbuf) - (int)inbuf_offset;
- X inptr = inbuf + (int)inbuf_offset;
- X `7D
- X
- X /* should be in proper position now, so check for sig */
- X if (readbuf(sig, 4) <= 0) `7B /* 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 `7D
- X if (strncmp(sig, local_hdr_sig, 4)) `7B
- X fprintf(stderr, OffsetMsg, filnum,
- X "can't find local header sig"); /* bad offset */
- X error_in_archive = 3;
- X continue;
- X `7D
- X if ((error = process_local_file_hdr()) != 0) `7B
- 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 `7D
- X if ((error = do_string(lrec.filename_length, FILENAME)) != 0) `7
- VB
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) `7B
- X fprintf(stderr, FilNamMsg, filename, "local");
- X continue; /* go on to next one */
- X `7D
- X `7D
- 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)) !=
- V 0)
- X `7B
- X if (error > error_in_archive)
- X error_in_archive = error;
- X if (error > 1) `7B
- X fprintf(stderr, ExtFieldMsg, filename, "local");
- X continue; /* go on */
- X `7D
- X `7D
- X
- X /*
- X * just about to extract file: if extracting to disk, check if
- X * already exists, and if so, take appropriate action according
- V 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`5B`
- V5D in
- X * info`5B`5D)
- X */
- X if (!tflag && !cflag) `7B
- 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 *
- V/
- X if ((error = mapname(!fflag `7C`7C renamed)) > 1) `7B /*
- V skip */
- X if ((error > 2) && (error_in_archive < 2))
- X error_in_archive = 2; /* (weak) error in zipfile *
- V/
- X continue; /* go on to next file */
- X `7D
- X
- X switch (check_for_newer(filename)) `7B
- X case DOES_NOT_EXIST:
- X if (fflag && !renamed) /* don't skip if just rename
- Vd */
- 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 `7C`7C (uflag && !renamed))
- X continue; /* skip if update/freshen & orig name
- V */
- X if (!overwrite_all && !force_flag)
- X query = TRUE;
- X break;
- X `7D
- 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?) *
- V/
- X if (query) `7B
- X#ifdef MSWIN
- X FARPROC lpfnprocReplace;
- X int ReplaceDlgRetVal; /* replace dialog return value *
- V/
- 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) `7B
- 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 `7D
- X#else /* !MSWIN */
- Xreprompt:
- X fprintf(stderr,
- X "replace %s? `5By`5Des, `5Bn`5Do, `5BA`5Dll, `5BN`5Don
- Ve, `5Br`5Dename: ",
- X filename);
- X FFLUSH /* for Amiga and Mac MPW */
- X fgets(answerbuf, 9, stdin);
- X switch (*answerbuf) `7B
- 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 `7B
- 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
- V */
- X len = strlen(filename);
- X if (filename`5Blen-1`5D == '\n')
- X filename`5B--len`5D = 0;
- X `7D 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 `5B%c`
- V5D\n",
- X *answerbuf); /* warn the user */
- X goto reprompt; /* why not another goto? */
- X `7D /* end switch (*answerbuf) */
- X#endif /* ?MSWIN */
- X `7D /* end if (query) */
- X/*#endif*/ /* !VMS */
- X `7D /* end if (extracting to disk) */
- X
- X#ifdef CRYPT
- X if (pInfo->encrypted && ((error = decrypt_member()) != 0)) `7B
- X if (error == 10) `7B
- X if (error > error_in_archive)
- X error_in_archive = error;
- X fprintf(stderr,
- X " skipping: %-22s unable to get password\n", filename
- V);
- X `7D else `7B /* (error == 1) */
- X fprintf(stderr,
- X " skipping: %-22s incorrect password\n", filename);
- X ++num_bad_pwd;
- X `7D
- X continue; /* go on to next file */
- X `7D
- X#endif /* CRYPT */
- X disk_full = 0;
- X if ((error = extract_or_test_member()) != 0) `7B
- 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 `7D
- X `7D /* 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
- V 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
- V */
- 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
- V,
- X cur_zipfile_bufstart);
- X printf("inptr-inbuf = %d\n", inptr-inbuf);
- X printf("incnt = %d\n\n", incnt);
- X#endif
- X
- X `7D /* end while-loop (blocks of files in central directory) */
- X
- X/*--------------------------------------------------------------------------
- V-
- 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
- V.
- X --------------------------------------------------------------------------
- V-*/
- X
- X readbuf(sig, 4);
- X if (strncmp(sig, end_central_sig, 4)) `7B /* just to make sure again
- V */
- X fprintf(stderr, EndSigMsg); /* didn't find end-of-central-dir sig *
- V/
- 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 `7D
- X if (tflag && (quietflg == 1)) `7B
- 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 `7D
- 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`7D /* 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`7B
- 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/*--------------------------------------------------------------------------
- V-
- X Check central directory info for version/compatibility requirements.
- X --------------------------------------------------------------------------
- V-*/
- 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`5B1`5D == VMS_) `7B
- X if (crec.version_needed_to_extract`5B0`5D > VMS_VERSION) `7B
- X fprintf(stderr, VersionMsg, filename, "VMS",
- X crec.version_needed_to_extract`5B0`5D / 10,
- X crec.version_needed_to_extract`5B0`5D % 10,
- X VMS_VERSION / 10, VMS_VERSION % 10);
- X return 1;
- X `7D
- X#ifndef VMS /* won't be able to use extra field, but still have data */
- X else if (!tflag && !force_flag) `7B /* if forcing, extract regardle
- Vss */
- 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 `7D
- X#endif /* !VMS */
- X /* usual file type: don't need VMS to extract */
- X `7D else if (crec.version_needed_to_extract`5B0`5D > UNZIP_VERSION) `7B
- X fprintf(stderr, VersionMsg, filename, "PK",
- X crec.version_needed_to_extract`5B0`5D / 10,
- X crec.version_needed_to_extract`5B0`5D % 10,
- X UNZIP_VERSION / 10, UNZIP_VERSION % 10);
- X return 1;
- X `7D
- X
- X if UNKN_COMPR `7B
- X fprintf(stderr, ComprMsg, filename, crec.compression_method);
- X return 1;
- X `7D
- X#ifndef CRYPT
- X if (pInfo->encrypted) `7B
- X fprintf(stderr, " skipping: %-22s encrypted (not supported)\n",
- X filename);
- X return 1;
- X `7D
- X#endif /* !CRYPT */
- X
- X/*--------------------------------------------------------------------------
- V-
- X Store some central-directory information (encryption, file attributes,
- X offsets) for later use.
- X --------------------------------------------------------------------------
- V-*/
- 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) `7B
- 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 `7C (tmp<<6) `7C (tmp<<3) `7
- VC tmp);
- X#ifdef UNIX
- X umask( (int)(tmp=umask(0)) );
- X pInfo->unix_attr &= `7Etmp;
- 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 `7D /* end switch (host-OS-created-by) */
- X
- X pInfo->offset = (longint) crec.relative_offset_local_header;
- X return 0;
- X
- X`7D /* 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`7B
- X#ifdef S_IFLNK
- X int symlnk=FALSE;
- X#endif /* S_IFLNK */
- X int error=0;
- X UWORD b;
- X
- X
- X
- X/*--------------------------------------------------------------------------
- V-
- X Initialize variables, buffers, etc.
- X --------------------------------------------------------------------------
- V-*/
- 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_
- V)
- X && !tflag && !cflag)
- X symlnk = TRUE;
- X#endif /* S_IFLNK */
- X
- X memset(outbuf, 0xaa, OUTBUFSIZ);
- X#if (!defined(DOS_OS2) `7C`7C 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 `7C`7C MSWIN */
- X
- X if (tflag) `7B
- X if (!quietflg) `7B
- X fprintf(stdout, " Testing: %-22s ", filename);
- X fflush(stdout);
- X `7D
- X `7D else `7B
- X if (cflag) `7B /* output to stdout (copy of it) */
- X#if (defined(MACOS) `7C`7C defined(AMIGA))
- X outfd = 1;
- X#else /* !(MACOS `7C`7C AMIGA) */
- X outfd = dup(1); /* GRR: change this to #define for Mac/Amiga
- V */
- X#endif /* ?(MACOS `7C`7C 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!
- V */
- X return 50; /* 50: disk full (?) */
- X#endif
- X `7D else
- X#ifdef S_IFLNK
- X if (!symlnk) /* symlink() takes care of file creation */
- X#endif /* !S_IFLNK */
- X `7B
- X if (create_output_file())
- X return 50; /* 50: disk full (?) */
- X `7D
- X `7D /* endif (!tflag) */
- X
- X/*--------------------------------------------------------------------------
- V-
- X Unpack the file.
- X --------------------------------------------------------------------------
- V-*/
- X
- X switch (lrec.compression_method) `7B
- X
- X case STORED:
- X if (!tflag && (quietflg < 2)) `7B
- X fprintf(stdout, " Extracting: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X `7D
- X#ifdef S_IFLNK
- X /*
- X * If file came from Unix and is a symbolic link and we are extracti
- Vng
- X * to disk, allocate a storage area, put the data in it, and create
- V the
- X * link. Since we know it's a symbolic link to start with, shouldn'
- Vt
- X * have to worry about overflowing unsigned ints with unsigned longs
- V.
- X * (This doesn't do anything for compressed symlinks, but that can b
- Ve
- 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) `7B
- X#if (defined(MTS) `7C`7C defined(MACOS))
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X#else /* !(MTS `7C`7C 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) `7B /* OK to overwr
- Vite */
- X unlink(filename);
- X if (symlink(orig, filename))
- X perror("symlink error");
- X `7D else
- X perror("symlink error");
- X free(orig);
- X#endif /* ?(MTS `7C`7C MACOS) */
- X `7D 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)) `7B
- X fprintf(stdout, "UnShrinking: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X `7D
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) `7B
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X `7D
- 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)) `7B
- X fprintf(stdout, " Expanding: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X `7D
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) `7B
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X `7D
- X#endif /* S_IFLNK */
- X unReduce();
- X break;
- X
- X case IMPLODED:
- X if (!tflag && (quietflg < 2)) `7B
- X fprintf(stdout, " Exploding: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X `7D
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) `7B
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X `7D
- X#endif /* S_IFLNK */
- X explode(); /* ignore return code for now */
- X break;
- X
- X case DEFLATED:
- X if (!tflag && (quietflg < 2)) `7B
- X fprintf(stdout, " Inflating: %-22s ", filename);
- X if (cflag)
- X fprintf(stdout, "\n");
- X fflush(stdout);
- X `7D
- X#ifdef S_IFLNK /* !!! This code needs to be added to unShrink, etc. !!! */
- X if (symlnk) `7B
- X fprintf(stdout, "\n warning: symbolic link ignored\n");
- X error = 1; /* 1: warning error */
- X `7D
- 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 `7D /* end switch (compression method) */
- X
- X if (disk_full) `7B /* set by FlushOutput()/OUTB() macro */
- X if (disk_full > 1)
- X return 50; /* 50: disk full */
- X error = 1; /* 1: warning error */
- X `7D
- X
- X/*--------------------------------------------------------------------------
- V-
- 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 --------------------------------------------------------------------------
- V-*/
- X
- X#ifdef S_IFLNK
- X if (!symlnk) `7B
- X#endif /* S_IFLNK */
- X if (!disk_full && FlushOutput())
- X if (disk_full > 1)
- X return 50; /* 50: disk full */
- X else `7B /* disk_full == 1 */
- X fprintf(stderr, "%s: probably corrupt\n", filename);
- X error = 1; /* 1: warning error */
- X `7D
- 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 `7D /* endif (!symlnk) */
- X#endif /* S_IFLNK */
- X
- X /* logical-AND crc32val for 64-bit machines */
- X if ((crc32val = ((`7Ecrc32val) & 0xFFFFFFFFL)) != lrec.crc32) `7B
- 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 `7D else if (tflag) `7B
- X if (!quietflg)
- X fprintf(stdout, " OK\n");
- X `7D else `7B
- X if ((quietflg < 2) && !error)
- X fprintf(stdout, "\n");
- X `7D
- X
- X return error;
- X
- X`7D /* 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`7B /* tty; 1 if password bad; 0 if password OK
- V */
- X UWORD b;
- X int n, r;
- X static int nopwd=FALSE;
- X char *m, *prompt;
- X byte h`5B12`5D;
- X
- X
- X /* get header once */
- X for (n = 0; n < 12; n++) `7B
- X ReadByte(&b);
- X h`5Bn`5D = (byte) b;
- X `7D
- X
- X /* if have key already, test it; else allocate memory for it */
- X if (key) `7B
- 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 `7D else if ((key = (char *)malloc(PWLEN+1)) == (char *)NULL)
- X return 10;
- X
- X if ((prompt = (char *)malloc(FILNAMSIZ+15)) != (char *)NULL) `7B
- X sprintf(prompt, "%s password: ", filename);
- X m = prompt;
- X `7D else
- X m = "Enter password: ";
- X
- X /* try a few keys */
- X for (r = 0; r < 3; ++r) `7B
- X m = getp(m, key, PWLEN+1);
- X if (prompt != (char *)NULL) `7B
- X free(prompt);
- X prompt = (char *)NULL;
- X `7D
- X if (m == (char *)NULL)
- X return 10;
- X if (!testp(h))
- X return 0;
- X if (*key == '\0') `7B
- X nopwd = TRUE;
- X return 1;
- X `7D
- X m = "password incorrect--reenter: ";
- X `7D
- X return 1;
- X`7D
- 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`7B
- 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`5Bn`5D);
- X b = DECRYPT(h`5B11`5D);
- 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 `7C (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n
- V",
- X (UWORD)(c `7C (b<<8)), (UWORD)(lrec.crc32 >> 16), lrec.last_mod_file_t
- Vime);
- X#endif /* CRYPT_DEBUG */
- X
- +-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+-
-