home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
unix
/
unsit.shr
< prev
next >
Wrap
Text File
|
1989-05-15
|
25KB
|
1,010 lines
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by rascal!werner on Thu Nov 3 19:33:40 CST 1988
# Contents: unsit.1 unsit.c unsit.h
echo x - unsit.1
sed 's/^@//' > "unsit.1" <<'@//E*O*F unsit.1//'
@.TH UNSIT L "January 15, 1988"
@.UC
@.SH NAME
unsit \- extract/list files in a Macintosh Stuffit archive file
@.SH SYNOPSIS
@.B unsit
[
@.B \-dlqruv
] file
@.br
@.SH DESCRIPTION
For the Stuffit archive file listed,
@.I unsit
extracts the files in 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
The options are similar to those for
@.I macput
and
@.I unpit.
@.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 \-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.
@.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)
@//E*O*F unsit.1//
chmod u=rw,g=r,o=r unsit.1
echo x - unsit.c
sed 's/^@//' > "unsit.c" <<'@//E*O*F unsit.c//'
/*
unsit - Macintosh StuffIt file extractor
Version 1, for StuffIt 1.31
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 [-rdulvq] 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.
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.
Author: Allan G. Weber
weber%brand.usc.edu@oberon.usc.edu
...sdcrdcf!usc-oberon!brand!weber
Date: January 15, 1988
*/
#include <stdio.h>
typedef long OSType;
#include "unsit.h"
/*
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 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
#define I_NAMELEN 69 /* 63 + strlen(".info") + 1 */
/* 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
struct node {
int flag, byte;
struct node *one, *zero;
} nodelist[512], *nodeptr, *read_tree(); /* 512 should be big enough */
char f_info[I_NAMELEN];
char f_data[I_NAMELEN];
char f_rsrc[I_NAMELEN];
char info[INFOBYTES];
char text[F_NAMELEN+1];
char iobuf[IOBUFSIZ];
int mode, txtmode, listonly, verbose, query;
int bit, chkcrc;
FILE *infp;
long get4();
short get2();
unsigned short write_file();
main(argc, argv)
int argc;
char *argv[];
{
unsigned short crc;
int i, n;
char c;
struct sitHdr sithdr;
struct fileHdr filehdr;
extern int optind;
extern char *optarg;
int errflg;
mode = FULL;
errflg = 0;
while ((c = getopt(argc, argv, "dlqruvx")) != (char)EOF)
/* added (char) for native amdahl compiler bug NRT*/
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 '?':
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 (readsithdr(&sithdr) == 0) {
fprintf(stderr, "Can't read file header\n");
exit(1);
}
/*
printf("numfiles=%d, arclength=%ld\n", sithdr.numFiles, sithdr.arcLength);
*/
for (i = 0; i < sithdr.numFiles; i++) {
if (readfilehdr(&filehdr) == -1) {
fprintf(stderr, "Can't read file header #%d\n", i+1);
exit(1);
}
/*
printf("rsrclen=%ld, datalen=%ld, rsrccrc=%d, datacrc=%d\n",
filehdr.compRLength, filehdr.compDLength,
filehdr.rsrcCRC, filehdr.dataCRC);
*/
if (f_rsrc[0] != '\0') {
txtmode = 0;
crc = write_file(f_rsrc, filehdr.compRLength,
filehdr.rsrcLength, filehdr.compRMethod);
if (chkcrc && filehdr.rsrcCRC != crc) {
fprintf(stderr,
"CRC error on resource fork: need 0x%04x, got 0x%04x\n",
filehdr.rsrcCRC, crc);
break;
}
}
else {
fseek(infp, filehdr.compRLength, 1);
}
if (f_data[0] != '\0') {
txtmode = (mode == TEXT);
crc = write_file(f_data, filehdr.compDLength,
filehdr.dataLength, filehdr.compDMethod);
if (chkcrc && filehdr.dataCRC != crc) {
fprintf(stderr,
"CRC error on data fork: need 0x%04x, got 0x%04x\n",
filehdr.dataCRC, crc);
break;
}
}
else {
fseek(infp, filehdr.compDLength, 1);
}
}
}
usage()
{
fprintf(stderr, "Usage: unsit [-rdulvq] filename\n");
}
readsithdr(s)
struct sitHdr *s;
{
char temp[SITHDRSIZE];
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) {
fprintf(stderr, "Not a StuffIt file\n");
return(0);
}
s->numFiles = get2(temp + S_NUMFILES);
s->arcLength = get4(temp + S_ARCLENGTH);
return(1);
}
readfilehdr(f)
struct fileHdr *f;
{
register int i;
unsigned short crc;
int n, j, write_it;
char hdr[FILEHDRSIZE];
char *tp, temp[10];
FILE *fp;
for (i = 0; i < INFOBYTES; i++)
info[i] = '\0';
if (fread(hdr, 1, FILEHDRSIZE, infp) != FILEHDRSIZE) {
fprintf(stderr, "Can't read file header\n");
return(-1);
}
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(-1);
}
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(text, hdr + F_FNAME + 1, n);
text[n] = '\0';
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);
write_it = 1;
if (listonly || verbose || query) {
printf("name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
text, hdr + F_FTYPE, hdr + F_CREATOR,
f->dataLength, f->rsrcLength);
if (listonly) {
write_it = 0;
putchar('\n');
}
else if (query) {
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
putchar('\n');
}
/* check for illegal Unix characters in file name */
for (tp = text; *tp; tp++)
if (*tp <= ' ' || *tp == '/' || *tp > '~')
*tp = '_';
f_data[0] = f_rsrc[0] = '\0';
if (write_it) {
switch (mode) {
case FULL:
sprintf(f_data, "%s.data", text); /* can be d.%s if name too long NRT*/
sprintf(f_rsrc, "%s.rsrc", text); /* can be r.%s if name too long NRT*/
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);
sprintf(f_info, "%s.info", text); /* can be i.%s if name too long NRT*/
fp = fopen(f_info, "w");
if (fp == NULL) {
perror(f_info);
exit(1);
}
fwrite(info, 1, INFOBYTES, fp);
fclose(fp);
break;
case RSRC:
sprintf(f_rsrc, "%s.rsrc", text);
break;
case DATA:
case TEXT:
sprintf(f_data, "%s", text);
break;
case DUMP:
sprintf(f_data, "%s.ddump", text);
sprintf(f_rsrc, "%s.rdump", text);
f->compRMethod = f->compDMethod = noComp;
break;
}
}
return(1);
}
unsigned short write_file(fname, ibytes, obytes, type)
char *fname;
long ibytes, obytes;
int type;
{
unsigned short crc;
int i, n, ch, lastch;
FILE *outf;
char temp[256];
crc = INIT_CRC;
chkcrc = 1; /* usually can check the CRC */
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 repComp: /* 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) {
n = (getc(infp) & 0xff) - 1;
ibytes--;
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 lpzComp: /* 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);
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");
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);
}
/* 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
@//E*O*F unsit.c//
chmod u=rw,g=r,o=r unsit.c
echo x - unsit.h
sed 's/^@//' > "unsit.h" <<'@//E*O*F unsit.h//'
/* unsit.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 repComp 1 /* RLE compression */
#define lpzComp 2 /* LZW compression */
#define hufComp 3 /* Huffman compression */
/* all other numbers are reserved */
@//E*O*F unsit.h//
chmod u=rw,g=r,o=r unsit.h
exit 0