Article View: vmsnet.sources
Article #80Zip v1.9 & UnZip v5.0, part 11/22
From: goathunter
Date: Tue, 01 Sep 1992 22:51
Date: Tue, 01 Sep 1992 22:51
1332 lines
49780 bytes
49780 bytes
Submitted-by: goathunter@wkuvx1.bitnet
Posting-number: Volume 3, Issue 133
Archive-name: zip_unzip/part11
-+-+-+-+-+-+-+-+ START OF PART 11 -+-+-+-+-+-+-+-+
X if ((ascii_to_native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) `7B
X incnt -= inptr - inbuf;
X return 0; /* found it! */
X `7D /* ...otherwise fall through & fail */
X
X/*--------------------------------------------------------------------------
V-
X Zipfile is longer than INBUFSIZ: may need to loop. Start with short
X block at end of zipfile (if not TOO short).
X --------------------------------------------------------------------------
V-*/
X
X `7D else `7B
X if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) `7B
X cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) !
V=
X (int)tail_len)
X goto fail; /* shut up; it's expedient. */
X
X /* 'P' must be at least 22 bytes from end of zipfile */
X for (inptr = inbuf+(int)tail_len-22; inptr >= inbuf; --inptr)
X if ((ascii_to_native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) `7B
X incnt -= inptr - inbuf;
X return 0; /* found it */
X `7D /* ...otherwise search next block */
X strncpy((char *)hold, (char *)inbuf, 3); /* sig may span bloc
Vk
X boundary */
X `7D else `7B
X cur_zipfile_bufstart = ziplen - tail_len;
X `7D
X
X /*----------------------------------------------------------------------
V-
X Loop through blocks of zipfile data, starting at the end and going
X toward the beginning. Need only check last 65557 bytes of zipfile:
X comment may be up to 65535 bytes long, end-of-central-directory rec-
X ord is 18 bytes (shouldn't hardcode this number, but what the hell:
X already did so above (22=18+4)), and sig itself is 4 bytes.
X ----------------------------------------------------------------------
V-*/
X
X numblks = (int)
X ((MIN(ziplen,65557L) - tail_len + (INBUFSIZ-1)) / INBUFSIZ
V);
X /* =amount to search= ==done== ==rounding== =blksiz=
V */
X
X for (i = 1; i <= numblks; ++i) `7B
X cur_zipfile_bufstart -= INBUFSIZ;
X lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
X if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
X break; /* fall through and fail */
X
X for (inptr = inbuf+INBUFSIZ-1; inptr >= inbuf; --inptr)
X if ((ascii_to_native(*inptr) == 'P') &&
X !strncmp((char *)inptr, end_central_sig, 4)) `7B
X incnt -= inptr - inbuf;
X return 0; /* found it */
X `7D
X strncpy((char *)hold, (char *)inbuf, 3); /* sig may span bloc
Vk
X boundary */
X `7D
X
X `7D /* end if (ziplen > INBUFSIZ) */
X
X/*--------------------------------------------------------------------------
V-
X Searched through whole region where signature should be without finding
X it. Print informational message and die a horrible death.
X --------------------------------------------------------------------------
V-*/
X
Xfail:
X#ifdef MSWIN
X MessageBeep(1);
X#endif
X
X fprintf(stderr, "\nFile: %s\n\n\
X End-of-central-directory signature not found. Either this file is not\
Vn\
X a zipfile, or it constitutes one disk of a multi-part archive. In the\
Vn\
X latter case the central directory and zipfile comment will be found on\
Vn\
X the last disk(s) of this archive.\n", zipfn);
X return 1;
X
X`7D /* end function find_end_central_dir() */
X
X
X
X
X
X/***************************************/
X/* Function process_end_central_dir() */
X/***************************************/
X
Xint process_end_central_dir() /* return PK-type error code */
X`7B
X ec_byte_rec byterec;
X int error=0;
X
X
X/*--------------------------------------------------------------------------
V-
X Read the end-of-central-directory record and do any necessary machine-
X type conversions (byte ordering, structure padding compensation) by
X reading data into character array, then copying to struct.
X --------------------------------------------------------------------------
V-*/
X
X if (readbuf((char *) byterec, ECREC_SIZE+4) <= 0)
X return 51;
X
X ecrec.number_this_disk =
X makeword(&byterec`5BNUMBER_THIS_DISK`5D);
X ecrec.num_disk_with_start_central_dir =
X makeword(&byterec`5BNUM_DISK_WITH_START_CENTRAL_DIR`5D);
X ecrec.num_entries_centrl_dir_ths_disk =
X makeword(&byterec`5BNUM_ENTRIES_CENTRL_DIR_THS_DISK`5D);
X ecrec.total_entries_central_dir =
X makeword(&byterec`5BTOTAL_ENTRIES_CENTRAL_DIR`5D);
X ecrec.size_central_directory =
X makelong(&byterec`5BSIZE_CENTRAL_DIRECTORY`5D);
X ecrec.offset_start_central_directory =
X makelong(&byterec`5BOFFSET_START_CENTRAL_DIRECTORY`5D);
X ecrec.zipfile_comment_length =
X makeword(&byterec`5BZIPFILE_COMMENT_LENGTH`5D);
X
X/*--------------------------------------------------------------------------
V-
X Get the zipfile comment, if any, and print it out. (Comment may be up
X to 64KB long. May the fleas of a thousand camels infest the armpits of
X anyone who actually takes advantage of this fact.) Then position the
X file pointer to the beginning of the central directory and fill buffer.
X --------------------------------------------------------------------------
V-*/
X
X#ifdef MSWIN
X cchComment = ecrec.zipfile_comment_length; /* save for comment button */
X if (ecrec.zipfile_comment_length && zflag) `7B
X#else /* !MSWIN */
X if (ecrec.zipfile_comment_length && !quietflg) `7B
X if (!zflag)
X printf("`5B%s`5D comment:\n", zipfn);
X#endif /* ?MSWIN */
X if (do_string(ecrec.zipfile_comment_length,DISPLAY)) `7B
X fprintf(stderr, "\ncaution: zipfile comment truncated\n");
X error = 1; /* 1: warning error */
X `7D
X `7D
X
X return error;
X
X`7D /* end function process_end_central_dir() */
X
X
X
X
X
X/* also referenced in UpdateListBox() in updatelb.c (Windows version) */
Xchar *Headers`5B`5D`5B2`5D = `7B
X `7B" Length Date Time Name",
X " ------ ---- ---- ----"`7D,
X `7B" Length Method Size Ratio Date Time CRC-32 Name",
X " ------ ------ ---- ----- ---- ---- ------ ----"`7D
X`7D;
X
X/*************************/
X/* Function list_files() */
X/*************************/
X
Xint list_files() /* return PK-type error code */
X`7B
X char **fnamev;
X int do_this_file=FALSE, ratio, error, error_in_archive=0;
X int which_hdr=(vflag>1), date_format;
X UWORD j, yr, mo, dy, hh, mm, members=0;
X ULONG tot_csize=0L, tot_ucsize=0L;
X#ifdef OS2
X ULONG tot_easize=0L, tot_eafiles=0L, ea_size;
X#endif
X#ifdef MSWIN
X PSTR psLBEntry; /* list box entry */
X#endif
X min_info info;
X static char *method`5BNUM_METHODS+1`5D =
X `7B"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
X "Implode", "Token", "Deflate", unkn`7D;
X
X
X
X/*--------------------------------------------------------------------------
V-
X Unlike extract_or_test_files(), this routine confines itself to the cen-
X tral directory. Thus its structure is somewhat simpler, since we can do
X just a single loop through the entire directory, listing files as we go.
X
X So to start off, print the heading line and then begin main loop through
X the central directory. The results will look vaguely like the following
V:
X
X Length Method Size Ratio Date Time CRC-32 Name ("`5E" ==> c
Vase
X ------ ------ ---- ----- ---- ---- ------ ---- conversion
V)
X 44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
X 3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 `5Edos-file.ext
X --------------------------------------------------------------------------
V-*/
X
X pInfo = &info;
X date_format = dateformat();
X
X#ifndef MSWIN
X if (quietflg < 2)
X if (U_flag)
X printf("%s\n%s\n", Headers`5Bwhich_hdr`5D`5B0`5D, Headers`5Bwhic
Vh_hdr`5D`5B1`5D);
X else
X printf("%s (\"`5E\" ==> case\n%s conversion)\n",`20
X Headers`5Bwhich_hdr`5D`5B0`5D, Headers`5Bwhich_hdr`5D`5B1`5D);
X#endif /* !MSWIN */
X
X for (j = 0; j < ecrec.total_entries_central_dir; ++j) `7B
X
X if (readbuf(sig, 4) <= 0)
X return 51; /* 51: unexpected EOF */
X if (strncmp(sig, central_hdr_sig, 4)) `7B /* just to make sure */
X fprintf(stderr, CentSigMsg, j); /* sig not found */
X fprintf(stderr, ReportMsg); /* check binary transfers */
X return 3; /* 3: error in zipfile */
X `7D
X if ((error = process_cdir_file_hdr()) != 0) /* (sets pInfo->lcflag)
V */
X return error; /* only 51 (EOF) defined */
X
X /*
X * We could DISPLAY the filename instead of storing (and possibly tr
Vun-
X * cating, in the case of a very long name) and printing it, but tha
Vt
X * has the disadvantage of not allowing case conversion--and it's ni
Vce
X * to be able to see in the listing precisely how you have to type e
Vach
X * filename in order for unzip to consider it a match. Speaking of
X * which, if member names were specified on the command line, check
V in
X * with match() to see if the current file is one of them, and make
V a
X * note of it if it is.
X */
X
X if ((error = do_string(crec.filename_length, FILENAME)) != 0) `7B
X error_in_archive = error; /* `5E--(uses pInfo->lcfl
Vag) */
X if (error > 1) /* fatal: can't continue */
X return error;
X `7D
X if (extra_field != (byte *)NULL)
X free(extra_field);
X extra_field = (byte *)NULL;
X if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0)
V `7B
X error_in_archive = error; `20
X if (error > 1) /* fatal: can't continue */
X return error;
X `7D
X if (!process_all_files) `7B /* check if specified on command line
V */
X do_this_file = FALSE;
X fnamev = fnv; /* don't destroy permanent filename ptr */
X for (--fnamev; *++fnamev;)
X if (match(filename, *fnamev)) `7B
X do_this_file = TRUE;
X break; /* found match, so stop looping */
X `7D
X `7D
X /*
X * If current file was specified on command line, or if no names wer
Ve
X * specified, do the listing for this file. Otherwise, get rid of t
Vhe
X * file comment and go back for the next file.
X */
X
X if (process_all_files `7C`7C do_this_file) `7B
X
X yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)
V100;
X mo = (crec.last_mod_file_date >> 5) & 0x0f;
X dy = crec.last_mod_file_date & 0x1f;
X
X /* twist date so it displays according to national convention */
X switch (date_format) `7B
X case DF_YMD:
X hh = mo; mo = yr; yr = dy; dy = hh; break;
X case DF_DMY:
X hh = mo; mo = dy; dy = hh;
X `7D
X hh = (crec.last_mod_file_time >> 11) & 0x1f;
X mm = (crec.last_mod_file_time >> 5) & 0x3f;
X
X csize = (longint) crec.compressed_size;
X ucsize = (longint) crec.uncompressed_size;
X if (crec.general_purpose_bit_flag & 1)
X csize -= 12; /* if encrypted, don't count encrypt hdr */
X
X ratio = (ucsize == 0) ? 0 : /* .zip can have 0-length members
V */
X ((ucsize > 2000000L) ? /* risk signed overflow if mult. *
V/
X (int) ((ucsize-csize) / (ucsize/1000L)) + 5 : /* big */
X (int) ((1000L*(ucsize-csize)) / ucsize) + 5); /* small */
X
X#if 0 /* GRR/Euro: add this? define p above */
X#if (defined(DOS_OS2) `7C`7C (defined(UNIX) && !defined(VMS)))
X for (p = filename; *p; ++p)
X if (!isprint(*p))
X *p = '?'; /* change non-printable chars to '?' */
X#endif /* DOS_OS2 `7C`7C UNIX */
X#endif /* 0 */
X
X#ifdef MSWIN
X#ifdef NEED_EARLY_REDRAW
X /* turn on listbox redrawing just before adding last line */
X if (j == (ecrec.total_entries_central_dir-1))
X (void)SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L);
X#endif /* NEED_EARLY_REDRAW */
X psLBEntry =
X (PSTR)LocalAlloc(LMEM_FIXED, FILNAMSIZ+LONG_FORM_FNAME_INX);
X switch (which_hdr) `7B
X case 0: /* short form */
X OemToAnsi(filename, filename); /* translate to ANSI */
X wsprintf(psLBEntry, "%7ld %02u-%02u-%02u %02u:%02u %c
V%s",
X (long)ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'`5E'
V:' '),
X (LPSTR)filename);
X SendMessage(hWndList, LB_ADDSTRING, 0,
X (LONG)(LPSTR)psLBEntry);
X break;
X case 1: /* verbose */
X OemToAnsi(filename, filename); /* translate to ANSI */
X wsprintf(psLBEntry,`20
X "%7ld %-7s%7ld %3d%% %02u-%02u-%02u %02u:%02u %08lx %c
V%s",
X (long)ucsize, (LPSTR)method`5Bmethnum`5D, (long)csize,
X ratio/10, mo, dy, yr, hh, mm, (unsigned long)crec.crc3
V2,
X (pInfo->lcflag?'`5E':' '), (LPSTR)filename);
X SendMessage(hWndList, LB_ADDSTRING, 0,
X (LONG)(LPSTR)psLBEntry);
X `7D
X LocalFree((HANDLE)psLBEntry);
X#else /* !MSWIN */
X switch (which_hdr) `7B
X case 0: /* short form */
X printf("%7ld %02u-%02u-%02u %02u:%02u %c%s\n",
X ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'`5E':' '),
X filename);
X break;
X case 1: /* verbose */
X printf(
X "%7ld %-7s%7ld %3d%% %02u-%02u-%02u %02u:%02u %08lx %c%s\
Vn",
X ucsize, method`5Bmethnum`5D, csize, ratio/10, mo, dy,
V yr,
X hh, mm, crec.crc32, (pInfo->lcflag?'`5E':' '), filenam
Ve);
X `7D
X#endif /* ?MSWIN */
X
X error = do_string(crec.file_comment_length, (QCOND? DISPLAY:SKIP
V));
X if (error) `7B
X error_in_archive = error; /* might be just warning */
X if (error > 1) /* fatal */
X return error;
X `7D
X tot_ucsize += (ULONG) ucsize;
X tot_csize += (ULONG) csize;
X ++members;
X#ifdef OS2
X if ((ea_size = SizeOfEAs(extra_field)) != 0) `7B
X tot_easize += ea_size;
X tot_eafiles++;
X `7D
X#endif
X `7D else `7B /* not listing this file */
X SKIP_(crec.file_comment_length)
X `7D
X `7D /* end for-loop (j: files in central directory) */
X
X/*--------------------------------------------------------------------------
V-
X Print footer line and totals (compressed size, uncompressed size, number
X of members in zipfile).
X --------------------------------------------------------------------------
V-*/
X
X ratio = (tot_ucsize == 0) ?`20
X 0 : ((tot_ucsize > 4000000L) ? /* risk unsigned overflow if mult.
V */
X (int) ((tot_ucsize - tot_csize) / (tot_ucsize/1000L)) + 5 :
X (int) ((tot_ucsize - tot_csize) * 1000L / tot_ucsize) + 5);
X
X if (quietflg < 2) `7B
X#ifdef MSWIN
X /* Display just the totals since the dashed lines get displayed
X * in UpdateListBox(). Get just enough space to display total.
X */
X switch (which_hdr) `7B
X case 0: /* short */
X wsprintf(lpumb->szTotalsLine, "%7lu %-7u"
V,`20
X (ULONG)tot_ucsize, members);
X break;
X case 1: /* verbose */
X wsprintf(lpumb->szTotalsLine,`20
X "%7lu %7lu %3d%% %-7u
V",`20
X (ULONG)tot_ucsize, (ULONG)tot_csize, ratio / 10, members);
X break;
X `7D
X#else /* !MSWIN */
X switch (which_hdr) `7B
X case 0: /* short */
X printf("%s\n%7lu %-7u\n",
X " ------ -------",
X tot_ucsize, members);
X break;
X case 1: /* verbose */
X printf(
X "%s\n%7lu %7lu %3d%% %-7u
V\n",
X " ------ ------ --- ---
V----",
X tot_ucsize, tot_csize, ratio / 10, members);
X `7D
X#endif /* ?MSWIN */
X#ifdef OS2
X if (tot_eafiles && tot_easize)
X printf("\n%ld file%s %ld bytes of EA's attached.\n", tot_eafiles
V,`20
X tot_eafiles == 1 ? " has" : "s have a total of", tot_easize);
X#endif
X `7D
X/*--------------------------------------------------------------------------
V-
X Double check that we're back at the end-of-central-directory record.
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); */
X error_in_archive = 1; /* 1: warning error */
X `7D
X return error_in_archive;
X
X`7D /* end function list_files() */
X
X
X
X
X
X/**************************************/
X/* Function process_cdir_file_hdr() */
X/**************************************/
X
Xint process_cdir_file_hdr() /* return PK-type error code */
X`7B
X cdir_byte_hdr byterec;
X
X
X/*--------------------------------------------------------------------------
V-
X Read the next central directory entry and do any necessary machine-type
X conversions (byte ordering, structure padding compensation--do so by
X copying the data from the array into which it was read (byterec) to the
X usable struct (crec)).
X --------------------------------------------------------------------------
V-*/
X
X if (readbuf((char *) byterec, CREC_SIZE) <= 0)
X return 51; /* 51: unexpected EOF */
X
X crec.version_made_by`5B0`5D = byterec`5BC_VERSION_MADE_BY_0`5D;
X crec.version_made_by`5B1`5D = byterec`5BC_VERSION_MADE_BY_1`5D;
X crec.version_needed_to_extract`5B0`5D = byterec`5BC_VERSION_NEEDED_TO_EX
VTRACT_0`5D;
X crec.version_needed_to_extract`5B1`5D = byterec`5BC_VERSION_NEEDED_TO_EX
VTRACT_1`5D;
X
X crec.general_purpose_bit_flag =
X makeword(&byterec`5BC_GENERAL_PURPOSE_BIT_FLAG`5D);
X crec.compression_method =
X makeword(&byterec`5BC_COMPRESSION_METHOD`5D);
X crec.last_mod_file_time =
X makeword(&byterec`5BC_LAST_MOD_FILE_TIME`5D);
X crec.last_mod_file_date =
X makeword(&byterec`5BC_LAST_MOD_FILE_DATE`5D);
X crec.crc32 =
X makelong(&byterec`5BC_CRC32`5D);
X crec.compressed_size =
X makelong(&byterec`5BC_COMPRESSED_SIZE`5D);
X crec.uncompressed_size =
X makelong(&byterec`5BC_UNCOMPRESSED_SIZE`5D);
X crec.filename_length =
X makeword(&byterec`5BC_FILENAME_LENGTH`5D);
X crec.extra_field_length =
X makeword(&byterec`5BC_EXTRA_FIELD_LENGTH`5D);
X crec.file_comment_length =
X makeword(&byterec`5BC_FILE_COMMENT_LENGTH`5D);
X crec.disk_number_start =
X makeword(&byterec`5BC_DISK_NUMBER_START`5D);
X crec.internal_file_attributes =
X makeword(&byterec`5BC_INTERNAL_FILE_ATTRIBUTES`5D);
X crec.external_file_attributes =
X makelong(&byterec`5BC_EXTERNAL_FILE_ATTRIBUTES`5D); /* LONG, not wo
Vrd! */
X crec.relative_offset_local_header =
X makelong(&byterec`5BC_RELATIVE_OFFSET_LOCAL_HEADER`5D);
X
X pInfo->hostnum = MIN(crec.version_made_by`5B1`5D, NUM_HOSTS);
X/* extnum = MIN(crec.version_needed_to_extract`5B1`5D, NUM_HOSTS); */
X methnum = MIN(crec.compression_method, NUM_METHODS);
X if (methnum == NUM_METHODS)
X sprintf(unkn, "Unk:%03d", crec.compression_method);
X
X/*--------------------------------------------------------------------------
V-
X Set flag for lowercase conversion of filename, depending on which OS the
X file is coming from. This section could be ifdef'd if some people have
X come to love DOS uppercase filenames under Unix...but really, guys, get
X a life. :) NOTE THAT ALL SYSTEM NAMES NOW HAVE TRAILING UNDERSCORES!!!
X This is to prevent interference with compiler command-line defines such
X as -DUNIX, for example, which are then used in "#ifdef UNIX" constructs.
X --------------------------------------------------------------------------
V-*/
X
X pInfo->lcflag = 0;
X if (!U_flag) /* as long as user hasn't specified case-preservation */
X switch (pInfo->hostnum) `7B
X case DOS_OS2_FAT_:
X /* case VMS_: VMS Zip converts filenames to lowercase
V */
X case VM_CMS_: /* all caps? */
X case CPM_: /* like DOS, right? */
X /* case ATARI_: ? */
X /* case Z_SYSTEM_: ? */
X /* case TOPS20_: (if we had such a thing...) */
X pInfo->lcflag = 1; /* convert filename to lowercase */
X break;
X
X default: /* AMIGA_, UNIX_, (ATARI_), OS2_HPFS_, *
V/
X break; /* MAC_, (Z_SYSTEM_): no conversion *
V/
X `7D
X
X return 0;
X
X`7D /* end function process_cdir_file_hdr() */
X
X
X
X
X
X/***************************************/
X/* Function process_local_file_hdr() */
X/***************************************/
X
Xint process_local_file_hdr() /* return PK-type error code */
X`7B
X local_byte_hdr byterec;
X
X
X/*--------------------------------------------------------------------------
V-
X Read the next local file header and do any necessary machine-type con-
X versions (byte ordering, structure padding compensation--do so by copy-
X ing the data from the array into which it was read (byterec) to the
X usable struct (lrec)).
X --------------------------------------------------------------------------
V-*/
X
X if (readbuf((char *) byterec, LREC_SIZE) <= 0)
X return 51; /* 51: unexpected EOF */
X
X lrec.version_needed_to_extract`5B0`5D = byterec`5BL_VERSION_NEEDED_TO_EX
VTRACT_0`5D;
X lrec.version_needed_to_extract`5B1`5D = byterec`5BL_VERSION_NEEDED_TO_EX
VTRACT_1`5D;
X
X lrec.general_purpose_bit_flag = makeword(&byterec`5BL_GENERAL_PURPOSE_BI
VT_FLAG`5D);
X lrec.compression_method = makeword(&byterec`5BL_COMPRESSION_METHOD`5D);
X lrec.last_mod_file_time = makeword(&byterec`5BL_LAST_MOD_FILE_TIME`5D);
X lrec.last_mod_file_date = makeword(&byterec`5BL_LAST_MOD_FILE_DATE`5D);
X lrec.crc32 = makelong(&byterec`5BL_CRC32`5D);
X lrec.compressed_size = makelong(&byterec`5BL_COMPRESSED_SIZE`5D);
X lrec.uncompressed_size = makelong(&byterec`5BL_UNCOMPRESSED_SIZE`5D);
X lrec.filename_length = makeword(&byterec`5BL_FILENAME_LENGTH`5D);
X lrec.extra_field_length = makeword(&byterec`5BL_EXTRA_FIELD_LENGTH`5D);
X
X csize = (longint) lrec.compressed_size;
X ucsize = (longint) lrec.uncompressed_size;
X
X if ((lrec.general_purpose_bit_flag & 8) != 0) `7B
X /* Can't trust local header, use central directory: */
X lrec.crc32 = pInfo->crc;
X lrec.compressed_size = pInfo->compr_size;
X csize = (longint) lrec.compressed_size;
X `7D
X
X return 0; /* 0: no error */
X
X`7D /* end function process_local_file_hdr() */
$ CALL UNPACK [.UNZIP50]UNZIP.C;1 157894339
$ create 'f'
X
XUNZIP(1) USER COMMANDS UNZIP(1)
X
XNAME
X unzip - list/test/extract from a ZIP archive file
X
XSYNOPSIS
X unzip `5B -cflptuvxz`5BajnoqUV`5D `5D file`5B.zip`5D `5Bfilespec ...`5D
X
XARGUMENTS
X file`5B.zip`5D Path of the ZIP archive. The suffix `60`60.zip'' is
X applied if the file specified does not exist.
X Note that self-extracting ZIP files are sup-
X ported; just specify the `60`60.exe'' suffix your-
X self.
X
X `5Bfilespec`5D An optional list of archive members to be pro-
X cessed. Expressions may be used to match multi-
X ple members; be sure to quote expressions that
X contain characters interpreted by the operating
X system. See DESCRIPTION (below) for more
X details.
X
XOPTIONS
X -c extract files to stdout/screen (`60`60CRT'')
X -f freshen existing files (replace if newer); create none
X -l list archive files (short format)
X -p extract files to pipe; no informational messages
X -t test archive files
X -u update existing files; create new ones if needed
X -v list archive files (verbose format)
X -x extract files in archive (default)
X -z display only the archive comment
X
XMODIFIERS
X -a convert to MS-DOS textfile format (CR LF), Mac format
X (CR), Unix/VMS format (LF), OR from ASCII to EBCDIC,
X depending on your system (only use for TEXT files!)
X -j junk paths (don't recreate archive's directory struc-
X ture)
X -n never overwrite existing files; don't prompt
X -o OK to overwrite files without prompting
X -q perform operations quietly (-qq => even quieter)
X -s `5BOS/2, MS-DOS`5D allow spaces in filenames (e.g.,
X `60`60EA DATA. SF'')
X -U leave filenames uppercase if created under MS-DOS, VMS,
X etc.
X -V retain (VMS) file version numbers
X -X `5BVMS`5D restore owner/protection info (may require
X privileges)
X
XDESCRIPTION
X UnZip will list, test, or extract from a ZIP archive, com-
X monly found on MSDOS systems. Archive member extraction is
X implied by the absence of the -c, -p, -t, -l, -v or -z
X
XInfo-ZIP Last change: 21 Aug 92 (v5.0) 1
X
XUNZIP(1) USER COMMANDS UNZIP(1)
X
X options. All archive members are processed unless a
X filespec is provided to specify a subset of the archive
X members. The filespec is similar to an egrep expression,
X and may contain:
X
X * matches a sequence of 0 or more characters
X ? matches exactly 1 character
X \nnn matches the character having octal code nnn
X `5B...`5D matches any single character found inside the brack-
X ets; ranges are specified by a beginning character, a
X hyphen, and an ending character. If an exclamation
X point or a carat (`60!' or `60`5E') follows the left
X bracket, then the range of characters matched is com-
X plemented with respect to the ASCII character set
X (that is, anything except the characters inside the
X brackets is considered a match).
X
XENVIRONMENT OPTIONS
X UnZip's default behavior may be modified via options placed
X in an environment variable. This can be done with any
X option, but it is probably most useful with the -q, -o, or
X -n modifiers: in order to make UnZip quieter by default, or
X to make it always overwrite or never overwrite files as it
X extracts them. For example, to make UnZip act as quietly as
X possible, only reporting errors, one would use one of the
X following commands:
X
X setenv UNZIP -qq Unix C shell
X
X UNZIP=-qq; export UNZIP Unix Bourne shell
X
X set UNZIP=-qq OS/2 or MS-DOS
X
X define UNZIP_OPTS "-qq" VMS (quotes for LOWERCASE)
X
X Environment options are, in effect, considered to be just
X like any other command-line options, except that they are
X effectively the first options on the command line. To over-
X ride an environment option, one may use the `60`60minus opera-
X tor'' to remove it. For instance, to override one of the
X quiet-flags in the example above, use the command
X
X unzip --q`5Bother options`5D zipfile
X
X The first hyphen is the normal switch character, and the
X second is a minus sign, acting on the q option. Thus the
X effect here is to cancel a single quantum of quietness. To
X cancel both quiet flags, two (or more) minuses may be used:
X
X unzip -x--q zipfile
X
XInfo-ZIP Last change: 21 Aug 92 (v5.0) 2
X
XUNZIP(1) USER COMMANDS UNZIP(1)
X
X or
X
X unzip ---qx zipfile
X
X (the two are equivalent). This may seem awkward or confus-
X ing, but it is reasonably intuitive: just ignore the first
X hyphen and go from there. It is also consistent with the
X behavior of Unix nice(1).
X
XEXAMPLES
X To use UnZip to extract all members of the archive
X letters.zip, creating any directories as necessary:
X
X unzip letters
X
X To extract all members of letters.zip to the current direc-
X tory:
X
X unzip -j letters
X
X To test letters.zip, printing only a summary message indi-
X cating whether the archive is OK or not:
X
X unzip -tq letters
X
X To extract to standard output all members of letters.zip
X whose names end in `60`60.tex'', converting to the local end-
X of-line convention and piping the output into more(1):
X
X unzip -ca letters \*.tex `7C more
X
X (The backslash before the asterisk is only required if the
X shell expands wildcards, as in Unix; double quotes could
X have been used instead, as in the source example below.) To
X extract the binary file paper1.dvi to standard output and
X pipe it to a printing program:
X
X unzip -p articles paper1.dvi `7C dvips
X
X To extract all FORTRAN and C source files--*.f, *.c, *.h,
X Makefile (the double quotes are necessary only in Unix and
X only if globbing is turned on):
X
X unzip source.zip "*.`5Bfch`5D" Makefile
X
X To extract only newer versions of the files already in the
X current directory, without querying (NOTE: be careful of
X unzipping in one timezone a zipfile created in another--ZIP
X archives contain no timezone information, and a `60`60newer''
X file from an eastern timezone may, in fact, be older):
X
XInfo-ZIP Last change: 21 Aug 92 (v5.0) 3
X
XUNZIP(1) USER COMMANDS UNZIP(1)
X
X unzip -fo sources
X
X To extract newer versions of the files already in the
X current directory and to create any files not already there
X (same caveat as previous example):
X
X unzip -uo sources
X
X In the last five examples, assume that UNZIP or UNZIP_OPTS
X is set to -q. To do a singly quiet listing:
X
X unzip -l file
X
X To do a doubly quiet listing:
X
X unzip -ql file
X
X To do a standard listing:
X
X unzip --ql file
X
X or
X
X unzip -l-q file
X
X or
X
X unzip -l--q file
X
X (extra minuses don't hurt).
X
XTIPS
X The current maintainer, being a lazy sort, finds it very
X useful to define an alias `60`60tt'' for `60`60unzip -tq''. One may
X then simply type `60`60tt zipfile'' to test the archive, some-
X thing which one ought make a habit of doing. With luck
X UnZip will report `60`60No errors detected in zipfile.zip,''
X after which one may breathe a sigh of relief.
X
XSEE ALSO
X funzip(1), zip(1), zipcloak(1), zipinfo(1), zipnote(1),
X zipsplit(1)
X
XAUTHORS
X Samuel H. Smith, Carl Mascott, David P. Kirschbaum, Greg R.
X Roelofs, Mark Adler, Kai Uwe Rommel, Igor Mandrichenko,
X Johnny Lee, Jean-loup Gailly; Glenn Andrews, Joel Aycock,
X Allan Bjorklund, James Birdsall, Wim Bonner, John Cowan,
X Frank da Cruz, Bill Davidsen, Arjan de Vet, James Dugal, Jim
X Dumser, Mark Edwards, David Feinleib, Mike Freeman, Hunter
X Goatley, Robert Heath, Dave Heiland, Larry Jones, Kjetil
X J`7Bob Kemp, J. Kercheval, Alvin Koh, Bo Kullmar, Johnny Lee,
X
XInfo-ZIP Last change: 21 Aug 92 (v5.0) 4
X
XUNZIP(1) USER COMMANDS UNZIP(1)
X
X Warner Losh, Fulvio Marino, Gene McManus, Joe Meadows, Mike
X O'Carroll, Humberto Ortiz-Zuazaga, Piet W. Plomp, Antonio
X Querubin Jr., Steve Salisbury, Georg Sassen, Jon Saxton,
X Hugh Schmidt, Martin Schulz, Charles Scripter, Chris Seaman,
X Richard Seay, Alex Sergejew, Cliff Stanford, Onno van der
X Linden, Jim Van Zandt, Antoine Verheijen, Paul Wells.
X
XVERSIONS
X v1.2 15 Mar 89 Samuel H. Smith
X v2.0 9 Sep 89 Samuel H. Smith
X v2.x fall 1989 many Usenet contributors
X v3.0 1 May 90 Info-ZIP (DPK, consolidator)
X v3.1 15 Aug 90 Info-ZIP (DPK, consolidator)
X v4.0 1 Dec 90 Info-ZIP (GRR, maintainer)
X v4.1 12 May 91 Info-ZIP
X v4.2 20 Mar 92 Info-ZIP (zip-bugs subgroup; GRR, maint.)
X v5.0 21 Aug 92 Info-ZIP (zip-bugs subgroup; GRR, maint.)
X
XInfo-ZIP Last change: 21 Aug 92 (v5.0) 5
X
$ CALL UNPACK [.UNZIP50]UNZIP.DOC;1 1762853046
$ create 'f'
X/*--------------------------------------------------------------------------
V-
X
X unzip.h
X
X This header file is used by all of the unzip source files. Its contents
X are divided into seven more-or-less separate sections: predefined macros,
X OS-dependent includes, (mostly) OS-independent defines, typedefs, function
V`20
X prototypes (or "prototypes," in the case of non-ANSI compilers), macros,`2
V0
X and global-variable declarations.
X
X --------------------------------------------------------------------------
V-*/
X
X
X
X/*****************************************/
X/* Predefined, Machine-specific Macros */
X/*****************************************/
X
X#if (defined(__GO32__) && defined(unix)) /* DOS extender */
X# undef unix
X#endif
X
X#if (defined(unix) && !defined(UNIX))
X# define UNIX
X#endif /* unix && !UNIX */
X
X/* Much of the following is swiped from zip's tailor.h: */
X
X/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C
V */
X#ifdef __POWERC
X# define __TURBOC__
X# define MSDOS
X#endif /* __POWERC */
X#if (defined(__TURBOC__) && defined(__MSDOS__) && !defined(MSDOS))
X# define MSDOS
X#endif
X
X/* use prototypes and ANSI libraries if __STDC__, or Microsoft or Borland C,
X * or Silicon Graphics, or Convex, or IBM C Set/2, or GNU gcc under emx, or
X * or Watcom C, or Macintosh, or Windows NT.
X */
X#if (__STDC__ `7C`7C defined(MSDOS) `7C`7C defined(sgi) `7C`7C defined(CONVE
VX))
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X#if (defined(__IBMC__) `7C`7C defined(__EMX__) `7C`7C defined(__WATCOMC__))
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X#if (defined(THINK_C) `7C`7C defined(MPW) `7C`7C defined(WIN32))
X# ifndef PROTO
X# define PROTO
X# endif
X# define MODERN
X#endif
X
X/* turn off prototypes if requested */
X#if (defined(NOPROTO) && defined(PROTO))
X# undef PROTO
X#endif
X
X/* used to remove arguments in function prototypes for non-ANSI C */
X#ifdef PROTO
X# define OF(a) a
X#else /* !PROTO */
X# define OF(a) ()
X#endif /* ?PROTO */
X
X#if (defined(ultrix) `7C`7C defined(bsd4_2) `7C`7C defined(sun) `7C`7C defin
Ved(pyr))
X# if (!defined(BSD) && !defined(__SYSTEM_FIVE) && !defined(SYSV))
X# define BSD
X# endif /* !BSD && !__SYSTEM_FIVE && !SYSV */
X#endif /* ultrix `7C`7C bsd4_2 `7C`7C sun `7C`7C pyr */
X
X#if (defined(CONVEX) `7C`7C defined(CRAY) `7C`7C defined(__SYSTEM_FIVE))
X# ifndef TERMIO
X# define TERMIO
X# endif /* !TERMIO */
X#endif /* CONVEX `7C`7C CRAY `7C`7C __SYSTEM_FIVE */
X
X#ifdef pyr /* Pyramid */
X# ifndef ZMEM
X# define ZMEM
X# endif /* !ZMEM */
X#endif /* pyr */
X
X#ifdef CRAY
X# ifdef ZMEM
X# undef ZMEM
X# endif /* ZMEM */
X#endif /* CRAY */
X
X/* the i386 test below is to catch SCO Unix (which has redefinition
X * warnings if param.h is included), but it probably doesn't hurt if
X * other 386 Unixes get nailed, too...except now that 386BSD and BSDI
X * exist. Sigh. <sys/param.h> is mostly included for "BSD", I think.
X * `5BAn alternate fix for SCO Unix is below.`5D
X */
X#if (defined(MINIX) `7C`7C (defined(i386) && defined(unix)))
X# define NO_PARAM_H
X#endif /* MINIX `7C`7C (i386 && unix) */
X
X
X
X
X
X/***************************/
X/* OS-Dependent Includes */
X/***************************/
X
X#ifndef MINIX /* Minix needs it after all the other includes (?)
V */
X# include <stdio.h>
X#endif
X#include <ctype.h> /* skip for VMS, to use tolower() function? */
X#include <errno.h> /* used in mapname() */
X#ifndef NO_ERRNO
X# define DECLARE_ERRNO /* everybody except MSC 6.0, SCO cc, Watcom C/386 *
V/
X#endif /* !NO_ERRNO */
X#ifdef VMS
X# include <types.h> /* (placed up here instead of in VMS section below
V */
X# include <stat.h> /* because types.h is used in some other headers) *
V/
X#else /* !VMS */
X# if !defined(THINK_C) && !defined(MPW)
X# include <sys/types.h> /* off_t, time_t, dev_t, ... */
X# include <sys/stat.h>
X# endif /* !THINK_C && !MPW */
X#endif /* ?VMS */
X
X#ifdef MODERN
X# if (!defined(M_XENIX) && !(defined(__GNUC__) && defined(sun)))
X# include <stddef.h>
X# endif
X# if (!defined(__GNUC__) && !defined(apollo)) /* both define __STDC__ */
X# include <stdlib.h> /* standard library prototypes, malloc(), etc. */
X# else
X# ifdef __EMX__
X# include <stdlib.h> /* emx IS gcc but has stdlib.h */
X# endif
X# endif
X# include <string.h> /* defines strcpy, strcmp, memcpy, etc. */
X typedef size_t extent;
X typedef void voidp;
X#else /* !MODERN */
X char *malloc();
X char *strchr(), *strrchr();
X long lseek();
X typedef unsigned int extent;
X# define void int
X typedef char voidp;
X#endif /* ?MODERN */
X
X/* this include must be down here for SysV.4, for some reason... */
X#include <signal.h> /* used in unzip.c, file_io.c */
X
X
X
X/*--------------------------------------------------------------------------
V-
X Next, a word from our Unix (mostly) sponsors:
X --------------------------------------------------------------------------
V-*/
X
X#ifdef UNIX
X# ifdef AMIGA
X# include <libraries/dos.h>
X# else /* !AMIGA */
X# ifndef NO_PARAM_H
X#if 0 /* `5BGRR: this is an alternate fix for SCO's redefinition bug`5D */
X# ifdef NGROUPS_MAX
X# undef NGROUPS_MAX /* SCO bug: defined again in <param.h> */
X# endif /* NGROUPS_MAX */
X#endif /* 0 */
X# include <sys/param.h> /* conflict with <sys/types.h>, some systems?
V */
X# endif /* !NO_PARAM_H */
X# endif /* ?AMIGA */
X
X# ifndef BSIZE
X# ifdef MINIX
X# define BSIZE 1024
X# else /* !MINIX */
X# define BSIZE DEV_BSIZE /* assume common for all Unix systems */
X# endif /* ?MINIX */
X# endif
X
X# ifndef BSD
X# if (!defined(AMIGA) && !defined(MINIX))
X# define NO_MKDIR /* for mapname() */
X# endif /* !AMIGA && !MINIX */
X# include <time.h>
X struct tm *gmtime(), *localtime();
X# else /* BSD */
X# include <sys/time.h>
X# include <sys/timeb.h>
X# ifdef _AIX
X# include <time.h>
X# endif
X# endif
X
X#else /* !UNIX */
X# define BSIZE 512 /* disk block size */
X#endif /* ?UNIX */
X
X#if (defined(V7) `7C`7C defined(BSD))
X# define strchr index
X# define strrchr rindex
X#endif
X
X/*--------------------------------------------------------------------------
V-
X And now, our MS-DOS and OS/2 corner:
X --------------------------------------------------------------------------
V-*/
X
X#ifdef __TURBOC__
X# define DOS_OS2
X# include <sys/timeb.h> /* for structure ftime
V */
X# ifndef __BORLANDC__ /* there appears to be a bug (?) in Borland's
V */
X# include <mem.h> /* MEM.H related to __STDC__ and far poin-
V */
X# endif /* ters. (dpk) `5Bmem.h included for memcpy
V`5D */
X# include <dos.h> /* for REGS macro (at least for Turbo C 2.0)
V */
X#else /* NOT Turbo C (or Power C)...
V */
X# ifdef MSDOS /* but still MS-DOS, so we'll assume it's
V */
X# ifndef MSC /* Microsoft's compiler and fake the ID, if
V */
X# define MSC /* necessary (it is in 5.0; apparently not
V */
X# endif /* in 5.1 and 6.0)
V */
X# include <dos.h> /* for _dos_setftime()
V */
X# endif
X#endif
X
X#if (defined(__IBMC__) && defined(__OS2__))
X# define DOS_OS2
X# define S_IFMT 0xF000
X# define timezone _timezone
X#endif
X
X#ifdef __WATCOMC__
X# define DOS_OS2
X# define __32BIT__
X# ifdef DECLARE_ERRNO
X# undef DECLARE_ERRNO
X# endif
X# undef far
X# define far
X#endif
X
X#ifdef __EMX__
X# define DOS_OS2
X# define __32BIT__
X# define far
X#endif /* __EMX__ */
X
X#ifdef MSC /* defined for all versions of MSC now
V */
X# define DOS_OS2 /* Turbo C under DOS, MSC under DOS or OS/2
V */
X# if (defined(_MSC_VER) && (_MSC_VER >= 600)) /* new with 5.1 or 6.0 ...
V */
X# undef DECLARE_ERRNO /* errno is now a function in a dynamic link
V */
X# endif /* library (or something)--incompatible with
V */
X#endif /* the usual "extern int errno" declaration
V */
X
X#ifdef DOS_OS2 /* defined for all MS-DOS and OS/2 compilers
V */
X# include <io.h> /* lseek(), open(), setftime(), dup(), creat()
V */
X# include <time.h> /* localtime() */
X#endif
X
X#ifdef OS2 /* defined for all OS/2 compilers */
X# ifdef isupper
X# undef isupper
X# endif
X# ifdef tolower
X# undef tolower
X# endif
X# define isupper(x) IsUpperNLS((unsigned char)(x))
X# define tolower(x) ToLowerNLS((unsigned char)(x))
X#endif
X
X#ifdef WIN32
X# include <io.h> /* read(), open(), etc. */
X# include <time.h>
X# include <memory.h>
X# include <direct.h> /* mkdir() */
X# ifdef FILE_IO_C
X# include <fcntl.h>
X# include <conio.h>
X# include <sys\types.h>
X# include <sys\utime.h>
X# include <windows.h>
X# define DOS_OS2
X# define getch() getchar()
X# endif
X#endif
X
X/*--------------------------------------------------------------------------
V-
X Followed by some VMS (mostly) stuff:
X --------------------------------------------------------------------------
V-*/
X
X#ifdef VMS
X# include <time.h> /* the usual non-BSD time functions */
X# include <file.h> /* same things as fcntl.h has */
X# include <rms.h>
X# define _MAX_PATH NAM$C_MAXRSS /* to define FILNAMSIZ below */
X# define UNIX /* can share most of same code from now on
V */
X# define RETURN return_VMS /* VMS interprets return codes incorrectly
V */
X#else /* !VMS */
X# ifndef THINK_C
X# define RETURN return /* only used in main() */
X# else
X# define RETURN(v) `7B int n;\
X n = (v);\
X fprintf(stderr, "\npress <return> to continue ");\
X while (getc(stdin) != '\n');\
X putc('\n', stderr);\
X InitCursor();\
X goto start;\
X `7D
X# endif
X# ifdef V7
X# define O_RDONLY 0
X# define O_WRONLY 1
X# define O_RDWR 2
X# else /* !V7 */
X# ifdef MTS
X# include <sys/file.h> /* MTS uses this instead of fcntl.h */
X# include <timeb.h>
X# include <time.h>
X# else /* !MTS */
X# ifdef COHERENT /* Coherent 3.10/Mark Williams C */
X# include <sys/fcntl.h>
X# define SHORT_NAMES
X# define tzset settz
X# else /* !COHERENT */
X# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation
V */
X# endif /* ?COHERENT */
X# endif /* ?MTS */
X# endif /* ?V7 */
X#endif /* ?VMS */
X
X#if (defined(MSDOS) `7C`7C defined(VMS))
X# define DOS_VMS
X#endif
X
X/*--------------------------------------------------------------------------
V-
X And some Mac stuff for good measure:
X --------------------------------------------------------------------------
V-*/
X
X#ifdef THINK_C
X# define MACOS
X# ifndef __STDC__ /* if Think C hasn't defined __STDC__ ... */
X# define __STDC__ 1 /* make sure it's defined: it needs it */
X# else /* __STDC__ defined */
X# if !__STDC__ /* sometimes __STDC__ is defined as 0; */
X# undef __STDC__ /* it needs to be 1 or required header */
X# define __STDC__ 1 /* files are not properly included. */
X# endif /* !__STDC__ */
X# endif /* ?defined(__STDC__) */
X#endif /* THINK_C */
X
X#ifdef MPW
X# define MACOS
X# include <Errors.h>
X# include <Files.h>
X# include <Memory.h>
X# include <Quickdraw.h>
X# include <ToolUtils.h>
X# define CtoPstr c2pstr
X# define PtoCstr p2cstr
X# ifdef CR
X# undef CR
X# endif
X#endif /* MPW */
X
X#ifdef MACOS
X# define open(x,y) macopen(x,y, gnVRefNum, glDirID)
X# define close macclose
X# define read macread
X# define write macwrite
X# define lseek maclseek
X# define creat(x,y) maccreat(x, gnVRefNum, glDirID, gostCreator, gostType)
X# define stat(x,y) macstat(x,y,gnVRefNum, glDirID)
X
X# ifndef isascii
X# define isascii(c) ((unsigned char)(c) <= 0x3F)
X# endif
X
X# include "macstat.h"
X
Xtypedef struct _ZipExtraHdr `7B
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
X`7D ZIP_EXTRA_HEADER;
X
Xtypedef struct _MacInfoMin `7B
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
X unsigned long signature; /* 4 bytes */
X FInfo finfo; /* 16 bytes */
X unsigned long lCrDat; /* 4 bytes */
X unsigned long lMdDat; /* 4 bytes */
X unsigned long flags ; /* 4 bytes */
X unsigned long lDirID; /* 4 bytes */
X /*------------*/
X`7D MACINFOMIN; /* = 40 bytes for size of data */
X
Xtypedef struct _MacInfo `7B
X unsigned short header; /* 2 bytes */
X unsigned short data; /* 2 bytes */
+-+-+-+-+-+-+-+- END OF PART 11 +-+-+-+-+-+-+-+-
Technical Details
Message-ID:
<8009648@MVB.SAIC.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sourcesShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sources From: goathunter@wkuvx1.bitnet Newsgroups: vmsnet.sources Subject: Zip v1.9 & UnZip v5.0, part 11/22 Message-ID: <8009648@MVB.SAIC.COM> Date: Tue, 01 Sep 1992 22:51:38 GMT Organization: Western Kentucky University, Bowling Green, KY Lines: 1332 Approved: Mark.Berryman@Mvb.Saic.Com