home *** CD-ROM | disk | FTP | other *** search
- From: np@doc.imperial.ac.uk (Nigel Perry)
- Newsgroups: comp.sources.mac
- Subject: AufsTools (part 3 of 4)
- Message-ID: <CSM.91.3>
- Date: 20 Feb 91 20:00:06 GMT
- Approved: bytebug@dhw68k.cts.com (Roger L. Long)
-
- [AufsTools - part 3 of 4]
-
- ---
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 4)."
- # Contents: mcvert/hqxify.c mcvert/mcvert.c stuffit/sit.c
- # Wrapped by np@asun5 on Mon Dec 3 13:15:58 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mcvert/hqxify.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mcvert/hqxify.c'\"
- else
- echo shar: Extracting \"'mcvert/hqxify.c'\" \(19992 characters\)
- sed "s/^X//" >'mcvert/hqxify.c' <<'END_OF_FILE'
- X#include "mactypes.h"
- X
- X#define HQXBUFLEN 512
- Xbyte hqxbuf[HQXBUFLEN+1], *buf_ptr, *buf_end, *buf_start=hqxbuf+1;
- X
- X#define MAXLINE 255
- Xbyte line[MAXLINE+1], *line_ptr, *line_end, *line_start=line+1;
- X
- Xint line_count, file_count;
- Xint save_state, total_bytes, save_run_length;
- Xword save_nibble;
- Xchar binfname[BINNAMELEN], hqxfname[BINNAMELEN];
- XFILE *hqxfile, *binfile;
- X
- X/* This routine reads the header of a hqxed file and appropriately twiddles it,
- X determines if it has CRC problems, creates the .bin file, and puts the info
- X into the .bin file.
- X Output is hqx_datalen, hqx_rsrclen, type, binfname, binfile */
- X
- Xhqx_to_bin_hdr(type, hqx_datalen, hqx_rsrclen)
- Xchar *type;
- Xulong *hqx_datalen, *hqx_rsrclen;
- X{ register byte *hqx_ptr, *hqx_end;
- X register ulong calc_crc;
- X hqx_buf *hqx_block;
- X hqx_header *hqx;
- X info_header info;
- X ulong mtim;
- X short crc;
- X
- X extern word magic[];
- X extern FILE *verbose;
- X extern char *dir, *ext;
- X extern short calc_mb_crc();
- X
- X /* read the hqx header, assuming that I won't exhaust hqxbuf in so doing */
- X fill_hqxbuf();
- X hqx_block = (hqx_buf *) buf_ptr;
- X hqx = (hqx_header *) (hqx_block->name + hqx_block->nlen);
- X hqx_ptr = buf_ptr;
- X hqx_end = (byte *) hqx + sizeof(hqx_header) - 1;
- X calc_crc = 0;
- X while (hqx_ptr < hqx_end)
- X calc_crc = (((calc_crc&0xff) << 8) | *hqx_ptr++) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X buf_ptr = hqx_ptr;
- X
- X /* stuff the hqx header data into the info header */
- X bzero(&info, sizeof(info_header));
- X info.nlen = hqx_block->nlen;
- X strncpy(info.name, hqx_block->name, info.nlen); /* name */
- X bcopy(hqx->type, info.type, 9); /* type, author, flag */
- X info.flags &= 0x7e; /* reset lock bit, init bit */
- X if (hqx->protect & 0x40) info.protect = 1; /* copy protect bit */
- X bcopy(hqx->dlen, info.dlen, 8); /* dlen, rlen */
- X mtim = time2mac(time(0));
- X bcopy(&mtim, info.mtim, 4);
- X bcopy(&mtim, info.ctim, 4);
- X info.uploadvers = '\201';
- X info.readvers = '\201';
- X
- X /* calculate MacBinary CRC */
- X crc = calc_mb_crc(&info, 124, 0);
- X info.crc[0] = (char) (crc >> 8);
- X info.crc[1] = (char) crc;
- X
- X /* Create the .bin file and write the info to it */
- X unixify(hqx_block->name);
- X sprintf(binfname, "%s/%s%s", dir, hqx_block->name, ext);
- X fprintf(verbose,
- X "Converting %-30s type = \"%4.4s\", author = \"%4.4s\"\n",
- X hqx_block->name, info.type, info.auth);
- X if ((binfile = fopen(binfname, "w")) == NULL)
- X error("Cannot open %s", binfname);
- X check_hqx_crc(calc_crc, "File header CRC mismatch in %s", binfname);
- X fwrite(&info, sizeof(info), 1, binfile);
- X
- X /* Get a couple of items we'll need later */
- X bcopy(info.dlen, hqx_datalen, 4);
- X *hqx_datalen = mac2long(*hqx_datalen);
- X bcopy(info.rlen, hqx_rsrclen, 4);
- X *hqx_rsrclen = mac2long(*hqx_rsrclen);
- X bcopy(info.type, type, 4);
- X }
- X
- X/* This routine reads the header of a bin file and appropriately twiddles it,
- X creates the .hqx file, and puts the info into the .hqx file.
- X Output is hqx_datalen, hqx_rsrclen, type, hqxfname, hqxfile */
- X
- Xbin_to_hqx_hdr(hqx_datalen, hqx_rsrclen)
- Xulong *hqx_datalen, *hqx_rsrclen;
- X{ register byte *hqx_ptr, *hqx_end;
- X register ulong calc_crc;
- X hqx_buf *hqx_block;
- X hqx_header *hqx;
- X info_header info;
- X extern word magic[];
- X extern FILE *verbose;
- X extern char **hqxnames_left;
- X extern char *ext;
- X
- X strcpy(binfname, *hqxnames_left++);
- X if (!(binfile = fopen(binfname, "r"))) {
- X /* Maybe we are supposed to figure out the suffix ourselves? */
- X strcat(binfname, ext);
- X if (!(binfile = fopen(binfname, "r")))
- X error("Cannot open %s", binfname);
- X }
- X if (!fread(&info, sizeof(info), 1, binfile))
- X error("Unexpected EOF in header of %s", binfname);
- X
- X /* stuff the info header into the hqx header */
- X hqx_block = (hqx_buf *) buf_ptr;
- X hqx_block->nlen = info.nlen;
- X strncpy(hqx_block->name, info.name, info.nlen);
- X hqx = (hqx_header *) (hqx_block->name + hqx_block->nlen);
- X hqx->version = 0;
- X bcopy(info.type, hqx->type, 9); /* type, author, flags */
- X if (info.protect = 1) hqx->protect = 0; /* protect bit: 0x40 */
- X else hqx->protect = 0;
- X bcopy(info.dlen, hqx->dlen, 8); /* dlen, rlen */
- X
- X /* Create the .hqx file and write the info to it */
- X strncpy(hqxfname, info.name, info.nlen);
- X hqxfname[info.nlen] = '\0';
- X unixify(hqxfname);
- X fprintf(verbose,
- X "Converting %-30s type = \"%4.4s\", author = \"%4.4s\"\n",
- X hqxfname, info.type, info.auth);
- X
- X calc_crc = 0;
- X hqx_ptr = (byte *) hqx_block;
- X hqx_end = hqx_ptr + hqx_block->nlen + sizeof(hqx_header);
- X while (hqx_ptr < hqx_end)
- X calc_crc = (((calc_crc&0xff) << 8) | *hqx_ptr++) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X buf_ptr = hqx_end;
- X write_hqx_crc(calc_crc);
- X
- X /* Get a couple of items we'll need later */
- X bcopy(info.dlen, hqx_datalen, 4);
- X *hqx_datalen = mac2long(*hqx_datalen);
- X bcopy(info.rlen, hqx_rsrclen, 4);
- X *hqx_rsrclen = mac2long(*hqx_rsrclen);
- X }
- X
- X
- X/* This routine copies bytes from the decoded input stream to the output.
- X It also pads to a multiple of 128 bytes on the output, which is part
- X of the .bin format */
- Xword hqx_to_bin_fork(nbytes)
- Xregister ulong nbytes;
- X{ register byte *c;
- X register ulong calc_crc;
- X register int c_length;
- X ulong extra_bytes;
- X extern word magic[];
- X
- X extra_bytes = 127 - (nbytes+127)%128; /* pad fork to mult of 128 bytes */
- X calc_crc = 0;
- X for (;;) {
- X c = buf_ptr;
- X c_length = (c + nbytes > buf_end) ? buf_end - c : nbytes;
- X nbytes -= c_length;
- X fwrite(c, sizeof(byte), c_length, binfile);
- X while (c_length--)
- X calc_crc = (((calc_crc&0xff) << 8) | *c++) ^ magic[calc_crc >> 8];
- X if (!nbytes) break;
- X fill_hqxbuf();
- X }
- X buf_ptr = c;
- X while (extra_bytes--) putc(0, binfile);
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X return (word) calc_crc;
- X }
- X
- X/* This routine copies bytes from the input stream to the encoded output.
- X It also pads to a multiple of 128 bytes on the input, which is part
- X of the .bin format */
- Xword bin_to_hqx_fork(nbytes)
- Xregister ulong nbytes;
- X{ register byte *c;
- X register ulong calc_crc;
- X register int c_length;
- X ulong extra_bytes;
- X extern word magic[];
- X
- X extra_bytes = 127 - (nbytes+127)%128; /* pad fork to mult of 128 bytes */
- X calc_crc = 0;
- X for (;;) {
- X c = buf_ptr;
- X c_length = (c + nbytes > buf_end) ? buf_end - c : nbytes;
- X nbytes -= c_length;
- X fread(c, sizeof(byte), c_length, binfile);
- X buf_ptr += c_length;
- X while (c_length--)
- X calc_crc = (((calc_crc&0xff) << 8) | *c++) ^ magic[calc_crc >> 8];
- X if (!nbytes) break;
- X empty_hqxbuf();
- X }
- X buf_ptr = c;
- X
- X fseek(binfile, extra_bytes, 1);
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X calc_crc = ((calc_crc&0xff) << 8) ^ magic[calc_crc >> 8];
- X return (word) calc_crc;
- X }
- X
- X/* Essentials for Binhex 8to6 run length encoding */
- X#define RUNCHAR 0x90
- X#define MAXRUN 255
- X#define IS_LEGAL <0x40
- X#define ISNT_LEGAL >0x3f
- X#define DONE 0x7F /* tr68[':'] = DONE, since Binhex terminator is ':' */
- X#define SKIP 0x7E /* tr68['\n'|'\r'] = SKIP, i. e. end of line char. */
- X#define FAIL 0x7D /* character illegal in binhex file */
- X
- Xbyte tr86[] =
- X "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
- Xbyte tr68[] = {
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- X 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
- X 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
- X 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
- X 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
- X 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
- X 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
- X 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
- X 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
- X 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
- X 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
- X };
- X
- X/*
- X * This procedure transparently reads and decodes the hqx input. It does run
- X * length and 6 to 8 decoding.
- X */
- X#define READING 0
- X#define SKIPPING 1
- X#define FIND_START_COLON 2
- X
- X/* NP 12/3/90: A dirty hack to handle "X-Mailer: ELM [version 2.2 PL14]" */
- X#define X_MAIL_STR "\054\014\043\061\070\073\065\077\177"
- X#define X_MAIL_LEN strlen(X_MAIL_STR)
- X
- Xfill_hqxbuf()
- X{ register ulong c, nibble;
- X register int not_in_a_run = TRUE, state68;
- X register byte *fast_buf, *fast_line;
- X static int status = FIND_START_COLON;
- X
- X buf_ptr = fast_buf = buf_start;
- X fast_line = line_ptr;
- X state68 = save_state;
- X nibble = save_nibble;
- X if (save_run_length > 0) {
- X c = save_run_length;
- X save_run_length = 0;
- X goto continue_run;
- X }
- X while (fast_buf < buf_end) {
- X next_char:
- X if ((c = *fast_line++) ISNT_LEGAL) {
- X if (c == DONE) break;
- X next_line:
- X if (!fgets(line_start, MAXLINE, hqxfile) && !new_in_hqx_file())
- X if (status == FIND_START_COLON) exit(0);
- X else error("Premature EOF in %s\n", hqxfname);
- X line_ptr = line_start;
- X scan_line:
- X fast_line = line_ptr;
- X while ((*fast_line = tr68[*fast_line]) IS_LEGAL) fast_line++;
- X c = *fast_line;
- X switch (status) {
- X case READING:
- X if (c == SKIP && fast_line == line_end) break;
- X if (c == DONE) {
- X status = FIND_START_COLON;
- X break;
- X }
- X status = SKIPPING;
- X goto next_line;
- X case SKIPPING:
- X if (c == SKIP && fast_line == line_end) {
- X status = READING;
- X break;
- X }
- X /* GMT, 1/9/90: Added this clause to avoid losing the last
- X * line if it was preceeded by a skipped line. */
- X if (c == DONE) {
- X /* NP 12/3/90: A dirty hack to handle "X-Mailer: ELM [version 2.2 PL14]" */
- X if( (fast_line - line_ptr == X_MAIL_LEN - 1)
- X && (strncmp(line_ptr, X_MAIL_STR, X_MAIL_LEN) == 0)) goto next_line;
- X status = FIND_START_COLON;
- X break;
- X }
- X goto next_line;
- X case FIND_START_COLON:
- X if (*line_start == DONE) {
- X status = READING;
- X line_ptr++;
- X goto scan_line;
- X }
- X goto next_line;
- X }
- X fast_line = line_ptr;
- X c = *fast_line++;
- X }
- X
- X /* Finally, we have the next 6 bits worth of data */
- X switch (state68++) {
- X case 0:
- X nibble = c;
- X goto next_char;
- X case 1:
- X nibble = (nibble << 6) | c;
- X c = nibble >> 4;
- X break;
- X case 2:
- X nibble = (nibble << 6) | c;
- X c = (nibble >> 2) & 0xff;
- X break;
- X case 3:
- X c = (nibble << 6) & 0xff | c;
- X state68 = 0;
- X break;
- X }
- X if (not_in_a_run)
- X if (c != RUNCHAR) *fast_buf++ = c;
- X else {not_in_a_run = FALSE; goto next_char;}
- X else {
- X if (c--) {
- X not_in_a_run = buf_end - fast_buf;
- X if (c > not_in_a_run) {
- X save_run_length = c - not_in_a_run;
- X c = not_in_a_run;
- X }
- X continue_run:
- X not_in_a_run = fast_buf[-1];
- X while (c--) *fast_buf++ = not_in_a_run;
- X }
- X else *fast_buf++ = RUNCHAR;
- X not_in_a_run = TRUE;
- X }
- X }
- X total_bytes += fast_buf - buf_ptr;
- X buf_start[-1] = fast_buf[-1];
- X line_ptr = fast_line;
- X save_state = state68;
- X save_nibble = nibble;
- X }
- X
- X
- Xnew_in_hqx_file()
- X{ char *hqx_ext;
- X extern char **hqxnames_left;
- X if (*hqxnames_left[0] == '\0' || *hqxnames_left[0] == '-') return FALSE;
- X strcpy(hqxfname, *hqxnames_left++);
- X hqx_ext = hqxfname + strlen(hqxfname) - 4;
- X if (!strcmp(hqx_ext, ".hqx"))
- X if (!freopen(hqxfname, "r", hqxfile))
- X error("Cannot open %s\n", hqxfname);
- X else;
- X else {
- X if (!freopen(hqxfname, "r", hqxfile)) {
- X hqx_ext += 4;
- X strcpy(hqx_ext, ".hqx");
- X if (!freopen(hqxfname, "r", hqxfile)) {
- X error("Cannot find %s\n", hqxfname);
- X }
- X }
- X }
- X fgets(line_start, MAXLINE, hqxfile);
- X return TRUE;
- X }
- X
- X/*
- X * This procedure transparently encodes and writes the hqx output.
- X * It does run length and 8 to 6 encoding.
- X */
- Xempty_hqxbuf()
- X{ register ulong c, nibble, last_c;
- X register byte *fast_buf, *fast_line;
- X register int state86, dont_look_for_runs = FALSE, run_length;
- X extern int maxlines;
- X
- X run_length = save_run_length;
- X last_c = buf_start[-1];
- X fast_buf = buf_start;
- X fast_line = line_ptr;
- X state86 = save_state;
- X nibble = save_nibble;
- X while (fast_buf < buf_ptr) {
- X c = *fast_buf++;
- X if (dont_look_for_runs) dont_look_for_runs = FALSE;
- X else if (last_c == c && run_length < MAXRUN) {run_length++; continue;}
- X else {
- X if (run_length >1) {
- X --fast_buf;
- X if (run_length == 2 && last_c != RUNCHAR) c = last_c;
- X else {
- X c = RUNCHAR;
- X *--fast_buf = run_length;
- X dont_look_for_runs = TRUE;
- X }
- X run_length = 1;
- X }
- X else last_c = c;
- X if (c == RUNCHAR && !dont_look_for_runs) {
- X *--fast_buf = 0;
- X dont_look_for_runs = TRUE;
- X }
- X }
- X
- X if (fast_line == line_end) {
- X if (line_count++ == maxlines) new_out_hqx_file();
- X fputs(line_start, hqxfile);
- X fast_line = line_start;
- X }
- X
- X switch (state86++) {
- X case 0:
- X *fast_line++ = tr86[ c >> 2 ];
- X nibble = (c << 4) & 0x3f;
- X break;
- X case 1:
- X *fast_line++ = tr86[ (c >> 4) | nibble ];
- X nibble = (c << 2) & 0x3f;
- X break;
- X case 2:
- X *fast_line++ = tr86[ (c >> 6) | nibble ];
- X if (fast_line == line_end) {
- X if (line_count++ == maxlines) new_out_hqx_file();
- X fputs(line_start, hqxfile);
- X fast_line = line_start;
- X }
- X *fast_line++ = tr86[ c & 0x3f ];
- X state86 = 0;
- X break;
- X }
- X }
- X save_run_length = run_length;
- X buf_start[-1] = last_c;
- X buf_ptr = buf_start;
- X line_ptr = fast_line;
- X save_state = state86;
- X save_nibble = nibble;
- X }
- X
- Xnew_out_hqx_file()
- X{ char filename[NAMELEN + 7];
- X extern int maxlines;
- X fprintf(hqxfile, "<<< End of Part %2d >>>\n", file_count);
- X fclose(hqxfile);
- X file_count++;
- X if (maxlines) sprintf(filename, "%s%02d.hqx", hqxfname, file_count);
- X else sprintf(filename, "%s.hqx", hqxfname);
- X if ((hqxfile = fopen(filename, "w")) == NULL)
- X error("Can't create %s", filename);
- X if (file_count > 1)
- X fprintf(hqxfile, "<<< Start of Part %2d >>>\n", file_count);
- X else fprintf(hqxfile, "(This file must be converted with BinHex 4.0)\n\n");
- X line_count = 3;
- X }
- X
- Xcheck_hqx_crc(calc_crc, msg, name)
- Xword calc_crc;
- Xchar msg[], name[];
- X{ word read_crc;
- X if (buf_ptr >= buf_end) fill_hqxbuf();
- X read_crc = *buf_ptr++ << 8;
- X if (buf_ptr >= buf_end) fill_hqxbuf();
- X read_crc |= *buf_ptr++;
- X if (read_crc != calc_crc) error(msg, name);
- X }
- X
- Xwrite_hqx_crc(calc_crc)
- Xword calc_crc;
- X{ if (buf_ptr == buf_end) empty_hqxbuf();
- X *buf_ptr++ = calc_crc >> 8;
- X if (buf_ptr == buf_end) empty_hqxbuf();
- X *buf_ptr++ = calc_crc;
- X }
- X
- Xun_hqx(unpit_flag)
- Xint unpit_flag;
- X{ char type[4];
- X ulong hqx_datalen, hqx_rsrclen;
- X word un_pit();
- X int unpitting, bytes_read;
- X word calc_crc;
- X extern char **hqxnames_left;
- X
- X hqxfile = fopen("/dev/null", "r");
- X line_end = line_start + HQXLINELEN;
- X buf_end = buf_start + HQXBUFLEN;
- X for (;;) {
- X total_bytes = 0;
- X line_ptr = line_start;
- X line_ptr[0] = SKIP;
- X save_state = 0;
- X save_run_length = 0;
- X
- X hqx_to_bin_hdr(type, &hqx_datalen, &hqx_rsrclen); /* binfname */
- X
- X unpitting = unpit_flag && !strcmp(type, "PIT ");
- X if (unpitting) {
- X fclose(binfile);
- X unlink(binfname);
- X bytes_read = total_bytes - (buf_end - buf_ptr);
- X calc_crc = un_pit();
- X bytes_read = total_bytes - (buf_end - buf_ptr) - bytes_read;
- X if (bytes_read != hqx_datalen)
- X fprintf(stderr,
- X "Warning - Extraneous characters ignored in %s\n", binfname);
- X }
- X else calc_crc = hqx_to_bin_fork(hqx_datalen);
- X check_hqx_crc(calc_crc, "File data CRC mismatch in %s", binfname);
- X
- X calc_crc = hqx_to_bin_fork(hqx_rsrclen);
- X check_hqx_crc(calc_crc, "File rsrc CRC mismatch in %s", binfname);
- X
- X if (!unpitting) fclose(binfile);
- X }
- X }
- X
- Xre_hqx()
- X{ word calc_crc;
- X ulong hqx_datalen, hqx_rsrclen;
- X extern char **hqxnames_left;
- X extern int maxlines;
- X line_end = line_start + HQXLINELEN;
- X buf_end = buf_start + HQXBUFLEN;
- X while (*hqxnames_left[0] != '-') {
- X hqxfile = fopen("/dev/null", "w");
- X line_count = maxlines;
- X file_count = 0;
- X line_ptr = line_start;
- X *line_ptr++ = ':';
- X strcpy(line_end, "\n");
- X buf_ptr = buf_start;
- X save_state = 0;
- X save_run_length = 1;
- X
- X bin_to_hqx_hdr(&hqx_datalen, &hqx_rsrclen); /* calculates hqxfname */
- X
- X calc_crc = bin_to_hqx_fork(hqx_datalen);
- X write_hqx_crc(calc_crc);
- X
- X calc_crc = bin_to_hqx_fork(hqx_rsrclen);
- X write_hqx_crc(calc_crc);
- X *buf_ptr = !buf_ptr[-1]; /* To end a run and to get the last */
- X buf_ptr++;
- X empty_hqxbuf(); /* stray bits, temporarily add a char */
- X if (save_state != 2) --line_ptr;
- X if (line_ptr == line_end) {
- X fputs(line_start, hqxfile);
- X line_ptr = line_start;
- X }
- X strcpy(line_ptr, ":\n");
- X fputs(line_start, hqxfile);
- X fclose(hqxfile);
- X }
- X }
- END_OF_FILE
- if test 19992 -ne `wc -c <'mcvert/hqxify.c'`; then
- echo shar: \"'mcvert/hqxify.c'\" unpacked with wrong size!
- fi
- # end of 'mcvert/hqxify.c'
- fi
- if test -f 'mcvert/mcvert.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mcvert/mcvert.c'\"
- else
- echo shar: Extracting \"'mcvert/mcvert.c'\" \(13666 characters\)
- sed "s/^X//" >'mcvert/mcvert.c' <<'END_OF_FILE'
- X/* mcvert.c - version 1.05 - 10 January, 1990 modified 12 March, 1990 by NP
- X * Written by Doug Moore - Rice University - dougm@rice.edu - April '87
- X * Sun bug fixes, assorted stuff - Jim Sasaki, March '89
- X * Changed default max_line_size from 2000 to unlimited - Doug Moore, April, '89
- X * Sun 3/60 doesn't like odd-sized structs. Bug fixed - Doug Moore, April, '89
- X * - aided by Spencer W. Thomas
- X * Didn't handle properly many hqx files combined in one file. Bug fixed -
- X * Doug Moore, June, '89
- X * Modified to handle MacBinaryII specification. Jim Van Verth, Sept, '89
- X *
- X * Fixed a bug when there are blank lines in hqx data, as happens when newline
- X * get translated to CRLF and then to \n\n, common for some file transfers.
- X * The last hqx line would be lost if the previous line was blank or junk.
- X * Glenn Trewitt, Stanford University, 1990 (1.05)
- X *
- X * Mcvert would hiccup on mail header lines "X-Mailer: ELM [version 2.2 PL14]"
- X * as "X-Mailer:" is a vaild hqx line! Added in code to special case this
- X * line and keep scanning for the real hqx data.
- X * Nigel Perry, Imperial College, 12 March 1990 [NP]
- X *
- X * This program may be freely distributed for non-profit purposes. It may not
- X * be sold, by itself or as part of a collection of software. It may be freely
- X * modified as long as no modified version is distributed. Modifications of
- X * interest to all can be incorporated into the program by sending them to me
- X * for distribution. Parts of the code can be used in other programs. I am not
- X * responsible for any damage caused by this program. I hope you enjoy it.
- X */
- X
- X#include "mactypes.h"
- X
- X#define HQX 0
- X#define TEXT 1
- X#define DATA 2
- X#define RSRC 3
- X#define HOST 4
- X#define FORWARDS 0
- X#define BACKWARDS 1
- X
- XFILE *verbose;
- Xchar **hqxnames, **hqxnames_left;
- Xchar *dir, *ext, *text_author;
- Xchar *maxlines_str;
- Xint maxlines;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{ char *flags, *getenv();
- X int direction, mode, unpit_flag;
- X
- X argv++;
- X argc--;
- X verbose = stderr;
- X direction = FORWARDS;
- X mode = HQX;
- X unpit_flag = 0;
- X
- X if ((text_author = getenv("MAC_EDITOR")) == NULL) text_author = "MACA";
- X if ((ext = getenv("MAC_EXT")) == NULL) ext = ".bin";
- X if ((dir = getenv("MAC_DLOAD_DIR")) == NULL) dir = ".";
- X if ((maxlines_str = getenv("MAC_LINE_LIMIT")) == NULL) maxlines = 0;
- X else maxlines = atoi(maxlines_str);
- X
- X /* Make command line arguments globally accessible */
- X hqxnames = (char **) calloc(argc+1, sizeof(char *));
- X hqxnames_left = hqxnames;
- X while (argc--) *hqxnames_left++ = *argv++;
- X *hqxnames_left = "-";
- X hqxnames_left = hqxnames;
- X
- X while (strcmp(*hqxnames_left, "-")) {
- X if (hqxnames_left[0][0] == '-') {
- X flags = *hqxnames_left++;
- X while (*++flags)
- X switch (*flags) {
- X case 'x':
- X mode = HQX;
- X break;
- X case 'u':
- X mode = TEXT;
- X break;
- X case 'd':
- X mode = DATA;
- X break;
- X case 'r':
- X mode = RSRC;
- X break;
- X case 'h':
- X mode = HOST;
- X break;
- X case 'D':
- X direction = FORWARDS;
- X break;
- X case 'U':
- X direction = BACKWARDS;
- X break;
- X case 'q':
- X unpit_flag = 0;
- X break;
- X case 'p':
- X unpit_flag = 1;
- X break;
- X case 's':
- X verbose = fopen("/dev/null", "w");
- X break;
- X case 'v':
- X verbose = stderr;
- X break;
- X default:
- X error(
- X "Usage: mcvert [ -[r|d|u|x|h] [D|U] [p|q] [s|v] ] filename...",
- X NULL);
- X }
- X }
- X
- X if (direction == BACKWARDS)
- X if (mode == HQX && unpit_flag) re_hqx();/* no re_pit() yet */
- X else if (mode == HQX) re_hqx();
- X else re_other(mode);
- X else
- X if (mode == HQX) un_hqx(unpit_flag);
- X else un_other(mode);
- X }
- X }
- X
- X/* An array useful for CRC calculations that use 0x1021 as the "seed" */
- Xword magic[] = {
- X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- X 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- X 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- X 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- X 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- X 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- X 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- X 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- X 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- X 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- X 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- X 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- X 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- X 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- X 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- X 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- X 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- X 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- X 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- X 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- X 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- X 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- X 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- X 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- X 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- X 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- X 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- X 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- X 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- X 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- X 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- X 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
- X };
- X
- X
- X/*
- X * calc_crc() --
- X * Compute the MacBinary II-style CRC for the data pointed to by p, with the
- X * crc seeded to seed.
- X *
- X * Modified by Jim Van Verth to use the magic array for efficiency.
- X */
- Xshort calc_mb_crc(p, len, seed)
- Xunsigned char *p;
- Xlong len;
- Xshort seed;
- X{
- X short hold; /* crc computed so far */
- X long i; /* index into data */
- X
- X extern unsigned short magic[]; /* the magic array */
- X
- X hold = seed; /* start with seed */
- X for (i = 0; i < len; i++, p++) {
- X hold ^= (*p << 8);
- X hold = (hold << 8) ^ magic[(unsigned char)(hold >> 8)];
- X }
- X
- X return (hold);
- X} /* calc_crc() */
- X
- X
- X/* Report a fatal error */
- Xerror(msg, name)
- Xchar msg[], name[];
- X{ fprintf(stderr, msg, name);
- X putc('\n', stderr);
- X exit(1);
- X }
- X
- X/* replace illegal Unix characters in file name */
- X/* make sure host file name doesn't get truncated beyond recognition */
- Xunixify(np)
- Xregister byte *np;
- X{ register ulong c;
- X c = strlen(np);
- X if (c > SYSNAMELEN - 4) c = SYSNAMELEN - 4;
- X np[c] = '\0';
- X np--;
- X while (c = *++np)
- X if (c <= ' ' || c == '/' || c > '~') *np = '_';
- X }
- X
- X/* Convert Unix time (GMT since 1-1-1970) to Mac
- X time (local since 1-1-1904) */
- X#define MACTIMEDIFF 0x7c25b080 /* Mac time of 00:00:00 GMT, Jan 1, 1970 */
- X
- Xulong time2mac(time)
- Xulong time;
- X{ struct timeb tp;
- X ftime(&tp);
- X return long2mac(time + MACTIMEDIFF
- X - 60 * (tp.timezone - 60 * tp.dstflag));
- X }
- X
- X
- X/* This procedure copies the input file to the output file, basically, although
- X in TEXT mode it changes LF's to CR's and in any mode it forges a Mac info
- X header. Author type for TEXT mode can come from the MAC_EDITOR environ-
- X ment variable if it is defined. */
- X
- Xun_other(mode)
- Xint mode;
- X{ register ulong b;
- X register ulong nchars;
- X char txtfname[BINNAMELEN], binfname[BINNAMELEN];
- X FILE *txtfile, *binfile;
- X char *suffix;
- X struct stat stbuf;
- X info_header info;
- X int extra_chars;
- X ulong dlen, rlen, mtim, ctim;
- X short crc, calc_mb_crc();
- X
- X if (mode == DATA) suffix = ".data";
- X else if (mode == RSRC) suffix = ".rsrc";
- X else suffix = ".text";
- X
- X while (hqxnames_left[0][0] != '-') {
- X
- X strcpy(txtfname, *hqxnames_left++);
- X if (!(txtfile = fopen(txtfname, "r"))) {
- X /* Maybe we are supposed to figure out the suffix ourselves? */
- X strcat(txtfname, suffix);
- X if (!(txtfile = fopen(txtfname, "r")))
- X error("Cannot open %s", txtfname);
- X }
- X
- X if (stat(txtfname, &stbuf))
- X error("Cannot read %s", txtfname);
- X
- X /* stuff header data into the info header */
- X bzero(&info, sizeof(info_header));
- X info.nlen = strlen(txtfname);
- X info.nlen = (info.nlen > NAMELEN) ? NAMELEN : info.nlen;
- X info.name[info.nlen] = '\0';
- X strcpy(info.name, txtfname); /* name */
- X mtim = time2mac(stbuf.st_mtime);
- X ctim = time2mac(stbuf.st_ctime);
- X bcopy(&mtim, info.mtim, 4);
- X bcopy(&ctim, info.ctim, 4);
- X info.uploadvers = '\201';
- X info.readvers = '\201';
- X
- X if (mode == RSRC) {
- X /* dlen is already zero */
- X rlen = long2mac(stbuf.st_size);
- X bcopy(&rlen, info.rlen, 4);
- X bcopy("APPL", info.type, 4);
- X bcopy("CCOM", info.auth, 4);
- X }
- X else {
- X dlen = long2mac(stbuf.st_size);
- X bcopy(&dlen, info.dlen, 4);
- X /* rlen is already zero */
- X bcopy("TEXT", info.type, 4);
- X if (mode == DATA) bcopy("????", info.auth, 4);
- X else bcopy(text_author, info.auth, 4);
- X }
- X
- X /* calculate CRC */
- X crc = calc_mb_crc(&info, 124, 0);
- X info.crc[0] = (char) (crc >> 8);
- X info.crc[1] = (char) crc;
- X
- X /* Create the .bin file and write the info to it */
- X sprintf(binfname, "%s/%s%s", dir, txtfname, ext);
- X if ((binfile = fopen(binfname, "w")) == NULL)
- X error("Cannot open %s", binfname);
- X fprintf(verbose,
- X "Converting %-30s type = \"%4.4s\", author = \"%4.4s\"\n",
- X txtfname, info.type, info.auth);
- X fwrite(&info, sizeof(info), 1, binfile);
- X
- X nchars = stbuf.st_size;
- X extra_chars = 127 - (nchars+127) % 128;
- X if (mode == TEXT) while (nchars--) {
- X b = getc(txtfile);
- X if (b == LF) b = CR;
- X putc(b, binfile);
- X }
- X else while (nchars--) putc(getc(txtfile), binfile);
- X
- X while (extra_chars--) putc(0, binfile);
- X fclose(binfile);
- X fclose(txtfile);
- X }
- X }
- X
- X/* This procedure copies the input file to the output file, basically, although
- X in TEXT mode it changes CR's to LF's and in any mode it skips over the Mac
- X info header. */
- X
- Xre_other(mode)
- Xint mode;
- X{ register ulong b;
- X register ulong nchars;
- X char txtfname[BINNAMELEN], binfname[BINNAMELEN];
- X FILE *txtfile, *binfile;
- X char *suffix;
- X info_header info;
- X
- X if (mode == DATA) suffix = ".data";
- X else if (mode == RSRC) suffix = ".rsrc";
- X else suffix = ".text";
- X
- X while (hqxnames_left[0][0] != '-') {
- X
- X strcpy(binfname, *hqxnames_left++);
- X if ((binfile = fopen(binfname, "r")) == NULL) {
- X /* Maybe we are supposed to figure out the suffix ourselves? */
- X strcat(binfname, ext);
- X if (!(binfile = fopen(binfname, "r")))
- X error("Cannot open %s", binfname);
- X }
- X
- X /* Read the info from the .bin file, create the output file */
- X fread(&info, sizeof(info), 1, binfile);
- X strncpy(txtfname, info.name, info.nlen);
- X txtfname[info.nlen] = '\0';
- X fprintf(verbose,
- X "Converting %-30s type = \"%4.4s\", author = \"%4.4s\"\n",
- X txtfname, info.type, info.auth);
- X if ((txtfile = fopen(txtfname, "r")) == NULL) {
- X if ((txtfile = fopen(txtfname, "w")) == NULL)
- X error("Cannot open %s", txtfname);
- X }
- X else {
- X fclose(txtfile);
- X strcat(txtfname, suffix);
- X if ((txtfile = fopen(txtfname, "w")) == NULL)
- X error("Cannot open %s", txtfname);
- X }
- X
- X nchars = mac2long(* (ulong *) info.dlen);
- X if (mode == TEXT) while (nchars--) {
- X b = getc(binfile);
- X if (b == CR) b = LF;
- X putc(b, txtfile);
- X }
- X else if (mode == DATA) while (nchars--)
- X putc(getc(binfile), txtfile);
- X else {
- X while (nchars--) getc(binfile);
- X nchars = mac2long(* (ulong *) info.rlen);
- X while (nchars--) putc(getc(binfile), txtfile);
- X }
- X
- X fclose(binfile);
- X fclose(txtfile);
- X }
- X }
- END_OF_FILE
- if test 13666 -ne `wc -c <'mcvert/mcvert.c'`; then
- echo shar: \"'mcvert/mcvert.c'\" unpacked with wrong size!
- fi
- # end of 'mcvert/mcvert.c'
- fi
- if test -f 'stuffit/sit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stuffit/sit.c'\"
- else
- echo shar: Extracting \"'stuffit/sit.c'\" \(12417 characters\)
- sed "s/^X//" >'stuffit/sit.c' <<'END_OF_FILE'
- X/*
- X * sit - Stuffit for UNIX
- X * Puts unix data files into stuffit archive suitable for downloading
- X * to a Mac. Automatically processes files output from xbin.
- X *
- X * Reverse engineered from unsit by Allan G. Weber, which was based on
- X * macput, which was based on ...
- X * Just like unsit this uses the host's version of compress to do the work.
- X *
- X * Examples:
- X * 1) take collection of UNIX text files and make them LSC text files
- X * when uncompressed on the mac:
- X * sit -u -T TEXT -C KAHL file ...
- X * 2) Process output from xbin:
- X * xbin file1 (produces FileOne.{info,rsrc,data})
- X * sit file1
- X *
- X * Tom Bereiter
- X * ..!{rutgers,ames}!cs.utexas.edu!halley!rolex!twb
- X *
- X * This version for CAP aufs files based on info from aufs source + mcvert etc.
- X * Aufs version is program is called AUFSNAME (default stuffit)
- X *
- X * Aug 90. Nigel Perry, np@doc.ic.ac.uk
- X *
- X */
- X#define BSD
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include "sit.h"
- X#ifdef BSD
- X#include <sys/time.h>
- X#include <sys/timeb.h>
- X#else
- X#include <time.h>
- Xextern long timezone;
- X#endif
- X
- X#ifndef min
- X#define min(a,b) ((a)<(b)?(a):(b))
- X#endif
- X
- X/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
- X#define TIMEDIFF 0x7c25b080
- X
- X/* if called by this name, program will work on aufs files */
- X#define AUFSNAME "stuffit"
- X
- Xstruct sitHdr sh;
- Xstruct fileHdr fh;
- X
- Xchar buf[BUFSIZ];
- Xchar *defoutfile = "archive.sit";
- Xint ofd;
- Xushort crc;
- Xint clen;
- Xint rmfiles;
- Xint unixf;
- Xchar *Creator, *Type;
- Xint aufs;
- X
- Xusage() { fprintf(stderr,"Usage: sit file\n"); }
- Xextern char *optarg;
- Xextern int optind;
- X
- X/********************************************************************************/
- X/* added for aufs, nicked from various places... */
- X
- X/* following from mcvert program */
- X
- X/* Useful, though not particularly Mac related, values */
- Xtypedef unsigned char byte; /* one byte, obviously */
- Xtypedef unsigned short word; /* must be 2 bytes */
- Xtypedef unsigned long ulong; /* 4 bytes */
- X
- X#define NAMELEN 63 /* maximum legal Mac file name length */
- X
- X/* Format of a bin file:
- XA bin file is composed of 128 byte blocks. The first block is the
- Xinfo_header (see below). Then comes the data fork, null padded to fill the
- Xlast block. Then comes the resource fork, padded to fill the last block. A
- Xproposal to follow with the text of the Get Info box has not been implemented,
- Xto the best of my knowledge. Version, zero1 and zero2 are what the receiving
- Xprogram looks at to determine if a MacBinary transfer is being initiated.
- X*/
- Xtypedef struct { /* info file header (128 bytes). Unfortunately, these
- X longs don't align to word boundaries */
- X byte version; /* there is only a version 0 at this time */
- X byte nlen; /* Length of filename. */
- X byte name[NAMELEN]; /* Filename (only 1st nlen are significant)*/
- X byte type[4]; /* File type. */
- X byte auth[4]; /* File creator. */
- X byte flags; /* file flags: LkIvBnSyBzByChIt */
- X byte zero1; /* Locked, Invisible,Bundle, System */
- X /* Bozo, Busy, Changed, Init */
- X byte icon_vert[2]; /* Vertical icon position within window */
- X byte icon_horiz[2]; /* Horizontal icon postion in window */
- X byte window_id[2]; /* Window or folder ID. */
- X byte protect; /* = 1 for protected file, 0 otherwise */
- X byte zero2;
- X byte dflen[4]; /* Data Fork length (bytes) - most sig. */
- X byte rflen[4]; /* Resource Fork length byte first */
- X byte cdate[4]; /* File's creation date. */
- X byte mdate[4]; /* File's "last modified" date. */
- X byte ilen[2]; /* GetInfo message length */
- X byte flags2; /* Finder flags, bits 0-7 */
- X byte unused[14];
- X byte packlen[4]; /* length of total files when unpacked */
- X byte headlen[2]; /* length of secondary header */
- X byte uploadvers; /* Version of MacBinary II that the uploading program is written for */
- X byte readvers; /* Minimum MacBinary II version needed to read this file */
- X byte crc[2]; /* CRC of the previous 124 bytes */
- X byte padding[2]; /* two trailing unused bytes */
- X } info_header;
- X
- X/* end of mcvert stuff */
- X/* from CAP aufs documentation */
- X
- X#define FINFOLEN 32
- X#define MAXCLEN 199
- Xtypedef struct
- X{ /* byte fi_fndr[FINFOLEN]; */ /* finder info */
- X /* what I think the above is... */
- X ulong fndr_type, fndr_creator;
- X word fndr_flags;
- X ulong fndr_loc;
- X word fndr_fldr;
- X word fndr_icon;
- X byte fndr_unused[8];
- X word fndr_comment;
- X ulong fndr_putaway;
- X /* end of fi_fndr */
- X
- X word fi_attr; /* attributes */
- X#define FI_MAGIC1 255
- X byte fi_magic1; /* was: length of comment */
- X#define FI_VERSION 0x10 /* version major 1, minor 0 */
- X /* if more than 8 versions then */
- X /* something wrong anyway */
- X byte fi_version; /* version number */
- X#define FI_MAGIC 0xda
- X byte fi_magic; /* magic word check */
- X byte fi_bitmap; /* bitmap of included info */
- X#define FI_BM_SHORTFILENAME 0x1 /* is this included? */
- X#define FI_BM_MACINTOSHFILENAME 0x2 /* is this included? */
- X byte fi_shortfilename[12+1]; /* possible short file name */
- X byte fi_macfilename[32+1]; /* possible macintosh file name */
- X byte fi_comln; /* comment length */
- X byte fi_comnt[MAXCLEN+1]; /* comment string */
- X} FileInfo;
- X
- XFileInfo fndr_info;
- X
- X/* end aufs */
- X/********************************************************************************/
- X
- Xmain(argc,argv) char **argv; {
- X int i,n;
- X int total, nfiles;
- X int c;
- X
- X rmfiles = unixf = 0;
- X aufs = strcmp(argv[0], AUFSNAME) == 0;
- X
- X while ((c=getopt(argc, argv, "ro:uC:T:")) != EOF)
- X switch (c) {
- X case 'r':
- X rmfiles++; /* remove files when done */
- X break;
- X case 'o': /* specify output file */
- X defoutfile = optarg;
- X break;
- X case 'u': /* unix file -- change '\n' to '\r' */
- X unixf++;
- X break;
- X case 'C': /* set Mac creator */
- X Creator = optarg;
- X break;
- X case 'T': /* set Mac file type */
- X Type = optarg;
- X break;
- X case '?':
- X usage();
- X exit(1);
- X }
- X
- X if(aufs && (strlen(defoutfile) > 32))
- X { fprintf(stderr, "Output name must not exceed 32 characters: %s\n", defoutfile);
- X exit(-1);
- X }
- X
- X if(aufs)
- X { /* make the .finderinfo file */
- X char buf[32+12+1];
- X
- X strcpy(buf, ".finderinfo/");
- X strcat(buf, defoutfile);
- X if ((ofd=creat(buf,0644))<0)
- X { perror(buf);
- X exit(1);
- X }
- X bzero(&fndr_info, sizeof(FileInfo));
- X bcopy("SIT!", &fndr_info.fndr_type, 4);
- X bcopy("SIT!", &fndr_info.fndr_creator, 4);
- X fndr_info.fi_magic1 = FI_MAGIC1;
- X fndr_info.fi_version = FI_VERSION;
- X fndr_info.fi_magic = FI_MAGIC;
- X fndr_info.fi_bitmap = FI_BM_MACINTOSHFILENAME;
- X strcpy(fndr_info.fi_macfilename, defoutfile);
- X write(ofd, &fndr_info, sizeof(FileInfo));
- X close(ofd);
- X }
- X
- X if ((ofd=creat(defoutfile,0644))<0) {
- X perror(defoutfile);
- X exit(1);
- X }
- X /* empty header, will seek back and fill in later */
- X write(ofd,&sh,sizeof sh);
- X
- X for (i=optind; i<argc; i++) {
- X n = put_file(argv[i]);
- X if (n) {
- X total += n;
- X nfiles++;
- X }
- X }
- X lseek(ofd,0,0);
- X
- X total += sizeof(sh);
- X /* header header */
- X strncpy(sh.sig1,"SIT!",4);
- X cp2(nfiles,sh.numFiles);
- X cp4(total,sh.arcLen);
- X strncpy(sh.sig2,"rLau",4);
- X sh.version = 1;
- X
- X write(ofd,&sh,sizeof sh);
- X}
- X
- Xput_file(name)
- Xchar name[];
- X{
- X struct stat st;
- X struct infohdr ih;
- X int i,n,fd;
- X long fpos1, fpos2;
- X char nbuf[256], *p;
- X int fork=0;
- X long tdiff;
- X struct tm *tp;
- X#ifdef BSD
- X struct timeb tbuf;
- X#else
- X long bs;
- X#endif
- X
- X fpos1 = lseek(ofd,0,1); /* remember where we are */
- X /* write empty header, will seek back and fill in later */
- X bzero(&fh,sizeof fh);
- X write(ofd,&fh,sizeof fh);
- X
- X /* look for resource fork */
- X if(aufs)
- X { strcpy(nbuf, ".resource/");
- X strcat(nbuf, name);
- X }
- X else
- X { strcpy(nbuf,name);
- X strcat(nbuf,".rsrc");
- X }
- X if (stat(nbuf,&st)>=0 && st.st_size) { /* resource fork exists */
- X dofork(nbuf);
- X cp4(st.st_size,fh.rLen);
- X cp4(clen,fh.cRLen);
- X cp2(crc,fh.rsrcCRC);
- X fh.compRMethod = lpzComp;
- X fork++;
- X }
- X if (rmfiles) unlink(nbuf); /* ignore errors */
- X
- X /* look for data fork */
- X st.st_size = 0;
- X strcpy(nbuf,name);
- X if (stat(nbuf,&st)<0) { /* first try plain name */
- X strcat(nbuf,".data");
- X stat(nbuf,&st);
- X }
- X if (st.st_size) { /* data fork exists */
- X dofork(nbuf);
- X cp4(st.st_size,fh.dLen);
- X cp4(clen,fh.cDLen);
- X cp2(crc,fh.dataCRC);
- X fh.compDMethod = lpzComp;
- X fork++;
- X }
- X if (fork == 0) {
- X fprintf(stderr,"%s: no data or resource files\n",name);
- X return 0;
- X }
- X if (rmfiles) unlink(nbuf); /* ignore errors */
- X
- X /* look for .info file */
- X if(aufs)
- X { strcpy(nbuf, ".finderinfo/");
- X strcat(nbuf, name);
- X }
- X else
- X { strcpy(nbuf,name);
- X strcat(nbuf,".info");
- X }
- X if((fd=open(nbuf,0))>=0
- X && ((!aufs && read(fd,&ih,sizeof(ih))==sizeof(ih))
- X || (aufs && read(fd,&fndr_info,sizeof(FileInfo))==sizeof(FileInfo))
- X )
- X )
- X { if(aufs)
- X { char *np;
- X
- X np = (char *)(fndr_info.fi_bitmap & FI_BM_MACINTOSHFILENAME ? fndr_info.fi_macfilename
- X : fndr_info.fi_shortfilename);
- X fh.fName[0] = (char)strlen(np);
- X strncpy(fh.fName+1, np, 64);
- X bcopy(&fndr_info.fndr_type, fh.fType, 4);
- X bcopy(&fndr_info.fndr_creator, fh.fCreator, 4);
- X bcopy(&fndr_info.fndr_flags, fh.FndrFlags, 2);
- X#ifdef BSD
- X ftime(&tbuf);
- X tp = localtime(&tbuf.time);
- X tdiff = TIMEDIFF - tbuf.timezone * 60;
- X if (tp->tm_isdst)
- X tdiff += 60 * 60;
- X#else
- X /* I hope this is right! -andy */
- X time(&bs);
- X tp = localtime(&bs);
- X tdiff = TIMEDIFF - timezone;
- X if (tp->tm_isdst)
- X tdiff += 60 * 60;
- X#endif
- X cp4(st.st_ctime + tdiff, fh.cDate);
- X cp4(st.st_mtime + tdiff, fh.mDate);
- X }
- X else
- X { strncpy(fh.fName, ih.name,64);
- X strncpy(fh.fType, ih.type, 4);
- X strncpy(fh.fCreator, ih.creator, 4);
- X strncpy(fh.FndrFlags, ih.flag, 2);
- X strncpy(fh.cDate, ih.ctime, 4);
- X strncpy(fh.mDate, ih.mtime, 4);
- X }
- X }
- X else { /* no info file so fake it */
- X strncpy(&fh.fName[1], name,63); fh.fName[0] = min(strlen(name),63);
- X /* default to LSC text file */
- X strncpy(fh.fType, Type ? Type : "TEXT", 4);
- X strncpy(fh.fCreator, Creator ? Creator : "KAHL", 4);
- X /* convert unix file time to mac time format */
- X#ifdef BSD
- X ftime(&tbuf);
- X tp = localtime(&tbuf.time);
- X tdiff = TIMEDIFF - tbuf.timezone * 60;
- X if (tp->tm_isdst)
- X tdiff += 60 * 60;
- X#else
- X /* I hope this is right! -andy */
- X time(&bs);
- X tp = localtime(&bs);
- X tdiff = TIMEDIFF - timezone;
- X if (tp->tm_isdst)
- X tdiff += 60 * 60;
- X#endif
- X cp4(st.st_ctime + tdiff, fh.cDate);
- X cp4(st.st_mtime + tdiff, fh.mDate);
- X }
- X close(fd);
- X if (rmfiles) unlink(nbuf); /* ignore errors */
- X
- X crc = updcrc(0,&fh,(sizeof fh)-2);
- X cp2(crc, fh.hdrCRC);
- X
- X fpos2 = lseek(ofd,0,1); /* remember where we are */
- X lseek(ofd,fpos1,0); /* seek back over file(s) and header */
- X write(ofd,&fh,sizeof fh); /* write back header */
- X fpos2=lseek(ofd,fpos2,0); /* seek forward file */
- X
- X return (fpos2 - fpos1);
- X}
- X
- Xdofork(name)
- Xchar name[];
- X{
- X FILE *fs;
- X int n, fd, ufd;
- X char *p;
- X
- X if ((fd=open(name,0))<0) {
- X perror(name);
- X return 0;
- X }
- X if (unixf) /* build conversion file */
- X if ((ufd=creat("sit+temp",0644))<0) {
- X perror("sit+temp");
- X return 0;
- X }
- X /* do crc of file: */
- X crc = 0;
- X while ((n=read(fd,buf,BUFSIZ))>0) {
- X if (unixf) { /* convert '\n' to '\r' */
- X for (p=buf; p<&buf[n]; p++)
- X if (*p == '\n') *p = '\r';
- X write(ufd,buf,n);
- X }
- X crc = updcrc(crc,buf,n);
- X }
- X close(fd);
- X /*
- X * open pipe to compress file
- X * If a unix file ('\n' -> '\r' conversion) 'sit+temp' will be a new copy
- X * with the conversion done. Otherwise, 'sit+temp' is just a link to
- X * the input file.
- X */
- X if (unixf)
- X close(ufd);
- X else link(name,"sit+temp");
- X fs = popen("compress -c -n -b 14 sit+temp","r");
- X if (fs == NULL) {
- X perror(name);
- X return 0;
- X }
- X /* write out compressed file */
- X clen = 0;
- X while ((n=fread(buf,1,BUFSIZ,fs))>0) {
- X write(ofd,buf,n);
- X clen += n;
- X }
- X pclose(fs);
- X unlink("sit+temp");
- X}
- X
- Xcp2(x,dest)
- Xunsigned short x;
- Xchar dest[];
- X{
- X dest[0] = x>>8;
- X dest[1] = x;
- X}
- X
- Xcp4(x,dest)
- Xunsigned long x;
- Xchar dest[];
- X{
- X dest[0] = x>>24;
- X dest[1] = x>>16;
- X dest[2] = x>>8;
- X dest[3] = x;
- X}
- END_OF_FILE
- if test 12417 -ne `wc -c <'stuffit/sit.c'`; then
- echo shar: \"'stuffit/sit.c'\" unpacked with wrong size!
- fi
- # end of 'stuffit/sit.c'
- fi
- echo shar: End of archive 3 \(of 4\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --- end of part 3 ---
-