mirror of
https://github.com/wnayes/macutils.git
synced 2024-12-22 01:30:15 +00:00
365 lines
7.6 KiB
C
365 lines
7.6 KiB
C
#ifdef TYPES_H
|
|
#include <sys/types.h>
|
|
#endif /* TYPES_H */
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include "globals.h"
|
|
#include "crc.h"
|
|
#include "readline.h"
|
|
#include "../util/masks.h"
|
|
#include "../util/util.h"
|
|
#include "../util/patchlevel.h"
|
|
#include "../fileio/wrfile.h"
|
|
#include "../fileio/wrfileopt.h"
|
|
#include "../fileio/machdr.h"
|
|
#include "../fileio/kind.h"
|
|
#include "../util/curtime.h"
|
|
#include "hexbin.h"
|
|
|
|
#define LOCALOPT "ilvcn:qVH"
|
|
|
|
extern void backtrans();
|
|
#ifdef DL
|
|
extern void dl();
|
|
#endif /* DL */
|
|
#ifdef HECX
|
|
extern void hecx();
|
|
#endif /* HECX */
|
|
#ifdef HQX
|
|
extern void hqx();
|
|
#endif /* HQX */
|
|
#ifdef MU
|
|
extern void mu();
|
|
#endif /* MU */
|
|
|
|
static void usage();
|
|
static void do_files();
|
|
static int find_header();
|
|
|
|
static char options[128];
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
char *filename;
|
|
char macname[32];
|
|
extern int optind;
|
|
extern char *optarg;
|
|
int errflg;
|
|
int c;
|
|
|
|
set_wrfileopt(0);
|
|
(void)strcat(options, get_wrfileopt());
|
|
(void)strcat(options, LOCALOPT);
|
|
errflg = 0;
|
|
filename = "";
|
|
macname[0] = 0;
|
|
|
|
while((c = getopt(argc, argv, options)) != EOF) {
|
|
if(!wrfileopt((char)c)) {
|
|
switch(c) {
|
|
case 'l':
|
|
listmode++;
|
|
break;
|
|
case 'v':
|
|
verbose++;
|
|
break;
|
|
case 'i':
|
|
info_only++;
|
|
break;
|
|
case 'c':
|
|
uneven_lines++;
|
|
break;
|
|
case 'n':
|
|
backtrans(macname, optarg);
|
|
break;
|
|
case '?':
|
|
errflg++;
|
|
break;
|
|
case 'H':
|
|
give_wrfileopt();
|
|
(void)fprintf(stderr, "Hexbin specific options:\n");
|
|
(void)fprintf(stderr,
|
|
"-i:\tgive information only, do not convert\n");
|
|
(void)fprintf(stderr, "-l:\tgive listing\n");
|
|
(void)fprintf(stderr,
|
|
"-v:\tgive verbose listing, including lines skipped\n");
|
|
(void)fprintf(stderr,
|
|
"-c:\tdo not check for equal line lengths\n");
|
|
(void)fprintf(stderr, "-n nm:\tname to be generated\n");
|
|
(void)fprintf(stderr,
|
|
"-V:\tgive information about this version\n");
|
|
(void)fprintf(stderr, "-H:\tthis message\n");
|
|
(void)fprintf(stderr, "Default is silent conversion\n");
|
|
exit(0);
|
|
case 'V':
|
|
(void)fprintf(stderr, "Version %s, ", VERSION);
|
|
(void)fprintf(stderr, "patchlevel %d", PATCHLEVEL);
|
|
(void)fprintf(stderr, "%s.\n", get_mina());
|
|
(void)fprintf(stderr, "Hexified files recognized:\n");
|
|
#ifdef DL
|
|
(void)fprintf(stderr, "\tDownload (.dl)\n");
|
|
#endif /* DL */
|
|
#ifdef HECX
|
|
(void)fprintf(stderr, "\tBinHex 2.0 (.hex)\n");
|
|
(void)fprintf(stderr, "\tBinHex 3.0 (.hcx)\n");
|
|
#endif /* HECX */
|
|
#ifdef HQX
|
|
(void)fprintf(stderr, "\tBinHex 4.0 (.hqx)\n");
|
|
#endif /* HQX */
|
|
#ifdef MU
|
|
(void)fprintf(stderr, "\tUUTool (.mu)\n");
|
|
#endif /* MU */
|
|
exit(0);
|
|
}
|
|
}
|
|
}
|
|
if(errflg) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
if(info_only || verbose) {
|
|
listmode++;
|
|
}
|
|
|
|
do {
|
|
if(optind == argc) {
|
|
filename = "-";
|
|
} else {
|
|
filename = argv[optind];
|
|
optind++;
|
|
#ifdef SCAN
|
|
do_idf(filename, UNIX_NAME);
|
|
#endif /* SCAN */
|
|
}
|
|
do_files(filename, macname);
|
|
} while(optind < argc);
|
|
exit(0);
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
static char *extensions[] = {
|
|
#ifdef DL
|
|
".dl",
|
|
#endif /* DL */
|
|
#ifdef HECX
|
|
".hex",
|
|
".Hex",
|
|
".hcx",
|
|
".Hcx",
|
|
#endif /* HECX */
|
|
#ifdef HQX
|
|
".hqx",
|
|
".Hqx",
|
|
#endif /* HQX */
|
|
#ifdef MU
|
|
".mu",
|
|
#endif /* MU */
|
|
"",
|
|
NULL
|
|
};
|
|
|
|
static void do_files(filename, macname)
|
|
char *filename; /* input file name -- extension optional */
|
|
char *macname; /* name to use on the mac side of things */
|
|
{
|
|
char namebuf[256];
|
|
char **ep;
|
|
struct stat stbuf;
|
|
long curtime;
|
|
int qformat;
|
|
int again;
|
|
|
|
if(filename[0] == '-') {
|
|
ifp = stdin;
|
|
filename = "stdin";
|
|
} else {
|
|
/* find input file and open it */
|
|
for(ep = extensions; *ep != NULL; ep++) {
|
|
(void)sprintf(namebuf, "%s%s", filename, *ep);
|
|
if(stat(namebuf, &stbuf) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if(*ep == NULL) {
|
|
perror(namebuf);
|
|
exit(1);
|
|
}
|
|
ifp = fopen(namebuf, "r");
|
|
if(ifp == NULL) {
|
|
perror(namebuf);
|
|
exit(1);
|
|
}
|
|
}
|
|
again = 0;
|
|
nexttry:
|
|
if(ifp == stdin) {
|
|
curtime = (long)time((time_t *)0) + TIMEDIFF;
|
|
mh.m_createtime = curtime;
|
|
mh.m_modifytime = curtime;
|
|
} else {
|
|
mh.m_createtime = stbuf.st_mtime + TIMEDIFF;
|
|
mh.m_modifytime = stbuf.st_mtime + TIMEDIFF;
|
|
}
|
|
|
|
qformat = find_header(again); /* eat mailer header &cetera, intuit format */
|
|
|
|
switch (qformat) {
|
|
#ifdef DL
|
|
case form_dl:
|
|
dl(macname, filename);
|
|
break;
|
|
#endif /* DL */
|
|
#ifdef HECX
|
|
case form_hecx:
|
|
hecx(macname, filename);
|
|
break;
|
|
#endif /* HECX */
|
|
#ifdef HQX
|
|
case form_hqx:
|
|
hqx(macname);
|
|
again = 1;
|
|
goto nexttry;
|
|
#endif /* HQX */
|
|
#ifdef MU
|
|
case form_mu:
|
|
mu(macname);
|
|
again = 1;
|
|
goto nexttry;
|
|
#endif /* MU */
|
|
default:
|
|
break;
|
|
}
|
|
(void)fclose(ifp);
|
|
}
|
|
|
|
/* eat characters until header detected, return which format */
|
|
static int find_header(again)
|
|
int again;
|
|
{
|
|
int c, dl_start, llen;
|
|
char *cp;
|
|
char header[INFOBYTES];
|
|
int ds, rs;
|
|
|
|
if(again && was_macbin) {
|
|
while(to_read-- > 0) {
|
|
c = fgetc(ifp);
|
|
}
|
|
}
|
|
was_macbin = 0;
|
|
c = fgetc(ifp);
|
|
(void)ungetc(c, ifp);
|
|
if(c == 0) {
|
|
was_macbin = 1;
|
|
if(fread(header, 1, INFOBYTES, ifp) != INFOBYTES) {
|
|
(void)fprintf(stderr, "Premature EOF\n");
|
|
#ifdef SCAN
|
|
do_error("hexbin: Premature EOF");
|
|
#endif /* SCAN */
|
|
exit(1);
|
|
}
|
|
ds = get4(header + I_DLENOFF);
|
|
rs = get4(header + I_RLENOFF);
|
|
ds = (((ds + 127) >> 7) << 7);
|
|
rs = (((rs + 127) >> 7) << 7);
|
|
to_read = ds + rs;
|
|
if(strncmp(header + I_TYPEOFF, "TEXT", 4)) {
|
|
(void)fprintf(stderr, "This file is not a proper BinHexed file.\n");
|
|
#ifdef SCAN
|
|
do_error("hexbin: not a proper BinHexed file");
|
|
#endif /* SCAN */
|
|
exit(1);
|
|
}
|
|
if(listmode) {
|
|
(void)fprintf(stderr, "This file is probably packed by ");
|
|
if(!strncmp(header + I_AUTHOFF, "BNHQ", 4)) {
|
|
(void)fprintf(stderr, "\"BinHex\"");
|
|
} else if(!strncmp(header + I_AUTHOFF, "BthX", 4)) {
|
|
(void)fprintf(stderr, "\"BinHqx\"");
|
|
} else if(!strncmp(header + I_AUTHOFF, "BnHq", 4)) {
|
|
(void)fprintf(stderr, "\"StuffIt\"");
|
|
} else if(!strncmp(header + I_AUTHOFF, "ttxt", 4)) {
|
|
(void)fprintf(stderr, "\"Compactor\"");
|
|
} else if(!strncmp(header + I_AUTHOFF, "BSWU", 4)) {
|
|
(void)fprintf(stderr, "\"UUTool\"");
|
|
} else {
|
|
(void)fprintf(stderr, "an unknown program");
|
|
}
|
|
(void)fprintf(stderr, ".\n");
|
|
}
|
|
}
|
|
/* look for "(This file ...)" or "(Convert with...)" line. */
|
|
/* or for "begin " */
|
|
/* dl format starts with a line containing only the symbols '@' to 'O',
|
|
or '|'. */
|
|
while(readline()) {
|
|
llen = strlen(line);
|
|
#ifdef HQX
|
|
if((strncmp(line, "(This file", 10) == 0) ||
|
|
(strncmp(line, "(Convert with", 13) == 0)) {
|
|
if(verbose) {
|
|
(void)fprintf(stderr, "Skip:%s\n", line);
|
|
}
|
|
break;
|
|
}
|
|
#endif /* HQX */
|
|
#ifdef MU
|
|
if(strncmp(line, "begin ", 6) == 0) {
|
|
return form_mu;
|
|
}
|
|
#endif /* MU */
|
|
#ifdef DL
|
|
/* Do not allow bogus false starts */
|
|
if(llen > 40 && (llen & 1) == 0) {
|
|
dl_start = 1;
|
|
for(cp = &line[0]; *cp != 0; cp++) {
|
|
if((*cp < '@' || *cp > 'O') && *cp != '|') {
|
|
dl_start = 0;
|
|
break;
|
|
}
|
|
}
|
|
if(dl_start && cp > &line[1]) {
|
|
return form_dl;
|
|
}
|
|
}
|
|
#endif /* DL */
|
|
if(llen != 0 && verbose) {
|
|
(void)fprintf(stderr, "Skip:%s\n", line);
|
|
}
|
|
}
|
|
while(readline()) {
|
|
switch (line[0]) {
|
|
#ifdef HQX
|
|
case ':':
|
|
return form_hqx;
|
|
#endif /* HQX */
|
|
#ifdef HECX
|
|
case '#':
|
|
return form_hecx;
|
|
#endif /* HECX */
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!again) {
|
|
(void)fprintf(stderr, "unexpected EOF\n");
|
|
#ifdef SCAN
|
|
do_error("hexbin: unexpected EOF");
|
|
#endif /* SCAN */
|
|
exit(1);
|
|
}
|
|
return form_none;
|
|
}
|
|
|
|
static void usage()
|
|
{
|
|
(void)fprintf(stderr, "Usage: hexbin [-%s] [filenames]\n", options);
|
|
(void)fprintf(stderr, "Use \"hexbin -H\" for help.\n");
|
|
}
|
|
|