home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-05-20 | 23.1 KB | 1,073 lines |
-
- : This is a shar archive. Extract with sh, not csh.
- echo x - Makefile
- sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
- XFILES = xbin.c xbin.1 xbinary Makefile readme
- XCFLAGS=-O
- X
- Xxbin: xbin.o
- X cc -o xbin xbin.o
- X
- Xclean:
- X rm -f *.o xbin xbin.sh
- X
- Xshar:
- X shar $(FILES) > xbin.sh
- !Funky!Stuff!
- echo x - readme
- sed -e 's/^X//' > readme << '!Funky!Stuff!'
- X
- XThis is a small rewrite of xbin to create either macget/macput format
- Xfiles or MacBinary files from BinHex files.
- X
- Xxbin [other options] files:
- X
- X .hqx -> .rsrc .info .data
- X
- XFiles are suitable for downloading with MacTerminal 1.1 protocol.
- X
- Xxbin -b [other options] files
- X
- X .hqx -> .bin
- X
- XFiles are suitable for downloading with MacBinary protocol, and there
- Xare one-third as many output files!
- X
- XThere is a Makefile, and a new man page. Enjoy!
- X
- XEarle Horton
- !Funky!Stuff!
- echo x - xbin.1
- sed -e 's/^X//' > xbin.1 << '!Funky!Stuff!'
- X.TH XBIN 1L "16 Jul 1988"
- X.UC 4
- X.SH NAME
- Xxbin \- convert BinHex file to binary before downloading
- Xto MacTerminal
- X.SH SYNOPSIS
- X.B xbin
- X[
- X.B \-o
- X]
- X[
- X.B \-b
- X]
- X[
- X.B \-v
- X]
- X[
- X.B \-l
- X]
- X[[
- X.B \-n
- Xname
- X] file] ...
- X.SH DESCRIPTION
- X.I Xbin
- Xconverts a file created by BinHex (usually
- Xnamed with one of the extensions ".hex", ".hcx", or ".hqx")
- Xinto either three host-system files suitable for downloading to a
- XMacintosh via macput, or a MacBinary format file.
- XThis program is designed for use with the 1.1 Release
- Xversion of MacTerminal, but includes a compatibility option for the
- Xold -0.15X Almost-Alpha version. MacBinary files are compatible
- Xwith many Macintosh communication programs.
- X.PP
- XThe
- X.B -l
- X(list) option reads the header information and
- Xprints out all the useful information there,
- Xwithout creating any converted output files.
- X.PP
- XThe
- X.B -v
- X(verbose) option prints a line for each file to be converted, indicating
- Xthe input and output file names.
- X.PP
- XThe
- X.B -n
- Xname
- Xoption allows the user to specify the name to use when creating
- Xthe host files and the eventual name to use on the mac.
- XThis option must precede the input file name it is to affect.
- X.PP
- XIf this option is not used, the names will be derived from
- Xeither the input file name (.hex or .hcx files),
- Xor the name encoded in the header information (.hqx files).
- XSpaces and slashes will be converted to underscores, and
- Xthe .h?x extension will be deleted, if one is included in the
- Xinput file name.
- X.PP
- XA file name of "-" indicates that the input should be taken from stdin.
- XIf no mac file name is specified, the default name (for .hex or .hcx files)
- Xis "stdin".
- X.PP
- XMail or news headers and signatures need not be manually
- Xstripped -- xbin will ignore pretty much anything
- Xit doesn't need.
- X.PP
- X.I xbin
- Xcreates three host-system files from each input file:
- X.IB name .info ,
- X.IB name .data ,
- Xand
- X.IB name .rsrc .
- X.PP
- XThe
- X.B \-o
- Xflag specifies "old" (version -0.15X) MacTerminal compatibility mode.
- X.PP
- XThe
- X.B \-b
- Xflag specifies create a single MacBinary file:
- X.IB name .bin ,
- Xinstead of the three MacTerminal format files.
- X.SH BUGS
- XThe "LOCKED" bit in the flags cannot be set by xbin.
- XThis is due to a bug in MacTerminal, which sets the flags
- Xwhen the file is created, rather than after it has been
- Xtransfered, resulting in it not being able to write the
- Xfile.
- X.PP
- XInput files must contain a line starting with "(This file"
- Xto detect the beginning of the BinHex information.
- X.SH SEE ALSO
- Xmacput(1), macget(1)
- X.SH AUTHOR
- XDave Johnson, Brown 12/16/84;
- XCRC handling code by Darin Adler, TMQ Software 3/16/85
- !Funky!Stuff!
- echo x - xbin.c
- sed -e 's/^X//' > xbin.c << '!Funky!Stuff!'
- X
- X
- X#ifndef lint
- Xstatic char version[] = "xbin.c Version 2.2.2 07/16/88";
- X#endif lint
- Xstatic char fname_trans_table[] =
- X"@ABCDEFGHIJKLMNOPQRSTUVWXYZexxxxxxx#xxxxxxxxxxxx0123456789xxxxxxxABCDEFGHIJKLMNOPQRSTUVWXYZxxxx_xabcdefghijklmnopqrstuvwxyzxxxxxxABCDEFGHIJKLMNOPQRSTUVWXYZexxxxxxxxxxxxxxxxxxxx0123456789xxxxxxxABCDEFGHIJKLMNOPQRSTUVWXYZxxxx_xabcdefghijklmnopqrstuvwxyzxxxxxx";
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X
- X#ifdef MAXNAMLEN /* 4.2 BSD */
- X#define FNAMELEN MAXNAMLEN
- X#else
- X#define FNAMELEN DIRSIZ
- X#endif
- X
- X#ifdef BSD
- X#include <sys/time.h>
- X#include <sys/timeb.h>
- X#define search_last rindex
- Xextern char *rindex();
- X#else
- X#include <time.h>
- Xextern long timezone;
- X#define search_last strrchr
- Xextern char *strrchr();
- X#endif
- X
- X/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
- X#define TIMEDIFF 0x7c25b080
- X
- X#define DATABYTES 128
- X
- X#define BYTEMASK 0xff
- X#define BYTEBIT 0x100
- X#define WORDMASK 0xffff
- X#define WORDBIT 0x10000
- X
- X#define NAMEBYTES 63
- X#define H_NLENOFF 1
- X#define H_NAMEOFF 2
- X
- X/* 65 <-> 80 is the FInfo structure */
- X#define H_TYPEOFF 65
- X#define H_AUTHOFF 69
- X#define H_FLAGOFF 73
- X
- X#define H_LOCKOFF 81
- X#define H_DLENOFF 83
- X#define H_RLENOFF 87
- X#define H_CTIMOFF 91
- X#define H_MTIMOFF 95
- X
- X#define H_OLD_DLENOFF 81
- X#define H_OLD_RLENOFF 85
- X
- X#define F_BUNDLE 0x2000
- X#define F_LOCKED 0x8000
- X
- Xstruct macheader {
- X char m_name[NAMEBYTES + 1];
- X char m_type[4];
- X char m_author[4];
- X short m_flags;
- X long m_datalen;
- X long m_rsrclen;
- X long m_createtime;
- X long m_modifytime;
- X} mh;
- X
- Xstruct filenames {
- X char f_info[256];
- X char f_data[256];
- X char f_rsrc[256];
- X} files;
- X
- Xint pre_beta; /* options */
- Xint listmode;
- Xint verbose;
- Xint macbinary = 0;
- X
- Xint compressed; /* state variables */
- Xint qformat;
- XFILE *ifp;
- XFILE *fp = NULL;
- X
- X
- X/*
- X * xbin -- unpack BinHex format file into suitable
- X * format for downloading with macput
- X * Dave Johnson, Brown University Computer Science
- X *
- X * checksum code by Darin Adler, TMQ Software
- X *
- X * modification to support MacBinary output file by Earle Horton
- X * uses code from Jim Budler's "macbin.c"
- X *
- X * (c) 1984 Brown University
- X * may be used but not sold without permission
- X *
- X * created ddj 12/16/84
- X * revised ddj 03/10/85 -- version 4.0 compatibility, other minor mods
- X * revised ddj 03/11/85 -- strip LOCKED bit from m_flags
- X * revised ahm 03/12/85 -- System V compatibility
- X * revised dba 03/16/85 -- 4.0 EOF fixed, 4.0 checksum added
- X * revised ddj 03/17/85 -- extend new features to older formats: -l, stdin
- X * revised ddj 03/24/85 -- check for filename truncation, allow multiple files
- X * revised ddj 03/26/85 -- fixed USG botches, many problems w/multiple files
- X * revised jcb 03/30/85 -- revised for compatibility with 16-bit int
- X * revised erh 07/16/88 -- revised to support MacBinary output with "-b"
- X */
- Xchar usage[] = "usage: \"xbin [-v] [-l] [-o] [-b] [-n name] [-] filename\"\n";
- X
- Xmain(ac, av)
- X char **av;
- X{
- X char *filename, *macname;
- X int i;
- X
- X filename = "";
- X macname = "";
- X ac--;
- X av++;
- X while (ac) {
- X if (av[0][0] == '-') {
- X switch (av[0][1]) {
- X case '\0':
- X filename = "-";
- X break;
- X case 'v':
- X verbose++;
- X break;
- X case 'l':
- X listmode++;
- X break;
- X case 'o':
- X pre_beta++;
- X break;
- X case 'b':
- X macbinary = 1;
- X break;
- X case 'n':
- X if (ac > 1) {
- X ac--;
- X av++;
- X macname = av[0];
- X filename = "";
- X break;
- X } else
- X goto bad_usage;
- X default:
- X goto bad_usage;
- X }
- X } else
- X filename = av[0];
- X if (filename[0] != '\0') {
- X setup_files(filename, macname);
- X if (listmode) {
- X print_header();
- X } else
- X{
- X if (macbinary == 1) {
- X fp = fopen(files.f_info, "w");
- X if (fp == NULL) {
- X perror("output file");
- X exit(-1);
- X }
- X for(i = 128 ; i-- > 0;) {
- X putc(0,fp);/* Make space for info. */
- X }
- X }
- X process_forks();
- X /* now that we know the size of the forks */
- X if (macbinary == 1)
- X rewind(fp);
- X forge_info();
- X}
- X if (ifp != stdin)
- X fclose(ifp);
- X macname = "";
- X ifp = NULL; /* reset state */
- X qformat = 0;
- X compressed = 0;
- X }
- X ac--;
- X av++;
- X }
- X if (*filename == '\0') {
- Xbad_usage:
- X fprintf(stderr, usage);
- X exit(1);
- X }
- X}
- X
- Xstatic char *extensions[] = {
- X ".hqx",
- X ".hcx",
- X ".hex",
- X "",
- X NULL
- X};
- X
- Xsetup_files(filename, macname)
- X char *filename; /* input file name -- extension
- X * optional */
- X char *macname;/* name to use on the mac side of things */
- X{
- X char namebuf[256], *np;
- X char **ep;
- X int n;
- X struct stat stbuf;
- X long curtime;
- X
- X if (filename[0] == '-') {
- X ifp = stdin;
- X filename = "stdin";
- X } else {
- X /* find input file and open it */
- X for (ep = extensions; *ep != NULL; ep++) {
- X sprintf(namebuf, "%s%s", filename, *ep);
- X if (stat(namebuf, &stbuf) == 0)
- X break;
- X }
- X if (*ep == NULL) {
- X perror(namebuf);
- X exit(-1);
- X }
- X ifp = fopen(namebuf, "r");
- X if (ifp == NULL) {
- X perror(namebuf);
- X exit(-1);
- X }
- X }
- X if (ifp == stdin) {
- X curtime = time(0);
- X mh.m_createtime = curtime;
- X mh.m_modifytime = curtime;
- X } else {
- X mh.m_createtime = stbuf.st_mtime;
- X mh.m_modifytime = stbuf.st_mtime;
- X }
- X if (listmode || verbose) {
- X fprintf(stderr, "%s %s%s",
- X listmode ? "\nListing" : "Converting",
- X namebuf, listmode ? ":\n" : " ");
- X }
- X qformat = find_header();/* eat mailer header &cetera, intuit format */
- X
- X if (qformat)
- X do_q_header(macname);
- X else
- X do_o_header(macname, filename);
- X
- X /* make sure host file name doesn't get truncated beyond recognition */
- X n = strlen(mh.m_name);
- X if (n > FNAMELEN - 2)
- X n = FNAMELEN - 2;
- X strncpy(namebuf, mh.m_name, n);
- X namebuf[n] = '\0';
- X
- X /* get rid of troublesome characters */
- X for (np = namebuf; *np; np++)
- X /* Negative chars on some systems make lousy subscripts. */
- X *np = fname_trans_table[(unsigned) *np];
- X
- X if ((macbinary == 1)) {
- X sprintf(files.f_info, "%s.bin", namebuf);
- X } else {
- X sprintf(files.f_data, "%s.data", namebuf);
- X sprintf(files.f_rsrc, "%s.rsrc", namebuf);
- X sprintf(files.f_info, "%s.info", namebuf);
- X }
- X if (verbose) {
- X if ((macbinary == 1))
- X fprintf(stderr, "==> %s.bin\n", namebuf);
- X else
- X fprintf(stderr, "==> %s.{info,data,rsrc}\n", namebuf);
- X }
- X}
- X
- X/* print out header information in human-readable format */
- Xprint_header()
- X{
- X char *ctime();
- X
- X printf("macname: %s\n", mh.m_name);
- X printf("filetype: %.4s, ", mh.m_type);
- X printf("author: %.4s, ", mh.m_author);
- X printf("flags: 0x%x\n", mh.m_flags);
- X if (qformat) {
- X printf("data length: %ld, ", mh.m_datalen);
- X printf("rsrc length: %ld\n", mh.m_rsrclen);
- X }
- X if (!pre_beta) {
- X printf("create time: %s", ctime(&mh.m_createtime));
- X }
- X}
- X
- Xprocess_forks()
- X{
- X if (qformat) {
- X /* read data and resource forks of .hqx file */
- X do_q_fork(files.f_data, mh.m_datalen);
- X do_q_fork(files.f_rsrc, mh.m_rsrclen);
- X } else
- X do_o_forks();
- X}
- X
- X/* write out .info file from information in the mh structure */
- Xforge_info()
- X{
- X static char buf[DATABYTES];
- X char *np;
- X int n;
- X long tdiff;
- X struct tm *tp;
- X#ifdef BSD
- X struct timeb tbuf;
- X#else
- X long bs;
- X#endif
- X
- X for (np = mh.m_name; *np; np++)
- X if (*np == '_')
- X *np = ' ';
- X
- X buf[H_NLENOFF] = n = np - mh.m_name;
- X strncpy(buf + H_NAMEOFF, mh.m_name, n);
- X strncpy(buf + H_TYPEOFF, mh.m_type, 4);
- X strncpy(buf + H_AUTHOFF, mh.m_author, 4);
- X put2(buf + H_FLAGOFF, mh.m_flags & ~F_LOCKED);
- X if (pre_beta) {
- X put4(buf + H_OLD_DLENOFF, mh.m_datalen);
- X put4(buf + H_OLD_RLENOFF, mh.m_rsrclen);
- X } else {
- X put4(buf + H_DLENOFF, mh.m_datalen);
- X put4(buf + H_RLENOFF, mh.m_rsrclen);
- X
- 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 put4(buf + H_CTIMOFF, mh.m_createtime + tdiff);
- X put4(buf + H_MTIMOFF, mh.m_modifytime + tdiff);
- X }
- X if (fp == NULL) {
- X fp = fopen(files.f_info, "w");
- X if (fp == NULL) {
- X perror("info file");
- X exit(-1);
- X }
- X }
- X if (macbinary == 1) {
- X if (buf[74] & 0x40)
- X buf[81] = '\1'; /* protected */
- X buf[74] = '\0'; /* MacBinary identifiers */
- X buf[82] = '\0';
- X }
- X fwrite(buf, 1, DATABYTES, fp);
- X fclose(fp);
- X fp = NULL;
- X}
- X
- X/* eat characters until header detected, return which format */
- Xfind_header()
- X{
- X int c, at_bol;
- X char ibuf[BUFSIZ];
- X
- X /* look for "(This file ...)" line */
- X while (fgets(ibuf, BUFSIZ, ifp) != NULL) {
- X if (strncmp(ibuf, "(This file", 10) == 0)
- X break;
- X }
- X at_bol = 1;
- X while ((c = getc(ifp)) != EOF) {
- X switch (c) {
- X case '\n':
- X case '\r':
- X at_bol = 1;
- X break;
- X case ':':
- X if (at_bol) /* q format */
- X return 1;
- X break;
- X case '#':
- X if (at_bol) { /* old format */
- X ungetc(c, ifp);
- X return 0;
- X }
- X break;
- X default:
- X at_bol = 0;
- X break;
- X }
- X }
- X
- X fprintf(stderr, "unexpected EOF\n");
- X exit(2);
- X /* NOTREACHED */
- X}
- X
- Xstatic unsigned int crc;
- X
- Xshort get2q();
- Xlong get4q();
- X
- X/* read header of .hqx file */
- Xdo_q_header(macname)
- X char *macname;
- X{
- X char namebuf[256]; /* big enough for both att & bsd */
- X int n;
- X int calc_crc, file_crc;
- X
- X crc = 0; /* compute a crc for the header */
- X q_init(); /* reset static variables */
- X
- X n = getq(); /* namelength */
- X n++; /* must read trailing null also */
- X getqbuf(namebuf, n); /* read name */
- X if (macname[0] == '\0')
- X macname = namebuf;
- X
- X n = strlen(macname);
- X if (n > NAMEBYTES)
- X n = NAMEBYTES;
- X strncpy(mh.m_name, macname, n);
- X mh.m_name[n] = '\0';
- X
- X getqbuf(mh.m_type, 4);
- X getqbuf(mh.m_author, 4);
- X mh.m_flags = get2q();
- X mh.m_datalen = get4q();
- X mh.m_rsrclen = get4q();
- X
- X comp_q_crc(0);
- X comp_q_crc(0);
- X calc_crc = crc;
- X file_crc = get2q();
- X verify_crc(calc_crc, file_crc);
- X}
- X
- Xdo_q_fork(fname, len)
- X char *fname;
- X register long len;
- X{
- X register int c, i;
- X int calc_crc, file_crc;
- X
- X if (macbinary != 1) {
- X if (fp != NULL) {
- X fclose(fp);
- X }
- X fp = fopen(fname, "w");
- X if (fp == NULL) {
- X perror(fname);
- X exit(-1);
- X }
- X }
- X crc = 0; /* compute a crc for a fork */
- X
- X if (len)
- X for (i = 0; i < len; i++) {
- X if ((c = getq()) == EOF) {
- X fprintf(stderr, "unexpected EOF\n");
- X exit(2);
- X }
- X putc(c, fp);
- X }
- X
- X comp_q_crc(0);
- X comp_q_crc(0);
- X calc_crc = crc;
- X file_crc = get2q();
- X verify_crc(calc_crc, file_crc);
- X if (macbinary != 1) {
- X fclose(fp);
- X fp = NULL;
- X }
- X}
- X
- X/* verify_crc(); -- check if crc's check out */
- Xverify_crc(calc_crc, file_crc)
- X unsigned int calc_crc, file_crc;
- X{
- X calc_crc &= WORDMASK;
- X file_crc &= WORDMASK;
- X
- X if (calc_crc != file_crc) {
- X fprintf(stderr, "CRC error\n---------\n");
- X fprintf(stderr, "CRC in file:\t0x%x\n", file_crc);
- X fprintf(stderr, "calculated CRC:\t0x%x\n", calc_crc);
- X exit(3);
- X }
- X}
- X
- Xstatic int eof;
- Xstatic char obuf[3];
- Xstatic char *op, *oend;
- X
- X/* initialize static variables for q format input */
- Xq_init()
- X{
- X eof = 0;
- X op = obuf;
- X oend = obuf + sizeof obuf;
- X}
- X
- X/* get2q(); q format -- read 2 bytes from input, return short */
- Xshort
- Xget2q()
- X{
- X register int c;
- X short value = 0;
- X
- X c = getq();
- X value = (c & BYTEMASK) << 8;
- X c = getq();
- X value |= (c & BYTEMASK);
- X
- X return value;
- X}
- X
- X/* get4q(); q format -- read 4 bytes from input, return long */
- Xlong
- Xget4q()
- X{
- X register int c, i;
- X long value = 0L;
- X
- X for (i = 0; i < 4; i++) {
- X c = getq();
- X value <<= 8;
- X value |= (c & BYTEMASK);
- X }
- X return value;
- X}
- X
- X/* getqbuf(); q format -- read n characters from input into buf */
- X/* All or nothing -- no partial buffer allowed */
- Xgetqbuf(buf, n)
- X register char *buf;
- X register int n;
- X{
- X register int c, i;
- X
- X for (i = 0; i < n; i++) {
- X if ((c = getq()) == EOF)
- X return EOF;
- X *buf++ = c;
- X }
- X return 0;
- X}
- X
- X#define RUNCHAR 0x90
- X
- X/* q format -- return one byte per call, keeping track of run codes */
- Xgetq()
- X{
- X register int c;
- X
- X if ((c = getq_nocrc()) == EOF)
- X return EOF;
- X comp_q_crc(c);
- X return c;
- X}
- X
- Xgetq_nocrc()
- X{
- X static int rep, lastc;
- X int c;
- X
- X if (rep) {
- X rep--;
- X return lastc;
- X }
- X if ((c = getq_raw()) == EOF) {
- X return EOF;
- X }
- X if (c == RUNCHAR) {
- X if ((rep = getq_raw()) == EOF)
- X return EOF;
- X if (rep == 0) {
- X return RUNCHAR;
- X } else {
- X /* already returned one, about to return another */
- X rep -= 2;
- X return lastc;
- X }
- X } else {
- X lastc = c;
- X return c;
- X }
- X}
- X
- X/* q format -- return next 8 bits from file without interpreting run codes */
- Xgetq_raw()
- X{
- X char ibuf[4];
- X register char *ip = ibuf, *iend = ibuf + sizeof ibuf;
- X int c;
- X
- X if (op == obuf) {
- X for (ip = ibuf; ip < iend; ip++) {
- X if ((c = get6bits()) == EOF)
- X if (ip <= &ibuf[1])
- X return EOF;
- X else if (ip == &ibuf[2])
- X eof = 1;
- X else
- X eof = 2;
- X *ip = c;
- X }
- X obuf[0] = (ibuf[0] << 2 | ibuf[1] >> 4);
- X obuf[1] = (ibuf[1] << 4 | ibuf[2] >> 2);
- X obuf[2] = (ibuf[2] << 6 | ibuf[3]);
- X }
- X if ((eof) & (op >= &obuf[eof]))
- X return EOF;
- X c = *op++;
- X if (op >= oend)
- X op = obuf;
- X return (c & BYTEMASK);
- X}
- X
- Xchar tr[] = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
- X
- X/* q format -- decode one byte into 6 bit binary */
- Xget6bits()
- X{
- X register int c;
- X register char *where;
- X
- X while (1) {
- X c = getc(ifp);
- X switch (c) {
- X case '\n':
- X case '\r':
- X continue;
- X case ':':
- X case EOF:
- X return EOF;
- X default:
- X where = tr;
- X while (*where != '\0' && *where != c)
- X where++;
- X if (*where == c)
- X return (where - tr);
- X else {
- X fprintf(stderr, "bad char\n");
- X return EOF;
- X }
- X }
- X }
- X}
- X
- X#define CRCCONSTANT 0x1021
- X
- Xcomp_q_crc(c)
- X register unsigned int c;
- X{
- X register int i;
- X register unsigned long temp = crc;
- X
- X for (i = 0; i < 8; i++) {
- X c <<= 1;
- X if ((temp <<= 1) & WORDBIT)
- X temp = (temp & WORDMASK) ^ CRCCONSTANT;
- X temp ^= (c >> 8);
- X c &= BYTEMASK;
- X }
- X crc = temp;
- X}
- X
- X/* old format -- process .hex and .hcx files */
- Xdo_o_header(macname, filename)
- X char *macname, *filename;
- X{
- X char namebuf[256]; /* big enough for both att & bsd */
- X char ibuf[BUFSIZ];
- X int n;
- X
- X /* set up name for output files */
- X if (macname[0] == '\0') {
- X strcpy(namebuf, filename);
- X
- X /* strip directories */
- X macname = search_last(namebuf, '/');
- X if (macname == NULL)
- X macname = namebuf;
- X else
- X macname++;
- X
- X /* strip extension */
- X n = strlen(macname);
- X if (n > 4) {
- X n -= 4;
- X if (macname[n] == '.' && macname[n + 1] == 'h'
- X && macname[n + 3] == 'x')
- X macname[n] = '\0';
- X }
- X }
- X n = strlen(macname);
- X if (n > NAMEBYTES)
- X n = NAMEBYTES;
- X strncpy(mh.m_name, macname, n);
- X mh.m_name[n] = '\0';
- X
- X /* read "#TYPEAUTH$flag" line */
- X if (fgets(ibuf, BUFSIZ, ifp) == NULL) {
- X fprintf(stderr, "unexpected EOF\n");
- X exit(2);
- X }
- X n = strlen(ibuf);
- X if (n >= 7 && ibuf[0] == '#' && ibuf[n - 6] == '$') {
- X if (n >= 11)
- X strncpy(mh.m_type, &ibuf[1], 4);
- X if (n >= 15)
- X strncpy(mh.m_author, &ibuf[5], 4);
- X sscanf(&ibuf[n - 5], "%4hx", &mh.m_flags);
- X }
- X}
- X
- Xdo_o_forks()
- X{
- X char ibuf[BUFSIZ];
- X int forks = 0, found_crc = 0;
- X int calc_crc, file_crc;
- X extern long make_file();
- X
- X crc = 0; /* calculate a crc for both forks */
- X
- X /* create empty files ahead of time */
- X if (macbinary != 1) {
- X close(creat(files.f_data, 0666));
- X close(creat(files.f_rsrc, 0666));
- X }
- X while (!found_crc && fgets(ibuf, BUFSIZ, ifp) != NULL) {
- X if (forks == 0 && strncmp(ibuf, "***COMPRESSED", 13) == 0) {
- X compressed++;
- X continue;
- X }
- X if (strncmp(ibuf, "***DATA", 7) == 0) {
- X mh.m_datalen = make_file(files.f_data, compressed);
- X forks++;
- X continue;
- X }
- X if (strncmp(ibuf, "***RESOURCE", 11) == 0) {
- X mh.m_rsrclen = make_file(files.f_rsrc, compressed);
- X forks++;
- X continue;
- X }
- X if (compressed && strncmp(ibuf, "***CRC:", 7) == 0) {
- X found_crc++;
- X calc_crc = crc;
- X sscanf(&ibuf[7], "%x", &file_crc);
- X break;
- X }
- X if (!compressed && strncmp(ibuf, "***CHECKSUM:", 12) == 0) {
- X found_crc++;
- X calc_crc = crc & BYTEMASK;
- X sscanf(&ibuf[12], "%x", &file_crc);
- X file_crc &= BYTEMASK;
- X break;
- X }
- X }
- X
- X if (found_crc)
- X verify_crc(calc_crc, file_crc);
- X else {
- X fprintf(stderr, "missing CRC\n");
- X exit(3);
- X }
- X}
- X
- Xlong
- Xmake_file(fname, compressed)
- X char *fname;
- X int compressed;
- X{
- X char ibuf[BUFSIZ];
- X register long nbytes = 0;
- X
- X if (macbinary != 1) {
- X if (fp != NULL)
- X fclose(fp);
- X fp = fopen(fname, "w");
- X if (fp == NULL) {
- X perror(fname);
- X exit(-1);
- X }
- X }
- X while (fgets(ibuf, BUFSIZ, ifp) != NULL) {
- X if (strncmp(ibuf, "***END", 6) == 0)
- X break;
- X if (compressed)
- X nbytes += comp_to_bin(ibuf, fp);
- X else
- X nbytes += hex_to_bin(ibuf, fp);
- X }
- X if (macbinary != 1) {
- X fclose(fp);
- X fp = NULL;
- X }
- X return nbytes;
- X}
- X
- Xcomp_c_crc(c)
- X unsigned char c;
- X{
- X crc = (crc + c) & WORDMASK;
- X crc = ((crc << 3) & WORDMASK) | (crc >> 13);
- X}
- X
- Xcomp_e_crc(c)
- X unsigned char c;
- X{
- X crc += c;
- X}
- X
- X#define SIXB(c) (((c)-0x20) & 0x3f)
- X
- Xcomp_to_bin(ibuf, outf)
- X char ibuf[];
- XFILE *outf;
- X{
- X char obuf[BUFSIZ];
- X register char *ip = ibuf;
- X register char *op = obuf;
- X register int n, outcount;
- X int numread, incount;
- X
- X numread = strlen(ibuf);
- X ip[numread - 1] = ' '; /* zap out the newline */
- X outcount = (SIXB(ip[0]) << 2) | (SIXB(ip[1]) >> 4);
- X incount = ((outcount / 3) + 1) * 4;
- X for (n = numread; n < incount; n++) /* restore lost spaces */
- X ibuf[n] = ' ';
- X
- X n = 0;
- X while (n <= outcount) {
- X *op++ = SIXB(ip[0]) << 2 | SIXB(ip[1]) >> 4;
- X *op++ = SIXB(ip[1]) << 4 | SIXB(ip[2]) >> 2;
- X *op++ = SIXB(ip[2]) << 6 | SIXB(ip[3]);
- X ip += 4;
- X n += 3;
- X }
- X
- X for (n = 1; n <= outcount; n++)
- X comp_c_crc(obuf[n]);
- X
- X fwrite(obuf + 1, 1, outcount, outf);
- X return outcount;
- X}
- X
- Xhex_to_bin(ibuf, outf)
- X char ibuf[];
- XFILE *outf;
- X{
- X register char *ip = ibuf;
- X register int n, outcount;
- X int c;
- X
- X n = strlen(ibuf) - 1;
- X outcount = n / 2;
- X for (n = 0; n < outcount; n++) {
- X c = hexit(*ip++);
- X comp_e_crc(c = (c << 4) | hexit(*ip++));
- X fputc(c, outf);
- X }
- X return outcount;
- X}
- X
- Xhexit(c)
- X int c;
- X{
- X if ('0' <= c && c <= '9')
- X return c - '0';
- X if ('A' <= c && c <= 'F')
- X return c - 'A' + 10;
- X
- X fprintf(stderr, "illegal hex digit: %c", c);
- X exit(4);
- X /* NOTREACHED */
- X}
- X
- Xput2(bp, value)
- X char *bp;
- X short value;
- X{
- X *bp++ = (value >> 8) & BYTEMASK;
- X *bp++ = value & BYTEMASK;
- X}
- X
- Xput4(bp, value)
- X char *bp;
- X long value;
- X{
- X register int i, c;
- X
- X for (i = 0; i < 4; i++) {
- X c = (value >> 24) & BYTEMASK;
- X value <<= 8;
- X *bp++ = c;
- X }
- X}
- !Funky!Stuff!
- echo x - xbinary
- sed -e 's/^X//' > xbinary << '!Funky!Stuff!'
- X#!/bin/csh
- X# Shell script for always running xbin in MacBinary mode. Make this
- X# executable and put it in your search path.
- Xxbin -b $*
- !Funky!Stuff!
- exit
-
-