home *** CD-ROM | disk | FTP | other *** search
- Date: Mon, 29 Jan 90 01:32:06 EST
- From: jjw7384@ultb.isc.rit.edu (Jeff Wasilko)
- Subject: Batch Unbinhexing/Unstuffing (SUMMARY and SOURCE)
-
-
- Quite a while ago, I requested info on batch un-binhexing/
- un-stufing software available for the mac. I received a few
- replies about this, all of them but one suggesting a solution
- centered around a mainframe. One person suggested that Ray Lau's
- commercial version of Stuffit might do batch work.
-
- What I found was a trio of programs from the archives at
- sumex-aim.stanford.edu in the /info-mac/unix directory. The
- combination of these three programs allow almost-batch operation
- (I'll get into why it's 'almost' later).
-
- The three programs are:
- -rw-r--r-- 1 macmod info-mac 54554 Jan 16 18:18 mcvert-15.shar
-
- mcvert converts a .hqx (BinHex 4.0) file to a .bin (MacBinary
- file) that can be read by unsit. This program allows wildcard
- operations. Additionally, mcvert will unpack PackIt files.
-
- Files in: *.hqx
- Files out: *.bin (generally *.sit.bin)
-
- -rw-r--r-- 1 macmod info-mac 26067 Jan 1 1989 unsit.shar
-
- unsit will decompress .sit.bin (MacBinary Stuffit files)
-
- I am enclosing a new version of unsit that Allen sent me to
- allow input from MacBinary files. Previously, it was only
- possible to input from macput/macget formatted files. The new version
- also adds compatiblity with Stuffit 1.5.1 and the new HMF
- folder scheme.
-
- At present, unsit can only output files in macput/macget format,
- but the author Allan Weber (weber%brand.usc.edu@oberon.usc.edu)
- said that he may add the option to output directly to MacBinary format.
-
- Files in: *.sit.bin
- Files out: foo.rsrc, foo.data, foo.info
-
- -rw-r--r-- 1 macmod info-mac 4184 Jan 1 1989 macbinary.shar
-
- macbinary (macbin) converts macput/macget type files to
- MacBinary files. This allows easy downloading with progams
- such as Kermit or ZTerm.
-
- macbin does NOT support wildcards, so this part of the
- conversion must be done manually.
-
- Files in: foo.rsrc, foo.data, foo.info
- Files out: foo.bin (Unstuffed and in Binary format)
-
-
- The combination of programs works very well and is extremely fast
- on our vax, especially when comparied to Stuffit's performance on
- a Plus.
-
- Since this process requires the use of three different programs,
- I'm writing a shell script to tie everything together. When I get
- it running, I'll send it along too.
-
- I'm including a new version of unsit that reads macbinary files.
-
- Jeff
-
-
- | RIT VAX/VMS Systems: | Jeff Wasilko | RIT Ultrix Systems: |
- |BITNET: jjw7384@ritvax+----------------------+INET:jjw7384@ultb.isc.rit.edu|
- |UUCP: {psuvax1, mcvax}!ritvax.bitnet!JJW7384 +___UUCP:jjw7384@ultb.UUCP____+
- |INTERNET: jjw7384@isc.rit.edu |'claimer: No one cares. |
-
-
- ------cut here for source for unsit 1.5------
-
-
- >From weber%brand.usc.edu%oberon.USC.EDU@usc.edu Wed Jan 10 17:35:07 1990
- Received: by ultb.isc.rit.edu (5.57/5.2 (Postmaster DPMSYS))
- id AA28138; Wed, 10 Jan 90 17:34:45 EST
- Received: from brand.usc.edu by usc.edu (5.59/SMI-3.0DEV3) id AA26388;
- Wed, 10 Jan 90 14:34:03 PST
- Received: by brand (5.61/SMI-3.0DEV3) id AA08278;
- Wed, 10 Jan 90 14:33:20 -0800
- Date: Wed, 10 Jan 1990 14:33:17 PST
- >From: Allan G. Weber <weber%brand.usc.edu@usc.edu>
- >To: jjw7384@usc.edu (Jeff Wasilko)
- In-Reply-To: Your message of Wed, 10 Jan 90 16:32:38 EST
- >Subject: unsit
- Message-Id: <CMM.0.88.632010797.weber@brand.usc.edu>
- Status: RO
-
- The problem is probably that unsit is expecting the file to be just the
- data fork of the Mac file, and Macbinary format has the data and resource
- forks together along with a header. I've include the lastest version of
- unsit below in case you don't have it. Some time ago I added a option to
- the program to make it skip the Macbinary header by using a "-m" switch
- on the command line. Try the version below with the -m and hopefully it
- will work.
-
- Allan Weber
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # Makefile
- # unsit.c
- # stuffit.h
- # updcrc.c
- # getopt.c
- # unsit.1
- # This archive created: Wed Jan 10 14:25:12 1990
- export PATH; PATH=/bin:$PATH
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
- Unsit, version 1.5
-
- These are the souces for "unsit", a Unix program for breaking apart
- StuffIt archive files created on a Macintosh into separate files on
- the Unix system. See the documentation at the beginning of "unsit.c"
- or the man page "unsit.1" for more information.
-
- To build the program, compile unsit.c and updcrc.c and link together.
- If your system doesn't have the getopt() routine in its standard
- library, also compile getopt.c and include it in the link.
-
- This program opens a pipe to the "compress" program for doing the
- uncompression of some of the files in the archive. Most Unix sites
- probably already have "compress". If not, it can be found in the
- comp.sources.unix archives.
-
- Comments and bug reports should be send to weber%brand.usc.edu@oberon.usc.edu
-
-
- Allan G. Weber
- Signal and Image Processing Institute
- University of Southern California
- Powell Hall 306, MC-0272
- Los Angeles, CA 90089-0272
- (213) 743-5519
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- GETOPT =
- #GETOPT = getopt.o
-
- unsit : unsit.o updcrc.o $(GETOPT)
- cc -o unsit unsit.o updcrc.o $(GETOPT)
-
- unsit.o : unsit.c stuffit.h
- getopt.o : getopt.c
-
- unsit.shar : README Makefile unsit.c stuffit.h updcrc.c getopt.c unsit.1
- shar README Makefile unsit.c stuffit.h updcrc.c getopt.c unsit.1 \
- >unsit.shar
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'unsit.c'
- then
- echo shar: will not over-write existing file "'unsit.c'"
- else
- cat << \SHAR_EOF > 'unsit.c'
- /*
- unsit - Macintosh StuffIt file extractor
-
- Version 1.5c, for StuffIt 1.5
-
- August 3, 1989
-
- This program will unpack a Macintosh StuffIt file into separate files.
- The data fork of a StuffIt file contains both the data and resource
- forks of the packed files. The program will unpack each Mac file into
- separate .data, .rsrc., and .info files that can be downloaded to a
- Mac using macput. The program is much like the "unpit" program for
- breaking apart Packit archive files.
-
- ***** IMPORTANT *****
- To extract StuffIt files that have been compressed with the Lempel-Ziv
- compression method, unsit pipes the data through the "compress"
- program with the appropriate switches, rather than incorporate the
- uncompression routines within "unsit". Therefore, it is necessary to
- have the "compress" program on the system and in the search path to
- make "unsit" work. "Compress" is available from the comp.sources.unix
- archives.
-
- The program syntax is much like unpit and macput/macget, with some added
- options:
-
- unsit [-rdulvqfm] stuffit-file.data
-
- The -r and -d flags will cause only the resource and data forks to be
- written. The -u flag will cause only the data fork to be written and
- to have carriage return characters changed to Unix newline characters.
- The -l flag will make the program only list the files in the StuffIt
- file. The -v flag causes the program to list the names, sizes, type,
- and creators of the files it is writing. The -q flag causes it to
- list the name, type and size of each file and wait for a 'y' or 'n'
- for either writing that file or skipping it, respectively. The -m
- flag is used when the input file in in the MacBinary format instead of
- three separate .data, .info, and .rsrc files. It causes the program
- to skip the 128 byte MacBinary header before looking for the StuffIt
- header.
-
- Version 1.5 of the unsit supports extracting files and folders as
- implemented by StuffIt 1.5's "Hierarchy Maintained Folder" feature.
- Each folder is extracted as a subdirectory on the Unix system with the
- files in the folder placed in the corresponding subdirectory. The -f
- option can be used to "flatten" out the hierarchy and unsit will store
- all the files in the current directory. If the query option (-q) is
- used and a "n" response is given to a folder name, none of the files
- or folders in that folder will be extraced.
-
- Some of the program is borrowed from the macput.c/macget.c programs.
- Many, many thanks to Raymond Lau, the author of StuffIt, for including
- information on the format of the StuffIt archives in the
- documentation. Several changes and enhancements supplied by David
- Shanks (cde@atelabs.UUCP) have been incorporated into the program for
- doing things like supporting System V and recognizing MacBinary files.
- I'm always glad to receive advice, suggestions, or comments about the
- program so feel free to send whatever you think would be helpful
-
-
- Author: Allan G. Weber
- weber%brand.usc.edu@oberon.usc.edu
- ...sdcrdcf!usc-oberon!brand!weber
- Date: April 3, 1989
-
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- typedef long OSType;
-
- #include "stuffit.h"
-
- /*
- * Define the following if your Unix can only handle 14 character file names
- * (e.g. Version 7 and System V).
- */
- /* #define SHORTNAMES */
-
- /*
- * The following defines the name of the compress program that is used for the
- * uncompression of Lempel-Ziv compressed files. If the path is set up to
- * include the right directory, this should work.
- */
- #define COMPRESS "compress"
-
- #define IOBUFSIZ 4096
-
- #define MACBINHDRSIZE 128L
-
- #define INIT_CRC 0L
- extern unsigned short updcrc();
-
- #define INFOBYTES 128
-
- #define BYTEMASK 0xff
-
- #define S_SIGNATURE 0
- #define S_NUMFILES 4
- #define S_ARCLENGTH 6
- #define S_SIGNATURE2 10
- #define S_VERSION 14
- #define SITHDRSIZE 22
-
- #define F_COMPRMETHOD 0
- #define F_COMPDMETHOD 1
- #define F_FNAME 2
- #define F_FTYPE 66
- #define F_CREATOR 70
- #define F_FNDRFLAGS 74
- #define F_CREATIONDATE 76
- #define F_MODDATE 80
- #define F_RSRCLENGTH 84
- #define F_DATALENGTH 88
- #define F_COMPRLENGTH 92
- #define F_COMPDLENGTH 96
- #define F_RSRCCRC 100
- #define F_DATACRC 102
- #define F_HDRCRC 110
- #define FILEHDRSIZE 112
-
- #define F_NAMELEN 63
- #ifdef SHORTNAMES /* short file names */
- # define I_NAMELEN 15 /* 14 char file names + '\0' terminator */
- #else
- # define I_NAMELEN 69 /* 63 + strlen(".info") + 1 */
- #endif
-
- /* The following are copied out of macput.c/macget.c */
- #define I_NAMEOFF 1
- /* 65 <-> 80 is the FInfo structure */
- #define I_TYPEOFF 65
- #define I_AUTHOFF 69
- #define I_FLAGOFF 73
- #define I_LOCKOFF 81
- #define I_DLENOFF 83
- #define I_RLENOFF 87
- #define I_CTIMOFF 91
- #define I_MTIMOFF 95
-
- #define INITED_BUG
- #define INITED_OFF I_FLAGOFF /* offset to byte with Inited flag */
- #define INITED_MASK (~1) /* mask to '&' with byte to reset it */
-
- #define TEXT 0
- #define DATA 1
- #define RSRC 2
- #define FULL 3
- #define DUMP 4
-
- #define NODECODE 0
- #define DECODE 1
-
- #define H_ERROR -1
- #define H_EOF 0
- #define H_WRITE 1
- #define H_SKIP 2
-
- struct node {
- int flag, byte;
- struct node *one, *zero;
- } nodelist[512], *nodeptr, *read_tree(); /* 512 should be big enough */
-
- struct sitHdr sithdr;
-
- char f_info[I_NAMELEN];
- char f_data[I_NAMELEN];
- char f_rsrc[I_NAMELEN];
-
- char info[INFOBYTES];
- char mname[F_NAMELEN+1];
- char uname[F_NAMELEN+1];
- char iobuf[IOBUFSIZ];
-
- int mode, txtmode, listonly, verbose, query, flatten;
- int bit, chkcrc, numfiles, depth;
- FILE *infp;
-
- long get4();
- short get2();
- unsigned short write_file();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int status;
- int c;
- extern int optind;
- extern char *optarg;
- int errflg;
- int macbin;
-
- mode = FULL;
- errflg = 0;
- macbin = 0;
- flatten = 0;
- numfiles = 0;
- depth = 0;
-
- while ((c = getopt(argc, argv, "dflmqruvx")) != EOF)
- switch (c) {
- case 'r':
- mode = RSRC;
- break;
- case 'd':
- mode = DATA;
- break;
- case 'u':
- mode = TEXT;
- break;
- case 'l':
- listonly++;
- break;
- case 'q':
- query++;
- break;
- case 'v':
- verbose++;
- break;
- case 'x':
- mode = DUMP;
- break;
- case 'm':
- macbin = 1;
- break;
- case 'f':
- flatten = 1;
- break;
- case '?':
- errflg++;
- break;
- }
- if (errflg) {
- usage();
- exit(1);
- }
-
- if (optind == argc) {
- usage();
- exit(1);
- }
- else {
- if ((infp = fopen(argv[optind], "r")) == NULL) {
- fprintf(stderr,"Can't open input file \"%s\"\n",argv[optind]);
- exit(1);
- }
- }
-
- if (macbin) {
- if (fseek(infp, MACBINHDRSIZE, 0) == -1) {
- fprintf(stderr, "Can't skip over MacBinary header\n");
- exit(1);
- }
- }
-
- if (readsithdr(&sithdr) == 0) {
- fprintf(stderr, "Can't read file header\n");
- exit(1);
- }
- /*
- printf("numfiles=%d, arclength=%ld\n", sithdr.numFiles, sithdr.arcLength);
- */
-
- status = extract("", 0);
- exit((status < 0) ? 1 : 0);
- }
-
- usage()
- {
- fprintf(stderr, "Usage: unsit [-rdulvqmf] filename\n");
- }
-
- /*
- extract(parent, skip) - Extract all files from the current folder.
- char *parent; name of parent folder
- int skip; 1 to skip all files and folders in this one
- 0 to extract them
-
- returns 1 if came an endFolder record
- 0 if EOF
- -1 if error (bad fileHdr, bad file, etc.)
- */
-
- extract(parent, skip)
- char *parent;
- int skip;
- {
- struct fileHdr filehdr;
- struct stat sbuf;
- int status, rstat, sstat, skipit;
- char name[256];
-
- while (1) {
- rstat = readfilehdr(&filehdr, skip);
- if (rstat == H_ERROR || rstat == H_EOF) {
- status = rstat;
- break;
- }
- /*
- printf("compr=%d, compd=%d, rsrclen=%ld, datalen=%ld, rsrccrc=%d, datacrc=%d\n",
- filehdr.compRMethod, filehdr.compDMethod,
- filehdr.compRLength, filehdr.compDLength,
- filehdr.rsrcCRC, filehdr.dataCRC);
- */
-
- skipit = (rstat == H_SKIP) ? 1 : 0;
-
- if (filehdr.compRMethod == endFolder &&
- filehdr.compDMethod == endFolder) {
- status = 1; /* finished with this folder */
- break;
- }
- else if (filehdr.compRMethod == startFolder &&
- filehdr.compDMethod == startFolder) {
- if (!listonly && rstat == H_WRITE && !flatten) {
- sstat = stat(uname, &sbuf);
- if (sstat == -1) { /* directory doesn't exist */
- if (mkdir(uname, 0777) == -1) {
- fprintf(stderr,
- "Can't create subdirectory %s\n", uname);
- return(-1);
- }
- }
- else { /* something exists with this name */
- if ((sbuf.st_mode & S_IFMT) != S_IFDIR) {
- fprintf(stderr, "Directory name %s already in use\n",
- uname);
- return(-1);
- }
- }
- if (chdir(uname) == -1) {
- fprintf(stderr, "Can't chdir to %s\n", uname);
- return(-1);
- }
- sprintf(name,"%s:%s", parent, uname);
- }
- depth++;
- status = extract(name, skipit);
- depth--;
- if (status != 1)
- break; /* problem with folder */
- if (depth == 0) /* count how many top-level files done */
- numfiles++;
- if (!flatten)
- chdir("..");
- }
- else {
- if ((status = extractfile(&filehdr, skipit)) != 1)
- break;
- if (depth == 0) /* count how many top-level files done */
- numfiles++;
- }
- if (numfiles == sithdr.numFiles)
- break;
- }
- return(status);
- }
-
- extractfile(fh, skip)
- struct fileHdr *fh;
- int skip;
- {
- unsigned short crc;
- FILE *fp;
-
- f_data[0] = f_rsrc[0] = f_info[0] = '\0'; /* assume no output files */
- /* figure out what file names to use and what to do */
- if (!listonly && !skip) {
- switch (mode) {
- case FULL: /* do both rsrc and data forks */
- sprintf(f_data, "%.*s.data", I_NAMELEN - 6, uname);
- sprintf(f_rsrc, "%.*s.rsrc", I_NAMELEN - 6, uname);
- sprintf(f_info, "%.*s.info", I_NAMELEN - 6, uname);
- break;
- case RSRC: /* rsrc fork only */
- sprintf(f_rsrc, "%.*s.rsrc", I_NAMELEN - 6, uname);
- break;
- case DATA: /* data fork only */
- case TEXT:
- sprintf(f_data, "%.*s", I_NAMELEN - 1, uname);
- break;
- case DUMP: /* for debugging, dump data as is */
- sprintf(f_data, "%.*s.ddump", I_NAMELEN - 7, uname);
- sprintf(f_rsrc, "%.*s.rdump", I_NAMELEN - 7, uname);
- fh->compRMethod = fh->compDMethod = noComp;
- break;
- }
- }
-
- if (f_info[0] != '\0' && check_access(f_info) != -1) {
- fp = fopen(f_info, "w");
- if (fp == NULL) {
- perror(f_info);
- exit(1);
- }
- fwrite(info, 1, INFOBYTES, fp);
- fclose(fp);
- }
-
- if (f_rsrc[0] != '\0') {
- txtmode = 0;
- crc = write_file(f_rsrc, fh->compRLength,
- fh->rsrcLength, fh->compRMethod);
- if (chkcrc && fh->rsrcCRC != crc) {
- fprintf(stderr,
- "CRC error on resource fork: need 0x%04x, got 0x%04x\n",
- fh->rsrcCRC, crc);
- return(-1);
- }
- }
- else {
- fseek(infp, (long) fh->compRLength, 1);
- }
- if (f_data[0] != '\0') {
- txtmode = (mode == TEXT);
- crc = write_file(f_data, fh->compDLength,
- fh->dataLength, fh->compDMethod);
- if (chkcrc && fh->dataCRC != crc) {
- fprintf(stderr,
- "CRC error on data fork: need 0x%04x, got 0x%04x\n",
- fh->dataCRC, crc);
- return(-1);
- }
- }
- else {
- fseek(infp, (long) fh->compDLength, 1);
- }
- return(1);
- }
-
- readsithdr(s)
- struct sitHdr *s;
- {
- char temp[FILEHDRSIZE];
- int count = 0;
-
- for (;;) {
- if (fread(temp, 1, SITHDRSIZE, infp) != SITHDRSIZE) {
- fprintf(stderr, "Can't read file header\n");
- return(0);
- }
-
- if (strncmp(temp + S_SIGNATURE, "SIT!", 4) == 0 &&
- strncmp(temp + S_SIGNATURE2, "rLau", 4) == 0) {
- s->numFiles = get2(temp + S_NUMFILES);
- s->arcLength = get4(temp + S_ARCLENGTH);
- return(1);
- }
-
- if (++count == 2) {
- fprintf(stderr, "Not a StuffIt file\n");
- return(0);
- }
-
- if (fread(&temp[SITHDRSIZE], 1, FILEHDRSIZE - SITHDRSIZE, infp) !=
- FILEHDRSIZE - SITHDRSIZE) {
- fprintf(stderr, "Can't read file header\n");
- return(0);
- }
-
- if (strncmp(temp + I_TYPEOFF, "SIT!", 4) == 0 &&
- strncmp(temp + I_AUTHOFF, "SIT!", 4) == 0) { /* MacBinary format */
- fseek(infp, (long)(INFOBYTES-FILEHDRSIZE), 1); /* Skip over header */
- }
- }
- }
-
- /*
- readfilehdr - reads the file header for each file and the folder start
- and end records.
-
- returns: H_ERROR = error
- H_EOF = EOF
- H_WRITE = write file/folder
- H_SKIP = skip file/folder
- */
-
- readfilehdr(f, skip)
- struct fileHdr *f;
- int skip;
- {
- unsigned short crc;
- int i, n, write_it, isfolder;
- char hdr[FILEHDRSIZE];
- char ch, *mp, *up;
- char *tp, temp[10];
-
- for (i = 0; i < INFOBYTES; i++)
- info[i] = '\0';
-
- /* read in the next file header, which could be folder start/end record */
- n = fread(hdr, 1, FILEHDRSIZE, infp);
- if (n == 0) /* return 0 on EOF */
- return(H_EOF);
- else if (n != FILEHDRSIZE) {
- fprintf(stderr, "Can't read file header\n");
- return(H_ERROR);
- }
-
- /* check the CRC for the file header */
- crc = INIT_CRC;
- crc = updcrc(crc, hdr, FILEHDRSIZE - 2);
- f->hdrCRC = get2(hdr + F_HDRCRC);
- if (f->hdrCRC != crc) {
- fprintf(stderr, "Header CRC mismatch: got 0x%04x, need 0x%04x\n",
- f->hdrCRC, crc);
- return(H_ERROR);
- }
-
- /* grab the name of the file or folder */
- n = hdr[F_FNAME] & BYTEMASK;
- if (n > F_NAMELEN)
- n = F_NAMELEN;
- info[I_NAMEOFF] = n;
- copy(info + I_NAMEOFF + 1, hdr + F_FNAME + 1, n);
- strncpy(mname, hdr + F_FNAME + 1, n);
- mname[n] = '\0';
- /* copy to a string with no illegal Unix characters in the file name */
- mp = mname;
- up = uname;
- while ((ch = *mp++) != '\0') {
- if (ch <= ' ' || ch > '~' || index("/!()[]*<>?\\\"$\';&`", ch) != NULL)
- ch = '_';
- *up++ = ch;
- }
- *up = '\0';
-
- /* get lots of other stuff from the header */
- f->compRMethod = hdr[F_COMPRMETHOD];
- f->compDMethod = hdr[F_COMPDMETHOD];
- f->rsrcLength = get4(hdr + F_RSRCLENGTH);
- f->dataLength = get4(hdr + F_DATALENGTH);
- f->compRLength = get4(hdr + F_COMPRLENGTH);
- f->compDLength = get4(hdr + F_COMPDLENGTH);
- f->rsrcCRC = get2(hdr + F_RSRCCRC);
- f->dataCRC = get2(hdr + F_DATACRC);
-
- /* if it's an end folder record, don't need to do any more */
- if (f->compRMethod == endFolder && f->compDMethod == endFolder)
- return(H_WRITE);
-
- /* prepare an info file in case its needed */
-
- copy(info + I_TYPEOFF, hdr + F_FTYPE, 4);
- copy(info + I_AUTHOFF, hdr + F_CREATOR, 4);
- copy(info + I_FLAGOFF, hdr + F_FNDRFLAGS, 2);
- #ifdef INITED_BUG
- info[INITED_OFF] &= INITED_MASK; /* reset init bit */
- #endif
- copy(info + I_DLENOFF, hdr + F_DATALENGTH, 4);
- copy(info + I_RLENOFF, hdr + F_RSRCLENGTH, 4);
- copy(info + I_CTIMOFF, hdr + F_CREATIONDATE, 4);
- copy(info + I_MTIMOFF, hdr + F_MODDATE, 4);
-
- isfolder = f->compRMethod == startFolder && f->compDMethod == startFolder;
-
- /* list the file name if verbose or listonly mode, also if query mode */
- if (skip) /* skip = 1 if skipping all in this folder */
- write_it = 0;
- else {
- write_it = 1;
- if (listonly || verbose || query) {
- for (i = 0; i < depth; i++)
- putchar(' ');
- if (isfolder)
- printf("Folder: \"%s\"", uname);
- else
- printf("name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
- uname, hdr + F_FTYPE, hdr + F_CREATOR,
- f->dataLength, f->rsrcLength);
- if (query) { /* if querying, check with the boss */
- printf(" ? ");
- fgets(temp, sizeof(temp) - 1, stdin);
- tp = temp;
- write_it = 0;
- while (*tp != '\0') {
- if (*tp == 'y' || *tp == 'Y') {
- write_it = 1;
- break;
- }
- else
- tp++;
- }
- }
- else /* otherwise, terminate the line */
- putchar('\n');
- }
- }
- return(write_it ? H_WRITE : H_SKIP);
- }
-
- check_access(fname) /* return 0 if OK to write on file fname, -1 otherwise */
- char *fname;
- {
- char temp[10], *tp;
-
- if (access(fname, 0) == -1) {
- return(0);
- }
- else {
- printf("%s exists. Overwrite? ", fname);
- fgets(temp, sizeof(temp) - 1, stdin);
- tp = temp;
- while (*tp != '\0') {
- if (*tp == 'y' || *tp == 'Y') {
- return(0);
- }
- else
- tp++;
- }
- }
- return(-1);
- }
-
- unsigned short write_file(fname, ibytes, obytes, type)
- char *fname;
- unsigned long ibytes, obytes;
- unsigned char type;
- {
- unsigned short crc;
- int i, n, ch, lastch;
- FILE *outf;
- char temp[256];
-
- crc = INIT_CRC;
- chkcrc = 1; /* usually can check the CRC */
-
- if (check_access(fname) == -1) {
- fseek(infp, ibytes, 1);
- chkcrc = 0; /* inhibit crc check if file not written */
- return(-1);
- }
-
- switch (type) {
- case noComp: /* no compression */
- outf = fopen(fname, "w");
- if (outf == NULL) {
- perror(fname);
- exit(1);
- }
- while (ibytes > 0) {
- n = (ibytes > IOBUFSIZ) ? IOBUFSIZ : ibytes;
- n = fread(iobuf, 1, n, infp);
- if (n == 0)
- break;
- crc = updcrc(crc, iobuf, n);
- outc(iobuf, n, outf);
- ibytes -= n;
- }
- fclose(outf);
- break;
- case rleComp: /* run length encoding */
- outf = fopen(fname, "w");
- if (outf == NULL) {
- perror(fname);
- exit(1);
- }
- while (ibytes > 0) {
- ch = getc(infp) & 0xff;
- ibytes--;
- if (ch == 0x90) { /* see if its the repeat marker */
- n = getc(infp) & 0xff; /* get the repeat count */
- ibytes--;
- if (n == 0) { /* 0x90 was really an 0x90 */
- iobuf[0] = 0x90;
- crc = updcrc(crc, iobuf, 1);
- outc(iobuf, 1, outf);
- }
- else {
- n--;
- for (i = 0; i < n; i++)
- iobuf[i] = lastch;
- crc = updcrc(crc, iobuf, n);
- outc(iobuf, n, outf);
- }
- }
- else {
- iobuf[0] = ch;
- crc = updcrc(crc, iobuf, 1);
- lastch = ch;
- outc(iobuf, 1, outf);
- }
- }
- fclose(outf);
- break;
- case lzwComp: /* LZW compression */
- sprintf(temp, "%s%s", COMPRESS, " -d -c -n -b 14 ");
- if (txtmode) {
- strcat(temp, "| tr \'\\015\' \'\\012\' ");
- chkcrc = 0; /* can't check CRC in this case */
- }
- strcat(temp, "> '");
- strcat(temp, fname);
- strcat(temp, "'");
- outf = popen(temp, "w");
- if (outf == NULL) {
- perror(fname);
- exit(1);
- }
- while (ibytes > 0) {
- n = (ibytes > IOBUFSIZ) ? IOBUFSIZ : ibytes;
- n = fread(iobuf, 1, n, infp);
- if (n == 0)
- break;
- fwrite(iobuf, 1, n, outf);
- ibytes -= n;
- }
- pclose(outf);
- if (chkcrc) {
- outf = fopen(fname, "r"); /* read the file to get CRC value */
- if (outf == NULL) {
- perror(fname);
- exit(1);
- }
- while (1) {
- n = fread(iobuf, 1, IOBUFSIZ, outf);
- if (n == 0)
- break;
- crc = updcrc(crc, iobuf, n);
- }
- fclose(outf);
- }
- break;
- case hufComp: /* Huffman compression */
- outf = fopen(fname, "w");
- if (outf == NULL) {
- perror(fname);
- exit(1);
- }
- nodeptr = nodelist;
- bit = 0; /* put us on a byte boundary */
- read_tree();
- while (obytes > 0) {
- n = (obytes > IOBUFSIZ) ? IOBUFSIZ : obytes;
- for (i = 0; i < n; i++)
- iobuf[i] = gethuffbyte(DECODE);
- crc = updcrc(crc, iobuf, n);
- outc(iobuf, n, outf);
- obytes -= n;
- }
- fclose(outf);
- break;
- default:
- fprintf(stderr, "Unknown compression method\n");
- chkcrc = 0; /* inhibit crc check if file not written */
- return(-1);
- }
-
- return(crc & 0xffff);
- }
-
- outc(p, n, fp)
- char *p;
- int n;
- FILE *fp;
- {
- register char *p1;
- register int i;
- if (txtmode) {
- for (i = 0, p1 = p; i < n; i++, p1++)
- if ((*p1 & BYTEMASK) == '\r')
- *p1 = '\n';
- }
- fwrite(p, 1, n, fp);
- }
-
- long get4(bp)
- char *bp;
- {
- register int i;
- long value = 0;
-
- for (i = 0; i < 4; i++) {
- value <<= 8;
- value |= (*bp & BYTEMASK);
- bp++;
- }
- return(value);
- }
-
- short get2(bp)
- char *bp;
- {
- register int i;
- int value = 0;
-
- for (i = 0; i < 2; i++) {
- value <<= 8;
- value |= (*bp & BYTEMASK);
- bp++;
- }
- return(value);
- }
-
- copy(p1, p2, n)
- char *p1, *p2;
- int n;
- {
- while (n-- > 0)
- *p1++ = *p2++;
- }
-
- /* This routine recursively reads the Huffman encoding table and builds
- and decoding tree. */
-
- struct node *read_tree()
- {
- struct node *np;
- np = nodeptr++;
- if (getbit() == 1) {
- np->flag = 1;
- np->byte = gethuffbyte(NODECODE);
- }
- else {
- np->flag = 0;
- np->zero = read_tree();
- np->one = read_tree();
- }
- return(np);
- }
-
- /* This routine returns the next bit in the input stream (MSB first) */
-
- getbit()
- {
- static char b;
- if (bit == 0) {
- b = getc(infp) & 0xff;
- bit = 8;
- }
- bit--;
- return((b >> bit) & 1);
- }
-
- /* This routine returns the next 8 bits. If decoding is on, it finds the
- byte in the decoding tree based on the bits from the input stream. If
- decoding is not on, it either gets it directly from the input stream or
- puts it together from 8 calls to getbit(), depending on whether or not we
- are currently on a byte boundary
- */
- gethuffbyte(decode)
- int decode;
- {
- register struct node *np;
- register int i, b;
- if (decode == DECODE) {
- np = nodelist;
- while (np->flag == 0)
- np = (getbit()) ? np->one : np->zero;
- b = np->byte;
- }
- else {
- if (bit == 0) /* on byte boundary? */
- b = getc(infp) & 0xff;
- else { /* no, put a byte together */
- b = 0;
- for (i = 8; i > 0; i--) {
- b = (b << 1) + getbit();
- }
- }
- }
- return(b);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'stuffit.h'
- then
- echo shar: will not over-write existing file "'stuffit.h'"
- else
- cat << \SHAR_EOF > 'stuffit.h'
- /* StuffIt.h: contains declarations for SIT headers */
-
- typedef struct sitHdr { /* 22 bytes */
- OSType signature; /* = 'SIT!' -- for verification */
- unsigned short numFiles; /* number of files in archive */
- unsigned long arcLength; /* length of entire archive incl.
- hdr. -- for verification */
- OSType signature2; /* = 'rLau' -- for verification */
- unsigned char version; /* version number */
- char reserved[7];
- };
-
- typedef struct fileHdr { /* 112 bytes */
- unsigned char compRMethod; /* rsrc fork compression method */
- unsigned char compDMethod; /* data fork compression method */
- unsigned char fName[64]; /* a STR63 */
- OSType fType; /* file type */
- OSType fCreator; /* er... */
- short FndrFlags; /* copy of Finder flags. For our
- purposes, we can clear:
- busy,onDesk */
- unsigned long creationDate;
- unsigned long modDate; /* !restored-compat w/backup prgms */
- unsigned long rsrcLength; /* decompressed lengths */
- unsigned long dataLength;
- unsigned long compRLength; /* compressed lengths */
- unsigned long compDLength;
- unsigned short rsrcCRC; /* crc of rsrc fork */
- unsigned short dataCRC; /* crc of data fork */
- char reserved[6];
- unsigned short hdrCRC; /* crc of file header */
- };
-
-
- /* file format is:
- sitArchiveHdr
- file1Hdr
- file1RsrcFork
- file1DataFork
- file2Hdr
- file2RsrcFork
- file2DataFork
- .
- .
- .
- fileNHdr
- fileNRsrcFork
- fileNDataFork
- */
-
-
-
- /* compression methods */
- #define noComp 0 /* just read each byte and write it to archive */
- #define rleComp 1 /* RLE compression */
- #define lzwComp 2 /* LZW compression */
- #define hufComp 3 /* Huffman compression */
-
- #define encrypted 16 /* bit set if encrypted. ex: encrypted+lpzComp */
-
- #define startFolder 32 /* marks start of a new folder */
- #define endFolder 33 /* marks end of the last folder "started" */
-
- /* all other numbers are reserved */
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'updcrc.c'
- then
- echo shar: will not over-write existing file "'updcrc.c'"
- else
- cat << \SHAR_EOF > 'updcrc.c'
- /* updcrc(3), crc(1) - calculate crc polynomials
- *
- * Calculate, intelligently, the CRC of a dataset incrementally given a
- * buffer full at a time.
- *
- * Usage:
- * newcrc = updcrc( oldcrc, bufadr, buflen )
- * unsigned int oldcrc, buflen;
- * char *bufadr;
- *
- * Compiling with -DTEST creates a program to print the CRC of stdin to stdout.
- * Compile with -DMAKETAB to print values for crctab to stdout. If you change
- * the CRC polynomial parameters, be sure to do this and change
- * crctab's initial value.
- *
- * Notes:
- * Regards the data stream as an integer whose MSB is the MSB of the first
- * byte recieved. This number is 'divided' (using xor instead of subtraction)
- * by the crc-polynomial P.
- * XMODEM does things a little differently, essentially treating the LSB of
- * the first data byte as the MSB of the integer. Define SWAPPED to make
- * things behave in this manner.
- *
- * Author: Mark G. Mendel, 7/86
- * UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm
- */
-
- /* The CRC polynomial.
- * These 4 values define the crc-polynomial.
- * If you change them, you must change crctab[]'s initial value to what is
- * printed by initcrctab() [see 'compile with -DMAKETAB' above].
- */
- /* Value used by: CITT XMODEM ARC */
- #define P 0xA001 /* the poly: 0x1021 0x1021 A001 */
- #define INIT_CRC 0L /* init value: -1 0 0 */
- #define SWAPPED /* bit order: undef defined defined */
- #define W 16 /* bits in CRC:16 16 16 */
-
- /* data type that holds a W-bit unsigned integer */
- #if W <= 16
- # define WTYPE unsigned short
- #else
- # define WTYPE unsigned long
- #endif
-
- /* the number of bits per char: don't change it. */
- #define B 8
-
- static WTYPE crctab[1<<B] = /* as calculated by initcrctab() */ {
- 0x0, 0xc0c1, 0xc181, 0x140, 0xc301, 0x3c0, 0x280, 0xc241,
- 0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440,
- 0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40,
- 0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841,
- 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
- 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
- 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
- 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
- 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
- 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
- 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
- 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
- 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
- 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
- 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
- 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
- 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
- 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
- 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
- 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
- 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
- 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
- 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
- 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
- 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
- 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
- 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
- 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
- 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
- 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
- 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
- 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
- } ;
-
- WTYPE
- updcrc( icrc, icp, icnt )
- WTYPE icrc;
- unsigned char *icp;
- int icnt;
- {
- register WTYPE crc = icrc;
- register unsigned char *cp = icp;
- register int cnt = icnt;
-
- while( cnt-- ) {
- #ifndef SWAPPED
- crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
- #else
- crc = (crc>>B) ^ crctab[(crc & ((1<<B)-1)) ^ *cp++];
- #endif SWAPPED
- }
-
- return( crc );
- }
-
- #ifdef MAKETAB
-
- #include <stdio.h>
- main()
- {
- initcrctab();
- }
-
- initcrctab()
- {
- register int b, i;
- WTYPE v;
-
-
- for( b = 0; b <= (1<<B)-1; ++b ) {
- #ifndef SWAPPED
- for( v = b<<(W-B), i = B; --i >= 0; )
- v = v & ((WTYPE)1<<(W-1)) ? (v<<1)^P : v<<1;
- #else
- for( v = b, i = B; --i >= 0; )
- v = v & 1 ? (v>>1)^P : v>>1;
- #endif
- crctab[b] = v;
-
- printf( "0x%lx,", v & ((1L<<W)-1L));
- if( (b&7) == 7 )
- printf("\n" );
- else
- printf(" ");
- }
- }
- #endif
-
- #ifdef TEST
-
- #include <stdio.h>
- #include <fcntl.h>
-
- #define MAXBUF 4096
-
-
-
- main( ac, av )
- int ac; char **av;
- {
- int fd;
- int nr;
- int i;
- char buf[MAXBUF];
- WTYPE crc, crc2;
-
- fd = 0;
- if( ac > 1 )
- if( (fd = open( av[1], O_RDONLY )) < 0 ) {
- perror( av[1] );
- exit( -1 );
- }
- crc = crc2 = INIT_CRC;
-
- while( (nr = read( fd, buf, MAXBUF )) > 0 ) {
- crc = updcrc( crc, buf, nr );
- }
-
- if( nr != 0 )
- perror( "reading" );
- else {
- printf( "%lx\n", crc );
- }
-
- #ifdef MAGICCHECK
- /* tack one's complement of crc onto data stream, and
- continue crc calculation. Should get a constant (magic number)
- dependent only on P, not the data.
- */
- crc2 = crc ^ -1L;
- for( nr = W-B; nr >= 0; nr -= B ) {
- buf[0] = (crc2 >> nr);
- crc = updcrc(crc, buf, 1);
- }
-
- /* crc should now equal magic */
- buf[0] = buf[1] = buf[2] = buf[3] = 0;
- printf( "magic test: %lx =?= %lx\n", crc, updcrc(-1, buf, W/B));
- #endif MAGICCHECK
- }
-
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'getopt.c'
- then
- echo shar: will not over-write existing file "'getopt.c'"
- else
- cat << \SHAR_EOF > 'getopt.c'
- /*
- * getopt - get option letter from argv
- */
-
- #include <stdio.h>
-
- char *optarg; /* Global argument pointer. */
- int optind = 0; /* Global argv index. */
-
- static char *scan = NULL; /* Private scan pointer. */
-
- extern char *index();
-
- int
- getopt(argc, argv, optstring)
- int argc;
- char *argv[];
- char *optstring;
- {
- register char c;
- register char *place;
-
- optarg = NULL;
-
- if (scan == NULL || *scan == '\0') {
- if (optind == 0)
- optind++;
-
- if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(EOF);
- if (strcmp(argv[optind], "--")==0) {
- optind++;
- return(EOF);
- }
-
- scan = argv[optind]+1;
- optind++;
- }
-
- c = *scan++;
- place = index(optstring, c);
-
- if (place == NULL || c == ':') {
- fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
- return('?');
- }
-
- place++;
- if (*place == ':') {
- if (*scan != '\0') {
- optarg = scan;
- scan = NULL;
- } else if (optind < argc) {
- optarg = argv[optind];
- optind++;
- } else {
- fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
- return('?');
- }
- }
-
- return(c);
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'unsit.1'
- then
- echo shar: will not over-write existing file "'unsit.1'"
- else
- cat << \SHAR_EOF > 'unsit.1'
- .TH UNSIT L "Septermber 28, 1988"
- .UC
- .SH NAME
- unsit \- extract/list files in a Macintosh Stuffit archive file
- .SH SYNOPSIS
- .B unsit
- [
- .B \-dflmqruv
- ] file
- .br
- .SH DESCRIPTION
- For the Stuffit archive file listed,
- .I unsit
- extracts the files in the archive into separate files.
- This makes it possible, for example, to separate a large StuffIt file
- into component files for selective downloading, rather than
- downloading the larger archive file just to extract a single, small
- file. It also allows the use of StuffIt to compress a group of files
- into a single, smaller archive that can be uploaded to a Unix system
- for storage, printing, etc.
- .PP
- In the normal mode, both the data and the resource forks of the
- component Macintosh files in the archive are extracted and stored in
- Unix files with the extension
- .I .data
- and
- .I .rsrc
- appended to the end of the Macintosh file name.
- In addition, a
- .I .info
- file will be created with the Finder information.
- These three file are compatible with the
- .I macput
- program for downloading to a Mac running Macterminal.
- If only the data or resource fork is extracted, no addition extension is
- appended to the Mac file name.
- Characters in the Mac file name that are illegal (or unwieldy, like spaces)
- are changed to underscores in the Unix file name. The true Mac file name
- is retained in the
- .I .info
- file and is restored when the file is downloaded.
- .PP
- StuffIt version 1.5 has the ability to archive a group of files and folders
- in such a way that the hierarchical relationship of the files and folders
- is maintained.
- .I Unsit
- version 1.5 can unpack files archived in this manner and place them in
- corresponding subdirectories so as to maintain the hierarchy. As an option,
- the hierarcy can be flattened out and all the files stored in the current
- directory.
- .PP
- The options are similar to those for
- .I macput
- and
- .I unpit.
- .TP
- .B \-f
- For StuffIt files containing a "Hierarchy Maintained Folder" entry, extract the
- files into a "flat" organization (all in the current directory) rather than
- maintaining the hierarchy by creating new directories, etc.
- Default is to maintain the hierarchical folder organization.
- .TP
- .B \-l
- List the files in the archive but do not extract them. The name, size,
- type, and creator of each file is listed.
- .TP
- .B \-m
- Assumes the input file in MacBinary format rather than macput/macget
- format and skips over the MacBinary header.
- .TP
- .B \-r
- Extract resources forks only.
- .TP
- .B \-d
- Extract data forks only.
- .TP
- .B \-u
- Extract data fork and change into a Unix text file.
- This only works if the file is really a text file.
- .TP
- .B \-q
- Query user before extracting files and folders. If a "n" answer is given for
- a folder, none of the files or folders in that folder will be extracted.
- .TP
- .B \-v
- Verbose option. Causes
- .I unsit
- to list name, size, type, and creator of each file extracted.
- .SH BUGS
- Files that were compressed by StuffIt with the Lempel-Ziv method and are
- extracted with the
- .B \-u
- switch (text files) are not checked for a correct CRC value when
- .I unsit
- uncompresses them. This is because
- .I unsit
- pipes the data through
- .I compress
- and
- .I tr
- to extract the file and never has a chance to do the CRC check.
- .PP
- The
- .I compress
- program has been observed to go into strange states when uncompressing a
- damaged file. Often it will get stuck writing out bogus data until the
- disk fills up. Since
- .I unsit
- sends data through
- .I compress,
- the same problem could occur when extracting files from a damaged Stuffit
- archive.
- .SH FILES
- For archives that have been compressed with the Lempel-Ziv method, the
- .I compress
- program must be present on the system and in the search path since
- .I unsit
- uses it for the uncompressing.
- .I Compress
- is available from the comp.sources.unix archives.
- .SH AUTHOR
- Allan G. Weber (weber%brand.usc.edu@oberon.usc.edu)
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-
-