Create macutils repository

This commit is contained in:
Will Nayes 2018-03-22 19:30:02 -05:00
commit 72ea2b578a
162 changed files with 17091 additions and 0 deletions

483
README Executable file
View File

@ -0,0 +1,483 @@
This is version 2.0b3 of macutil (22-OCT-1992).
This package contains the following utilities:
macunpack
hexbin
macsave
macstream
binhex
tomac
frommac
Requirements:
a. Of course a C compiler.
b. A 32-bit machine with large memory (or at least the ability to 'malloc'
large chunks of memory). For reasons of efficiency and simplicity the
programs work 'in-core', also many files are first read in core.
If somebody can take the trouble to do it differently, go ahead!
There are also probably in a number of places implicit assumptions that
an int is 32 bits. If you encounter such occurrences feel free to
notify me.
c. A Unix (tm) machine, or something very close. There are probably quite
a lot of Unix dependencies. Also here, if you have replacements, feel
free to send comments.
d. This version normally uses the 'mkdir' system call available on BSD Unix
and some versions of SysV Unix. You can change that, see the makefile for
details.
File name translation:
The programs use a table driven program to do Mac filename -> Unix filename
translation. When compiled without further changes the translation is as
follows:
Printable ASCII characters except space and slash are not changed.
Slash and space are changed to underscore, as are all characters that
do not fall in the following group.
Accented letters are translated to their unaccented counterparts.
If your system supports the Latin-1 character set, you can change this
translation scheme by specifying '-DLATIN1' for the 'CF' macro in the
makefile. This will translate all accented letters (and some symbols)
to their Latin-1 counterpart. This feature is untested (I do not have
access to systems that cater for Latin-1), so use with care.
Future revisions of the program will have user settable conversions.
Another feature of filename translation is that when the -DNODOT flag is
specified in the CF macro an initial period will be translated to underscore.
MacBinary stream:
Most programs allow MacBinary streams as either input or output. A
MacBinary stream is a series of files in MacBinary format pasted
together. Embedded within a MacBinary stream can be information about
folders. So a MacBinary stream can contain all information about a
folder and its constituents.
Appleshare support:
Optionally the package can be compiled for systems that support the sharing
of Unix and Mac filesystems. The package supports AUFS (AppleTalk Unix File
Server) from CAP (Columbia AppleTalk Package) and AppleDouble (from Apple).
It will not support both at the same time. Moreover this support requires
the existence of the 'mkdir' system call. And finally, as implemented it
probably will work on big-endian BSD compatible systems. If you have a SysV
system with restricted filename lengths you can get problems. I do not know
also whether the structures are stored native or Apple-wise on little-endian
systems. And also, I did not test it fully; having no access to either AUFS
or AppleDouble systems.
Acknowledgements:
a. Macunpack is for a large part based on the utilities 'unpit' and 'unsit'
written by:
Allan G. Weber
weber%brand.usc.edu@oberon.usc.edu
(wondering whether that is still valid!). I combined the two into a
single program and did a lot of modification. For information on the
originals, see the files README.unpit and README.unsit.
b. The crc-calculating routines are based on a routine originally written by:
Mark G. Mendel
UUCP: ihnp4!umn-cs!hyper!mark
(this will not work anymore for sure!). Also here I modified the stuff
and expanded it, see the files README.crc and README.crc.orig.
c. LZW-decompression is taken from the sources of compress that are floating
around. Probably I did not use the most efficient version, but this
program was written to get it done. The version I based it on (4.0) is
authored by:
Steve Davies (decvax!vax135!petsd!peora!srd)
Jim McKie (decvax!mcvax!jim) (Hi Jim!)
Joe Orost (decvax!vax135!petsd!joe)
Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
Ken Turkowski (decvax!decwrl!turtlevax!ken)
James A. Woods (decvax!ihnp4!ames!jaw)
I am sure those e-mail addresses also will not work!
d. Optional AUFS support comes from information supplied by:
Casper H.S. Dik
University of Amsterdam
Kruislaan 409
1098 SJ Amsterdam
Netherlands
phone: +31205922022
email: casper@fwi.uva.nl
This is an e-mail address that will workm but the address and phone
number ar no longer valid.
See the makefile.
Some caveats are applicable:
1. I did not fully test it (we do not use it). But the unpacking
appears to be correct. Anyhow, as the people who initially compile
it and use it will be system administrators I am confident they are
able to locate bugs! (What if an archive contains a Macfile with
the name .finderinfo or .resource? I have had two inputs for AUFS
support [I took Caspers; his came first], but both do not deal with
that. Does CAP deal with it?) Also I have no idea whether this
version supports it under SysV, so beware.
2. From one of the README's supplied by Casper:
Files will not appear in an active folder, because Aufs doesn't like
people working behind it's back.
Simply opening and closing the folder will suffice.
Appears to be the same problem as when you are unpacking or in some
other way creating files in a folder open to multifinder. I have seen
bundle bits disappear this way. So if after unpacking you see the
generic icon; check whether a different icon should appear and check
the bundle bit.
The desktop isn't updated, but that doesn't seem to matter.
I dunno, not using it.
e. Man pages are now supplied. The base was provided by:
Douglas Siebert
ISCA
dsiebert@icaen.uiowa.edu
f. Because of some problems the Uncompactor has been rewritten, it is now
based on sources from the dearchiver unzip (of PC fame). Apparently the
base code is by:
Samuel H. Smith
I have no further address available, but as soon as I find a better
attribution, I will include it.
g. UnstuffIt's LZAH code comes from lharc (also of PC fame) by:
Haruhiko Okumura,
Haruyasu Yoshizaki,
Yooichi Tagawa.
h. Zoom's code comes from information supplied by Jon W{tte
(d88-jwa@nada.kth.se). The Zoo decompressor is based on the routine
written by Rahul Dhesi (dhesi@cirrus.COM). This again is based on
code by Haruhiko Okumura. See also the file README.zoom.
i. MacLHa's decompressors are identical to the ones mentioned in g and h.
j. Most of hexbin's code is based on code written/modified by:
Dave Johnson, Brown University Computer Science
Darin Adler, TMQ Software
Jim Budler, amdcad!jimb
Dan LaLiberte, liberte@uiucdcs
ahm (?)
Jeff Meyer, John Fluke Company
Guido van Rossum, guido@cwi.nl (Hi!)
(most of the e-mail addresses will not work, the affiliation may also
be incorrect by now.) See also the file README.hexbin.
k. The dl code in hexbin comes is based on the original distribution of
SUMacC.
l. The mu code in hexbin is a slight modification of the hcx code (the
compressions are identical).
m. The MW code for StuffIt is loosely based on code by Daniel H. Bernstein
(brnstnd@acf10.nyu.edu).
n. Tomac and frommac are loosely based on the original macput and macget
by (the e-mail address will not work anymore):
Dave Johnson
ddj%brown@csnet-relay.arpa
Brown University Computer Science
-------------------------------------------------------------------------------
Macunpack will unpack PackIt, StuffIt, Diamond, Compactor/Compact Pro, most
StuffItClassic/StuffItDeluxe, and all Zoom and LHarc/MacLHa archives, and
archives created by later versions of DiskDoubler.
Also it will decode files created by BinHex5.0, MacBinary, UMCP,
Compress It, ShrinkToFit, MacCompress, DiskDoubler and AutoDoubler.
(PackIt, StuffIt, Diamond, Compactor, Compact/Pro, Zoom and LHarc/MacLHa are
archivers written by respectively: Harry R. Chesley, Raymond Lau, Denis Sersa,
Bill Goodman, Jon W{tte* and Kazuaki Ishizaki. BinHex 5.0, MacBinary and
UMCP are by respectively: Yves Lempereur, Gregory J. Smith, Information
Electronics. ShrinkToFit is by Roy T. Hashimoto, Compress It by Jerry
Whitnell, and MacCompress, DiskDoubler and AutoDoubler are all by
Lloyd Chambers.)
* from his signature:
Jon W{tte - Yes, that's a brace - Damn Swede.
Actually it is an a with two dots above; some (German inclined) people
refer to it (incorrectly) as a-umlaut.
It does not deal with:
a. Password protected archives.
b. Multi-segment archives.
c. Plugin methods for Zoom.
d. MacLHa archives not packed in MacBinary mode (the program deals very
poorly with that!).
Background:
There are millions of ways to pack files, and unfortunately, all have been
implemented one way or the other. Below I will give some background
information about the packing schemes used by the different programs
mentioned above. But first some background about compression (I am no
expert, more comprehensive information can be found in for instance:
Tomothy Bell, Ian H. Witten and John G. Cleary, Modelling for Text
Compression, ACM Computing Surveys, Vol 21, No 4, Dec 1989, pp 557-591).
Huffman encoding (also called Shannon-Fano coding or some other variation
of the name). An encoding where the length of the code for the symbols
depends on the frequency of the symbols. Frequent symbols have shorter
codes than infrequent symbols. The normal method is to first scan the
file to be compressed, and to assign codes when this is done (see for
instance: D. E. Knuth, the Art of Computer Programming). Later methods
have been designed to create the codes adaptively; for a survey see:
Jeremy S. Vetter, Design and Analysis of Dynamic Huffman Codes, JACM,
Vol 34, No 4, Oct 1987, pp 825-845.
LZ77: The first of two Ziv-Lempel methods. Using a window of past encoded
text, output consists of triples for each sequence of newly encoded
symbols: a back pointer and length of past text to be repeated and the
first symbol that is not part of that sequence. Later versions allowed
deviation from the strict alternation of pointers and uncoded symbols
(LZSS by Bell). Later Brent included Huffman coding of the pointers
(LZH).
LZ78: While LZ77 uses a window of already encoded text as a dictionary,
LZ78 dynamically builds the dictionary. Here again pointers are strictly
alternated with unencoded new symbols. Later Welch (LZW) managed to
eliminate the output of unencoded symbols. This algorithm is about
the same as the one independently invented by Miller and Wegman (MW).
A problem with these two schemes is that they are patented. Thomas
modified LZW to LZC (as used in the Unix compress command). While LZ78
and LZW become static once the dictionary is full, LZC has possibilities
to reset the dictionary. Many LZC variants are in use, depending on the
size of memory available. They are distinguished by the maximum number
of bits that are used in a code.
A number of other schemes are proposed and occasionally used. The main
advantage of the LZ type schemes is that (especially) decoding is fairly fast.
Programs background:
Plain programs:
BinHex 5.0:
Unlike what its name suggest this is not a true successor of BinHex 4.0.
BinHex 5.0 takes the MacBinary form of a file and stores it in the data
fork of the newly created file.
Although BinHex 5.0 does not create BinHex 4.0 compatible files, StuffIt
will give the creator type of BinHex 5.0 (BnHq) to its binhexed files,
rather than the creator type of BinHex 4.0 (BNHQ). The program knows
about that.
MacBinary:
As its name suggests, it does the same as BinHex 5.0.
UMCP:
Looks similar, but the file as stored by UMCP is not true MacBinary.
Size fields are modified, the result is not padded to a multiple of 128,
etc. Macunpack deals with all that, but until now is not able to
correctly restore the finder flags of the original file. Also, UMCP
created files have type "TEXT" and creator "ttxt", which can create a
bit of confusion. Macunpack will recognize these files only if the
creator has been modified to "UMcp".
Compressors:
ShrinkToFit:
This program uses a Huffman code to compress. It has an option (default
checked for some reason), COMP, for which I do not yet know the
meaning. Compressing more than a single file in a single run results
in a failure for the second and subsequent files.
Compress It:
Also uses a Huffman code to compress.
MacCompress:
MacCompress has two modes of operation, the first mode is (confusingly)
MacCompress, the second mode is (again confusingly) UnixCompress. In
MacCompress mode both forks are compressed using the LZC algorithm.
In UnixCompress mode only the data fork is compressed, and some shuffling
of resources is performed. Upto now macunpack only deals with MacCompress
mode. The LZC variant MacCompress uses depends on memory availability.
12 bit to 16 bit LZC can be used.
Archivers:
ArcMac:
Nearly PC-Arc compatible. Arc knows 8 compression methods, I have seen
all of them used by ArcMac, except the LZW techniques. Here they are:
1: No compression, shorter header
2: No compression
3: (packing) Run length encoding
4: (squeezing) RLE followed by Huffman encoding
5: (crunching) LZW
6: (crunching) RLE followed by LZW
7: (crunching) as the previous but with a different hash function
8: (crunching) RLE followed by 12-bit LZC
9: (squashing) 13-bit LZC
PackIt:
When archiving a file PackIt either stores the file uncompressed or
stores the file Huffman encoded. In the latter case both forks are
encoded using the same Huffman tree.
StuffIt and StuffIt Classic/Deluxe:
These have the ability to use different methods for the two forks of a
file. The following standard methods I do know about (the last three
are only used by the Classic/Deluxe version 2.0 of StuffIt):
0: No compression
1: Run length encoding
2: 14-bit LZC compression
3: Huffman encoding
5: LZAH: like LZH, but the Huffman coding used is adaptive
6: A Huffman encoding using a fixed (built-in) Huffman tree
8: A MW encoding
Diamond:
Uses a LZ77 like frontend plus a Fraenkel-Klein like backend (see
Apostolico & Galil, Combinatorial Algorithms on Words, pages 169-183).
Compactor/Compact Pro:
Like StuffIt, different encodings are possible for data and resource fork.
Only two possible methods are used:
0: Run length encoding
1: RLE followed by some form of LZH
Zoom:
Data and resource fork are compressed with the same method. The standard
uses either no compression or some form of LZH
MacLHa:
Has two basic modes of operation, Mac mode and Normal mode. In Mac mode
the file is archived in MacBinary form. In normal mode only the forks
are archived. Normal mode should not be used (and can not be unpacked
by macunpack) as all information about data fork size/resource fork size,
type, creator etc. is lost. It knows quite a few methods, some are
probably only used in older versions, the only methods I have seen used
are -lh0-, -lh1- and -lh5-. Methods known by MacLHa:
-lz4-: No compression
-lz5-: LZSS
-lzs-: LZSS, another variant
-lh0-: No compression
-lh1-: LZAH (see StuffIt)
-lh2-: Another form of LZAH
-lh3-: A form of LZH, different from the next two
-lh4-: LZH with a 4096 byte buffer (as far as I can see the coding in
MacLHa is wrong)
-lh5-: LZH with a 8192 byte buffer
DiskDoubler:
The older version of DiskDoubler is compatible with MacCompress. It does
not create archives, it only compresses files. The newer version (since
3.0) does both archiving and compression. The older version uses LZC as
its compression algorithm, the newer version knows a number of different
compression algorithms. Many (all?) are algorithms used in other
archivers. Probably this is done to simplify conversion from other formats
to DiskDoubler format archives. I have seen actual DiskDoubler archives
that used methods 0, 1 and 8:
0: No compression
1: LZC
2: unknown
3: RLE
4: Huffman (or no compression)
5: unknown
6: unknown
7: An improved form of LZSS
8: Compactor/Compact Pro compatible RLE/LZH or RLE only
9: unknown
The DiskDoubler archive format contains many subtle twists that make it
difficult to properly read the archive (or perhaps this is on purpose?).
Naming:
Some people have complained about the name conflict with the unpack utility
that is already available on Sys V boxes. I had forgotten it, so there
really was a problem. The best way to solve it was to trash pack/unpack/pcat
and replace it by compress/uncompress/zcat. Sure, man uses it; but man uses
pcat, so you can retain pcat. If that was not an option you were able to feel
free to rename the program. But finally I relented. It is now macunpack.
When you have problems unpacking an archive feel free to ask for information.
I am especially keen when the program detects an unknown method. If you
encounter such an archive, please, mail a 'binhexed' copy of the archive
to me so that I can deal with it. Password protected archives are (as
already stated) not implemented. I do not have much inclination to do that.
Also I feel no inclination to do multi-segment archives.
-------------------------------------------------------------------------------
Hexbin will de-hexify files created in BinHex 4.0 compatible format (hqx)
but also the older format (dl, hex and hcx). Moreover it will uudecode
files uuencoded by UUTool (the only program I know that does UU hexification
of all Mac file information).
There are currently many programs that are able to create files in BinHex 4.0
compatible format. There are however some slight differences, and most
de-hexifiers are not able to deal with all the variations. This program is
very simple minded. First it will intuit (based on the input) whether the
file is in dl, hex, hcx or hqx format. Next it will de-hexify the file.
When the format is hqx, it will check whether more files follow, and continue
processing. So you can catenate multiple (hqx) hexified files together and
feed them as a single file to hexbin. Also hexbin does not mind whether lines
are separated by CR's, LF's or combinations of the two. Moreover, it will
strip all leading, trailing and intermediate garbage introduced by mailers
etc. Next, it does not mind if a file is not terminated by a CR or an LF
(as StuffIt 1.5.1 and earlier did), but in that case a second file is not
allowed to follow it. Last, while most hexifiers output lines of equal length,
some do not. Hexbin will deal with that, but there are some caveats; see the
-c option in the man page.
Background:
dl format:
This was the first hexified format used. Programs to deal with it came
from SUMacC. This format only coded resource forks, 4 bits in a byte.
hex format:
I think this is the first format from Yves Lempereur. Like dl format,
it codes 4 bits in a byte, but is able to code both resource and
data fork. Is it BinHex 2.0?
hcx format:
A compressing variant of hex format. Codes 6 bits in a byte.
Is it BinHex 3.0?
hqx format:
Like hcx, but using a different coding (possibly to allow for ASCII->EBCDIC
and EBCDIC->ASCII translation, which not always results in an identical
file). Moreover this format also encodes the original Mac filename.
mu format:
The conversion can be done by the UUTool program from Octavian Micro
Development. It encodes both forks and also some finder info. You will
in general not use this with uudecode on non Mac systems, with uudecode
only the data fork will be uudecoded. UU hexification is well known (and
fairly old) in Unix environments. Moreover it has been ported to lots of
other systems.
-------------------------------------------------------------------------------
Macsave reads a MacBinary stream from standard input and writes the
files according to the options.
-------------------------------------------------------------------------------
Macstream reads files from the Unix host and will output a MacBinary stream
containing all those files together with information about the directory
structure.
-------------------------------------------------------------------------------
Binhex will read a MacBinary stream, or will read files/directories as
indicated on the command line, and will output all files in binhexed (.hqx)
format. Information about the directory structure is lost.
-------------------------------------------------------------------------------
Tomac will transmit a MacBinary stream, or named files to the Mac using
the XMODEM protocol.
-------------------------------------------------------------------------------
Frommac will receive one or more files from the Mac using the XMODEM protocol.
-------------------------------------------------------------------------------
This is an ongoing project, more stuff will appear.
All comments are still welcome. Thanks for the comments I already received.
dik t. winter, amsterdam, nederland
email: dik@cwi.nl
--
Note:
In these programs all algorithms are implemented based on publicly available
software to prevent any claim that would prevent redistribution due to
Copyright. Although parts of the code would indeed fall under the Copyright
by the original author, use and redistribution of all such code is explicitly
allowed. For some parts of it the GNU software license does apply.
--
Appendix.
BinHex 4.0 compatible file creators:
Type Creator Created by
"TEXT" "BthX" BinHqx
"TEXT" "BNHQ" BinHex
"TEXT" "BnHq" StuffIt and StuffIt Classic
"TEXT" "ttxt" Compactor
Files recognized by macunpack:
Type Creator Recognized as
"APPL" "DSEA" "DiskDoubler" Self extracting
"APPL" "EXTR" "Compactor" Self extracting
"APPL" "Mooz" "Zoom" Self extracting
"APPL" "Pack" "Diamond" Self extracting
"APPL" "arc@" "ArcMac" Self extracting (not yet)
"APPL" "aust" "StuffIt" Self extracting
"ArCv" "TrAS" "AutoSqueeze" (not yet)
"COMP" "STF " "ShrinkToFit"
"DD01" "DDAP" "DiskDoubler"
"DDAR" "DDAP" "DiskDoubler"
"DDF." "DDAP" "DiskDoubler" (any fourth character)
"DDf." "DDAP" "DiskDoubler" (any fourth character)
"LARC" "LARC" "MacLHa (LHARC)"
"LHA " "LARC" "MacLHa (LHA)"
"PACT" "CPCT" "Compactor"
"PIT " "PIT " "PackIt"
"Pack" "Pack" "Diamond"
"SIT!" "SIT!" "StuffIt"
"SITD" "SIT!" "StuffIt Deluxe"
"Smal" "Jdw " "Compress It"
"TEXT" "BnHq" "BinHex 5.0"
"TEXT" "GJBU" "MacBinary 1.0"
"TEXT" "UMcp" "UMCP"
"ZIVM" "LZIV" "MacCompress(M)"
"ZIVU" "LZIV" "MacCompress(U)" (not yet)
"mArc" "arc*" "ArcMac" (not yet)
"zooM" "zooM" "Zoom"

174
binhex/binhex.c Executable file
View File

@ -0,0 +1,174 @@
#include <stdio.h>
#include "../fileio/machdr.h"
#include "../fileio/rdfile.h"
#include "../util/patchlevel.h"
extern char *malloc();
extern char *realloc();
extern char *strcat();
extern void exit();
extern void transname();
extern void do_indent();
extern void dofile();
#define LOCALOPT "RilqVH"
static void usage();
static char options[128];
static char *dir_stack;
static int dir_ptr = -64;
static int dir_max;
int dorep = 1;
int main(argc, argv)
int argc;
char **argv;
{
int c, i, j, n;
extern int optind;
extern char *optarg;
int errflg;
char text[32], ftype[5], fauth[5];
int dir_skip = 0, write_it, query = 0, list = 0, info_only = 0;
int indent = 0;
(void)strcat(options, get_rdfileopt());
(void)strcat(options, LOCALOPT);
errflg = 0;
while((c = getopt(argc, argv, options)) != EOF) {
if(!rdfileopt((char)c)) {
switch(c) {
case 'R':
dorep = 0;
break;
case 'l':
list++;
break;
case 'q':
query++;
break;
case 'i':
info_only++;
break;
case '?':
errflg++;
break;
case 'H':
give_rdfileopt();
(void)fprintf(stderr, "Binhex specific options:\n");
(void)fprintf(stderr, "-r:\tdo not use run length encoding\n");
(void)fprintf(stderr,
"-i:\tgive information only, do not write\n");
(void)fprintf(stderr, "-l:\tgive listing\n");
(void)fprintf(stderr,
"-q:\tquery for every file/folder before writing\n");
(void)fprintf(stderr,
"-V:\tgive information about this version\n");
(void)fprintf(stderr, "-H:\tthis message\n");
(void)fprintf(stderr, "Default is silent writing\n");
exit(0);
case 'V':
(void)fprintf(stderr, "Version %s, ", VERSION);
(void)fprintf(stderr, "patchlevel %d", PATCHLEVEL);
(void)fprintf(stderr, "%s.\n", get_minb());
exit(0);
}
}
}
if(errflg) {
usage();
exit(1);
}
if(info_only || query) {
list++;
}
setup(argc - optind, argv + optind);
while((i = nextfile()) != ISATEND) {
if(dir_skip) {
if(i == ISDIR) {
dir_skip++;
} else if(i == ENDDIR) {
dir_skip--;
}
continue;
}
write_it = 1;
n = file_info[I_NAMEOFF] & 0x7f;
transname(file_info + I_NAMEOFF + 1, text, n);
if(i == ISFILE) {
transname(file_info + I_TYPEOFF, ftype, 4);
transname(file_info + I_AUTHOFF, fauth, 4);
}
if(list) {
if(i == ISFILE) {
do_indent(indent);
(void)fprintf(stderr,
"name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
text, ftype, fauth, (long)data_size, (long)rsrc_size);
} else if(i == ISDIR) {
do_indent(indent);
dir_ptr += 64;
if(dir_ptr == dir_max) {
if(dir_max == 0) {
dir_stack = malloc(64);
} else {
dir_stack = realloc(dir_stack, (unsigned)dir_max + 64);
}
dir_max += 64;
if(dir_stack == NULL) {
(void)fprintf(stderr, "Insufficient memory\n");
exit(1);
}
}
for(j = 0; j <= n; j++) {
dir_stack[dir_ptr + j] = text[j];
}
(void)fprintf(stderr, "folder=\"%s\"", text);
indent++;
} else {
indent--;
do_indent(indent);
(void)fprintf(stderr, "leaving folder \"%s\"",
dir_stack + dir_ptr);
dir_ptr -= 64;
}
if(info_only) {
write_it = 0;
}
if(query) {
if(i != ENDDIR) {
write_it = do_query();
} else {
(void)fputc('\n', stderr);
}
if(!write_it && i == ISDIR) {
dir_skip = 1;
indent--;
dir_ptr -= 64;
}
} else {
(void)fputc('\n', stderr);
}
}
if(write_it) {
if(i == ISFILE) {
dofile();
}
}
}
exit(0);
/* NOTREACHED */
}
static void usage()
{
(void)fprintf(stderr, "Usage: binhex [-%s] [files]\n", options);
(void)fprintf(stderr, "Use \"binhex -H\" for help.\n");
}

192
binhex/dofile.c Executable file
View File

@ -0,0 +1,192 @@
#include "../fileio/machdr.h"
#include "../fileio/rdfile.h"
extern int dorep;
extern unsigned long binhex_crcinit;
extern unsigned long binhex_updcrc();
#define RUNCHAR 0x90
static int pos_ptr;
static char codes[] =
"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
static int state;
static int savebits;
static int rep_char;
static int rep_count;
void doheader();
void dofork();
void outbyte();
void finish();
void outbyte1();
void out6bit();
void outchar();
void dofile()
{
(void)printf("(This file must be converted; you knew that already.)\n");
(void)printf("\n");
pos_ptr = 1;
state = 0;
rep_char = -1;
rep_count = 0;
outchar(':');
doheader();
dofork(data_fork, data_size);
dofork(rsrc_fork, rsrc_size);
finish();
(void)putchar(':');
(void)putchar('\n');
}
void doheader()
{
unsigned long crc;
int i, n;
crc = binhex_crcinit;
n = file_info[I_NAMEOFF];
crc = binhex_updcrc(crc, file_info + I_NAMEOFF, n + 1);
for(i = 0; i <= n; i++) {
outbyte(file_info[I_NAMEOFF + i]);
}
n = 0;
crc = binhex_updcrc(crc, (char *)&n, 1);
outbyte(0);
crc = binhex_updcrc(crc, file_info + I_TYPEOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_TYPEOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_AUTHOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_AUTHOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_FLAGOFF, 2);
for(i = 0; i < 2; i++) {
outbyte(file_info[I_FLAGOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_DLENOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_DLENOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_RLENOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_RLENOFF + i]);
}
outbyte((int)(crc >> 8));
outbyte((int)(crc & 0xff));
}
void dofork(fork, size)
char *fork;
int size;
{
unsigned long crc;
int i;
crc = binhex_updcrc(binhex_crcinit, fork, size);
for(i = 0; i < size; i++) {
outbyte(fork[i]);
}
outbyte((int)(crc >> 8));
outbyte((int)(crc & 0xff));
}
void outbyte(b)
int b;
{
b &= 0xff;
if(dorep && (b == rep_char)) {
if(++rep_count == 254) {
outbyte1(RUNCHAR);
outbyte1(255);
rep_char = -1;
rep_count = 0;
}
} else {
if(rep_count > 0) {
if(rep_count > 3) {
outbyte1(RUNCHAR);
outbyte1(rep_count + 1);
} else {
while(rep_count-- > 0) {
outbyte1(rep_char);
}
}
}
outbyte1(b);
if(b == RUNCHAR) {
outbyte1(0);
rep_char = -1;
} else {
rep_char = b;
}
rep_count = 0;
}
}
void finish()
{
if(rep_count > 0) {
if(rep_count > 3) {
outbyte1(RUNCHAR);
outbyte1(rep_count + 1);
} else {
while(rep_count-- > 0) {
outbyte1(rep_char);
}
}
}
switch(state) {
case 1:
out6bit(savebits << 4);
break;
case 2:
out6bit(savebits << 2);
break;
default:
break;
}
}
void outbyte1(b)
int b;
{
switch(state) {
case 0:
out6bit(b >> 2);
savebits = b & 0x3;
state = 1;
break;
case 1:
b |= (savebits << 8);
out6bit(b >> 4);
savebits = b & 0xf;
state = 2;
break;
case 2:
b |= (savebits << 8);
out6bit(b >> 6);
out6bit(b & 0x3f);
state = 0;
break;
}
}
void out6bit(c)
char c;
{
outchar(codes[c & 0x3f]);
}
void outchar(c)
char c;
{
(void)putchar(c);
if(++pos_ptr > 64) {
(void)putchar('\n');
pos_ptr = 1;
}
}

51
binhex/makefile Executable file
View File

@ -0,0 +1,51 @@
CFLAGS = -O $(CF)
SRCS = binhex.c dofile.c
OBJS = binhex.o dofile.o
LIB = ../crc/libcrc.a
TNAME = ../util/transname
BNAME = ../util/backtrans
UNAME = ../util/util
INAME = ../fileio/rdfile
GNAME = ../fileio/fileglob
XOBJS = $(TNAME).o $(BNAME).o $(UNAME).o $(INAME).o $(GNAME).o
XSRCS = $(TNAME).c $(BNAME).c $(UNAME).c $(INAME).c $(GNAME).c
binhex: $(OBJS) $(XOBJS) $(LIB)
$(CC) $(CFLAGS) -o binhex $(OBJS) $(XOBJS) $(LIB)
$(LIB): ../crc/makecrc.c
(cd ../crc; make CC=$(CC) CF="$(CF)" )
$(TNAME).o: $(TNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(BNAME).o: $(BNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(UNAME).o: $(UNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(INAME).o: $(INAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
$(GNAME).o: $(GNAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
lint:
lint $(CF) $(LFLAGS) $(SRCS) $(XSRCS)
clean:
-rm -f *.o
clobber:clean
-rm -f binhex
binhex.o: ../fileio/machdr.h
binhex.o: ../fileio/rdfile.h
binhex.o: ../util/patchlevel.h
dofile.o: ../fileio/machdr.h
dofile.o: ../fileio/rdfile.h

4
comm/comm.h Executable file
View File

@ -0,0 +1,4 @@
#define XM /* Know about XMODEM */
#undef YM /* Know about YMODEM */
#undef ZM /* Know about ZMODEM */

167
comm/frommac.c Executable file
View File

@ -0,0 +1,167 @@
#include <stdio.h>
#include "comm.h"
#include "../util/patchlevel.h"
#include "../fileio/machdr.h"
#include "globals.h"
#include "../fileio/fileglob.h"
#include "../fileio/wrfile.h"
#define LOCALOPT "lmxyzoTVH"
extern void exit();
extern void setup_tty();
extern void reset_tty();
extern char info[];
static void usage();
static char options[128];
static int multi_file = 0;
static int listmode = 0;
int main(argc, argv)
int argc;
char **argv;
{
extern int optind;
extern char *optarg;
int errflg;
int c;
char tname[64];
char fauth[5];
char ftype[5];
set_wrfileopt(0);
(void)strcat(options, get_wrfileopt());
(void)strcat(options, LOCALOPT);
errflg = 0;
while((c = getopt(argc, argv, options)) != EOF) {
if(!wrfileopt((char)c)) {
switch(c) {
case 'l':
listmode++;
break;
case 'm':
multi_file++;
break;
case 'x':
xfertype = XMODEM;
#ifndef XM
(void)fprintf(stderr, "XMODEM not supported\n");
exit(1);
#else /* XM */
break;
#endif /* XM */
case 'y':
xfertype = YMODEM;
#ifndef YM
(void)fprintf(stderr, "YMODEM not supported\n");
exit(1);
#else /* YM */
break;
#endif /* YM */
case 'z':
xfertype = ZMODEM;
#ifndef ZM
(void)fprintf(stderr, "ZMODEM not supported\n");
exit(1);
#else /* ZM */
break;
#endif /* ZM */
case 'o':
pre_beta++;
break;
case 'T':
time_out++;
break;
case '?':
errflg++;
break;
case 'H':
give_wrfileopt();
(void)fprintf(stderr, "Frommac specific options:\n");
(void)fprintf(stderr, "-l:\tgive listing\n");
(void)fprintf(stderr, "-m:\tmulti-file transfer\n");
#ifdef XM
(void)fprintf(stderr, "-x:\tuse XMODEM protocol\n");
#endif /* XM */
#ifdef YM
(void)fprintf(stderr, "-y:\tuse YMODEM protocol\n");
#endif /* YM */
#ifdef ZM
(void)fprintf(stderr, "-z:\tuse ZMODEM protocol\n");
#endif /* ZM */
(void)fprintf(stderr, "-o:\tuse pre-beta protocol\n");
(void)fprintf(stderr, "-T:\tdetect time-outs\n");
(void)fprintf(stderr,
"-V:\tgive information about this version\n");
(void)fprintf(stderr, "-H:\tthis message\n");
(void)fprintf(stderr,
"Default is silent receival of a single file using XMODEM\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, "Supported protocols:\n");
#ifdef XM
(void)fprintf(stderr, "\tXMODEM\n");
#endif /* XM */
#ifdef YM
(void)fprintf(stderr, "\tYMODEM\n");
#endif /* YM */
#ifdef ZM
(void)fprintf(stderr, "\tZMODEM\n");
#endif /* ZM */
exit(0);
}
}
}
if(errflg) {
usage();
exit(1);
}
do {
setup_tty();
switch(xfertype) {
case XMODEM:
#ifdef XM
xm_from();
break;
#endif /* XM */
#ifdef YM
case YMODEM:
ym_from();
break;
#endif /* YM */
#ifdef ZM
case ZMODEM:
zm_from();
break;
#endif /* ZM */
}
reset_tty();
if(listmode) {
transname(info + I_NAMEOFF + 1, tname, info[I_NAMEOFF]);
transname(info + I_AUTHOFF, fauth, 4);
transname(info + I_TYPEOFF, ftype, 4);
(void)fprintf(stderr,
"name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
tname, ftype, fauth,
get4(info + I_DLENOFF), get4(info + I_RLENOFF));
(void)fprintf(stderr, "\n");
}
} while(multi_file);
exit(0);
/* NOTREACHED */
}
static void usage()
{
(void)fprintf(stderr, "Usage: frommac [-%s]\n", options);
(void)fprintf(stderr, "Use \"frommac -H\" for help.\n");
}

6
comm/globals.c Executable file
View File

@ -0,0 +1,6 @@
#include "globals.h"
int xfertype = XMODEM;
int pre_beta = 0;
int time_out = 0;

8
comm/globals.h Executable file
View File

@ -0,0 +1,8 @@
#define XMODEM 0
#define YMODEM 1
#define ZMODEM 2
extern int xfertype;
extern int pre_beta;
extern int time_out;

91
comm/makefile Executable file
View File

@ -0,0 +1,91 @@
CFLAGS = -O $(CF)
SRCS1 = tomac.c xm_to.c ym_to.c zm_to.c tty.c globals.c
SRCS2 = frommac.c xm_from.c ym_from.c zm_from.c tty.c globals.c
OBJS1 = tomac.o xm_to.o ym_to.o zm_to.o tty.o globals.o
OBJS2 = frommac.o xm_from.o ym_from.o zm_from.o tty.o globals.o
LIB = ../crc/libcrc.a
TNAME = ../util/transname
BNAME = ../util/backtrans
UNAME = ../util/util
INAME = ../fileio/rdfile
ONAME = ../fileio/wrfile
GNAME = ../fileio/fileglob
XOBJS1 = $(TNAME).o $(BNAME).o $(UNAME).o $(INAME).o $(GNAME).o
XOBJS2 = $(TNAME).o $(UNAME).o $(ONAME).o $(GNAME).o
XSRCS1 = $(TNAME).c $(BNAME).c $(UNAME).c $(INAME).c $(GNAME).c
XSRCS2 = $(TNAME).c $(UNAME).c $(ONAME).c $(GNAME).c
all: tomac frommac
touch all
tomac: $(OBJS1) $(XOBJS1)
$(CC) $(CFLAGS) -o tomac $(OBJS1) $(XOBJS1)
frommac: $(OBJS2) $(XOBJS2)
$(CC) $(CFLAGS) -o frommac $(OBJS2) $(XOBJS2)
$(LIB): ../crc/makecrc.c
(cd ../crc; make CC=$(CC) CF="$(CF)" )
$(TNAME).o: $(TNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(BNAME).o: $(BNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(UNAME).o: $(UNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(INAME).o: $(INAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
$(ONAME).o: $(ONAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
$(GNAME).o: $(GNAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
lint:
lint $(CF) $(LFLAGS) $(SRCS1) $(XSRCS)
clean:
-rm -f *.o
clobber:clean
-rm -f all tomac frommac
tomac.o: comm.h
tomac.o: ../fileio/machdr.h
tomac.o: ../fileio/rdfile.h
tomac.o: ../util/patchlevel.h
tomac.o: globals.h
xm_to.o: comm.h
xm_to.o: ../fileio/machdr.h
xm_to.o: ../fileio/rdfile.h
xm_to.o: ../util/masks.h
xm_to.o: globals.h
xm_to.o: protocol.h
ym_to.o: comm.h
zm_to.o: comm.h
frommac.o: comm.h
frommac.o: ../util/patchlevel.h
frommac.o: ../fileio/machdr.h
frommac.o: globals.h
frommac.o: ../fileio/fileglob.h
frommac.o: ../fileio/wrfile.h
xm_from.o: comm.h
xm_from.o: ../fileio/machdr.h
xm_from.o: ../fileio/wrfile.h
xm_from.o: ../util/masks.h
xm_from.o: globals.h
xm_from.o: protocol.h
ym_from.o: comm.h
zm_from.o: comm.h
globals.o: globals.h
tty.o: ../util/masks.h
tty.o: protocol.h
tty.o: globals.h

22
comm/protocol.h Executable file
View File

@ -0,0 +1,22 @@
#define RECORDBYTES 132
#define DATABYTES 128
#define NAMEBYTES 63
#define RETRIES 10
#define SOHTIMO 10
#define ACKTIMO 10
#define LINTIMO 20
#define CHRTIMO 2
#define MAXRECNO 0xff
#define TMO -1
#define DUP '\000'
#define SOH '\001'
#define EOT '\004'
#define ACK '\006'
#define NAK '\025'
#define CAN '\030'
#define EEF '\032'
#define ESC '\033'

242
comm/tomac.c Executable file
View File

@ -0,0 +1,242 @@
#include <stdio.h>
#include "comm.h"
#include "../fileio/machdr.h"
#include "../fileio/rdfile.h"
#include "../util/patchlevel.h"
#include "globals.h"
extern char *malloc();
extern char *realloc();
extern char *strcat();
extern void exit();
extern void transname();
extern void do_indent();
extern void dofile();
extern void setup_tty();
extern void reset_tty();
#define LOCALOPT "ilqxyzoTVH"
static void usage();
static char options[128];
static char *dir_stack;
static int dir_ptr = -64;
static int dir_max;
int main(argc, argv)
int argc;
char **argv;
{
int c, i, j, n;
extern int optind;
extern char *optarg;
int errflg;
char text[32], ftype[5], fauth[5];
int dir_skip = 0, write_it, query = 0, list = 0, info_only = 0;
int indent = 0;
(void)strcat(options, get_rdfileopt());
(void)strcat(options, LOCALOPT);
errflg = 0;
while((c = getopt(argc, argv, options)) != EOF) {
if(!rdfileopt((char)c)) {
switch(c) {
case 'l':
list++;
break;
case 'q':
query++;
break;
case 'i':
info_only++;
break;
case 'o':
pre_beta++;
case 'x':
xfertype = XMODEM;
#ifndef XM
(void)fprintf(stderr, "XMODEM not supported\n");
exit(1);
#else /* XM */
break;
#endif /* XM */
case 'y':
xfertype = YMODEM;
#ifndef YM
(void)fprintf(stderr, "YMODEM not supported\n");
exit(1);
#else /* YM */
break;
#endif /* YM */
case 'z':
xfertype = ZMODEM;
#ifndef ZM
(void)fprintf(stderr, "ZMODEM not supported\n");
exit(1);
#else /* ZM */
break;
#endif /* ZM */
case 'T':
time_out++;
break;
case '?':
errflg++;
break;
case 'H':
give_rdfileopt();
(void)fprintf(stderr, "Tomac specific options:\n");
(void)fprintf(stderr,
"-i:\tgive information only, do not write\n");
(void)fprintf(stderr, "-l:\tgive listing\n");
(void)fprintf(stderr,
"-q:\tquery for every file/folder before writing\n");
#ifdef XM
(void)fprintf(stderr, "-x:\tuse XMODEM protocol\n");
#endif /* XM */
#ifdef YM
(void)fprintf(stderr, "-y:\tuse YMODEM protocol\n");
#endif /* YM */
#ifdef ZM
(void)fprintf(stderr, "-z:\tuse ZMODEM protocol\n");
#endif /* ZM */
(void)fprintf(stderr, "-o:\tuse pre-beta protocol\n");
(void)fprintf(stderr, "-T:\tdetect time-outs\n");
(void)fprintf(stderr,
"-V:\tgive information about this version\n");
(void)fprintf(stderr, "-H:\tthis message\n");
(void)fprintf(stderr,
"Default is silent sending with XMODEM\n");
exit(0);
case 'V':
(void)fprintf(stderr, "Version %s, ", VERSION);
(void)fprintf(stderr, "patchlevel %d", PATCHLEVEL);
(void)fprintf(stderr, "%s.\n", get_minb());
(void)fprintf(stderr, "Supported protocols:\n");
#ifdef XM
(void)fprintf(stderr, "\tXMODEM\n");
#endif /* XM */
#ifdef YM
(void)fprintf(stderr, "\tYMODEM\n");
#endif /* YM */
#ifdef ZM
(void)fprintf(stderr, "\tZMODEM\n");
#endif /* ZM */
exit(0);
}
}
}
if(errflg) {
usage();
exit(1);
}
if(info_only || query) {
list++;
}
setup(argc - optind, argv + optind);
while((i = nextfile()) != ISATEND) {
if(dir_skip) {
if(i == ISDIR) {
dir_skip++;
} else if(i == ENDDIR) {
dir_skip--;
}
continue;
}
write_it = 1;
n = file_info[I_NAMEOFF] & 0x7f;
transname(file_info + I_NAMEOFF + 1, text, n);
if(i == ISFILE) {
transname(file_info + I_TYPEOFF, ftype, 4);
transname(file_info + I_AUTHOFF, fauth, 4);
}
if(list) {
if(i == ISFILE) {
do_indent(indent);
(void)fprintf(stderr,
"name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
text, ftype, fauth, (long)data_size, (long)rsrc_size);
} else if(i == ISDIR) {
do_indent(indent);
dir_ptr += 64;
if(dir_ptr == dir_max) {
if(dir_max == 0) {
dir_stack = malloc(64);
} else {
dir_stack = realloc(dir_stack, (unsigned)dir_max + 64);
}
dir_max += 64;
if(dir_stack == NULL) {
(void)fprintf(stderr, "Insufficient memory\n");
exit(1);
}
}
for(j = 0; j <= n; j++) {
dir_stack[dir_ptr + j] = text[j];
}
(void)fprintf(stderr, "folder=\"%s\"", text);
indent++;
} else {
indent--;
do_indent(indent);
(void)fprintf(stderr, "leaving folder \"%s\"",
dir_stack + dir_ptr);
dir_ptr -= 64;
}
if(info_only) {
write_it = 0;
}
if(query) {
if(i != ENDDIR) {
write_it = do_query();
} else {
(void)fputc('\n', stderr);
}
if(!write_it && i == ISDIR) {
dir_skip = 1;
indent--;
dir_ptr -= 64;
}
} else {
(void)fputc('\n', stderr);
}
}
if(write_it) {
if(i == ISFILE) {
setup_tty();
switch(xfertype) {
#ifdef XM
case XMODEM:
xm_to();
break;
#endif /* XM */
#ifdef YM
case YMODEM:
ym_to();
break;
#endif /* YM */
#ifdef ZM
case ZMODEM:
zm_to();
break;
#endif /* ZM */
}
reset_tty();
}
}
}
exit(0);
/* NOTREACHED */
}
static void usage()
{
(void)fprintf(stderr, "Usage: tomac [-%s] [files]\n", options);
(void)fprintf(stderr, "Use \"tomac -H\" for help.\n");
}

146
comm/tty.c Executable file
View File

@ -0,0 +1,146 @@
#include <stdio.h>
#include <signal.h>
#ifndef TERMIOS_H
#include <sgtty.h>
#else /* TERMIOS_H */
#include <termios.h>
#endif /* TERMIOS_H */
#include <setjmp.h>
#include "../util/masks.h"
#include "protocol.h"
#include "globals.h"
void cleanup();
void timedout();
int tgetc();
void tputc();
static jmp_buf timobuf;
#ifndef TERMIOS_H
static struct sgttyb otty, ntty;
#else /* TERMIOS_H */
static struct termios otty, ntty;
#endif /* TERMIOS_H */
static int ttyfd;
static int signal_set;
void setup_tty()
{
ttyfd = fileno(stderr);
if(!signal_set) {
(void)signal(SIGHUP, cleanup);
(void)signal(SIGINT, cleanup);
(void)signal(SIGQUIT, cleanup);
(void)signal(SIGTERM, cleanup);
if(time_out) {
(void)signal(SIGALRM, timedout);
}
signal_set = 1;
}
#ifndef TERMIOS_H
(void)ioctl(ttyfd, TIOCGETP, &otty);
ntty = otty;
ntty.sg_flags = RAW | ANYP;
(void)ioctl(ttyfd, TIOCSETP, &ntty);
#else /* TERMIOS_H */
(void)tcgetattr(ttyfd, &otty);
ntty = otty;
ntty.c_lflag &= ~(ICANON | ISIG | ECHO);
ntty.c_iflag &= IXOFF;
ntty.c_oflag &= ~(OPOST);
ntty.c_cflag &= ~(PARENB | PARODD);
ntty.c_cc[VMIN] = 1;
ntty.c_cc[VTIME] = 0;
(void)tcsetattr(ttyfd, TCSAFLUSH, &ntty);
#endif /* TERMIOS_H */
}
void reset_tty()
{
(void)sleep(1); /* Wait for output to drain */
#ifndef TERMIOS_H
(void)ioctl(ttyfd, TIOCSETP, &otty);
#else /* TERMIOS_H */
(void)tcsetattr(ttyfd, TCSAFLUSH, &otty);
#endif /* TERMIOS_H */
}
void cleanup(sig) int sig;
{
reset_tty();
exit(sig);
}
void timedout()
{
(void)signal(SIGALRM, timedout);
longjmp(timobuf, 1);
}
int tgetc(timeout)
int timeout;
{
char c;
int i;
if(time_out) {
if(setjmp(timobuf)) {
return TMO;
}
(void)alarm(timeout);
}
i = read(ttyfd, &c, 1);
if(time_out) {
(void)alarm(0);
}
if(i == 0) {
return EOT;
} else {
return c & BYTEMASK;
}
}
tgetrec(buf, count, timeout)
char *buf;
int count, timeout;
{
int i, tot = 0, cc = count;
if(time_out) {
if(setjmp(timobuf)) {
return TMO;
}
(void)alarm(timeout);
}
while(tot < count) {
i = read(ttyfd, buf, cc);
if(i < 0) {
continue;
}
tot += i;
cc -= i;
buf += i;
}
if(time_out) {
(void)alarm(0);
}
return 0;
}
void tputc(c)
int c;
{
char cc;
cc = c & BYTEMASK;
(void)write(ttyfd, &cc, 1);
}
void tputrec(buf, count)
char *buf;
int count;
{
(void)write(ttyfd, buf, count);
}

164
comm/xm_from.c Executable file
View File

@ -0,0 +1,164 @@
#include "comm.h"
#ifdef XM
#include <stdio.h>
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../util/masks.h"
#include "globals.h"
#include "protocol.h"
extern int tgetc();
extern int tgetrec();
extern void tputc();
static void receive_part();
static int receive_sync();
static int receive_rec();
char info[INFOBYTES];
void xm_from()
{
unsigned long data_size, rsrc_size;
char text[64];
if(receive_sync() == ACK) {
receive_part(info, DATABYTES, 1);
transname(info + I_NAMEOFF + 1, text, info[I_NAMEOFF]);
define_name(text);
data_size = get4(info + I_DLENOFF);
rsrc_size = get4(info + I_RLENOFF);
start_info(info, rsrc_size, data_size);
start_data();
receive_part(out_buffer, data_size, 1);
start_rsrc();
receive_part(out_buffer, rsrc_size, 0);
end_file();
}
}
static void receive_part(info, size, more)
char *info;
int size, more;
{
int recno = 1, i, status, naks = 0;
status = 0;
while(status != EOT) {
status = receive_rec(info, DATABYTES, recno);
switch(status) {
case EOT:
if(!pre_beta) {
tputc(ACK);
}
if(more) {
tputc(NAK);
}
size = 0;
break;
case ACK:
tputc(ACK);
naks = 0;
size -= DATABYTES;
info += DATABYTES;
recno = (recno + 1) & MAXRECNO;
break;
case DUP:
tputc(ACK);
naks = 0;
break;
case NAK:
if(naks++ < RETRIES) {
tputc(NAK);
break;
}
case CAN:
tputc(CAN);
cleanup(-1);
}
}
}
static int receive_sync()
{
int c;
for(;;) {
c = tgetc(60);
switch(c) {
case ESC:
break;
case CAN:
cleanup();
break;
case EOT:
case TMO:
return c;
default:
continue;
}
c = tgetc(1);
if(c == 'a') {
break;;
}
}
tputc(ACK);
return ACK;
}
static int receive_rec(buf, bufsize, recno)
char *buf;
int bufsize, recno;
{
int i, cksum, c, rec, recbar;
char *bp;
c = tgetc(SOHTIMO);
switch(c) {
case EOT:
case CAN:
return c;
case SOH:
break;
case TMO:
default:
return NAK;
}
rec = tgetc(CHRTIMO);
if(rec == TMO) {
return NAK;
}
recbar = tgetc(CHRTIMO);
if(recbar == TMO) {
return NAK;
}
if(rec + recbar != MAXRECNO) {
return NAK;
}
if(tgetrec(buf, bufsize, LINTIMO) == TMO) {
return NAK;
}
bp = buf;
cksum = 0;
for(i = 0; i < bufsize; i++) {
cksum += *bp++ & BYTEMASK;
}
c = tgetc(CHRTIMO);
if(c == TMO) {
return NAK;
}
if(c != (cksum & BYTEMASK)) {
return NAK;
}
if(rec == recno - 1) {
return DUP;
}
if(rec != recno) {
return CAN;
}
return ACK;
}
#else /* XM */
int xm_from; /* Keep lint and some compilers happy */
#endif /* XM */

98
comm/xm_to.c Executable file
View File

@ -0,0 +1,98 @@
#include "comm.h"
#ifdef XM
#include "../fileio/machdr.h"
#include "../fileio/rdfile.h"
#include "../util/masks.h"
#include "globals.h"
#include "protocol.h"
extern int tgetc();
extern void tputc();
extern void tputrec();
static void send_part();
static int send_sync();
static void send_rec();
void xm_to()
{
if(send_sync() == ACK) {
send_part(file_info, DATABYTES, 1);
send_part(data_fork, data_size, 1);
send_part(rsrc_fork, rsrc_size, 0);
}
}
static void send_part(info, size, more)
char *info;
int size, more;
{
int recno = 1, i, status;
while(size > 0) {
for(i = 0; i < RETRIES; i++) {
send_rec(info, DATABYTES, recno);
status = tgetc(ACKTIMO);
if(status != NAK) {
break;
}
}
if(status == NAK || status == CAN) {
cleanup(-1);
}
size -= DATABYTES;
info += DATABYTES;
recno = (recno + 1) & MAXRECNO;
}
tputc(EOT);
if(!pre_beta) {
status = tgetc(ACKTIMO);
}
if(more) {
status = tgetc(ACKTIMO);
}
}
static int send_sync()
{
int c, i;
for(i = 0; i < 3; i++) {
tputc(ESC);
tputc('a');
while((c = tgetc(ACKTIMO)) != TMO) {
switch(c) {
case CAN:
case EOT:
case ACK:
return c;
default:
continue;
}
}
}
return CAN;
}
static void send_rec(buf, bufsize, recno)
char *buf;
int bufsize, recno;
{
int i, cksum;
char *bp;
cksum = 0;
bp = buf;
for(i = 0; i < bufsize; i++) {
cksum += *bp++ & BYTEMASK;
}
tputc(SOH);
tputc((unsigned char)recno);
tputc((unsigned char)(MAXRECNO - recno));
tputrec(buf, bufsize);
tputc((char)(cksum & BYTEMASK));
}
#else /* XM */
int xm_to; /* Keep lint and some compilers happy */
#endif /* XM */

5
comm/ym_from.c Executable file
View File

@ -0,0 +1,5 @@
#include "comm.h"
#ifdef YM
#else /* YM */
int ym_from; /* Keep lint and some compilers happy */
#endif /* YM */

5
comm/ym_to.c Executable file
View File

@ -0,0 +1,5 @@
#include "comm.h"
#ifdef YM
#else /* YM */
int ym_to; /* Keep lint and some compilers happy */
#endif /* YM */

5
comm/zm_from.c Executable file
View File

@ -0,0 +1,5 @@
#include "comm.h"
#ifdef ZM
#else /* ZM */
int zm_from; /* Keep lint and some compilers happy */
#endif /* ZM */

5
comm/zm_to.c Executable file
View File

@ -0,0 +1,5 @@
#include "comm.h"
#ifdef ZM
#else /* ZM */
int zm_to; /* Keep lint and some compilers happy */
#endif /* ZM */

55
crc/arc.c Normal file
View File

@ -0,0 +1,55 @@
unsigned long arc_crcinit = 0;
static unsigned short crctab[256] = {
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 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,
};
unsigned long arc_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xff
#define M2 0xff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc>>8)&M1)^crctab[(crc&0xff)^*cp++];
}
return(crc);
}

BIN
crc/arc.o Normal file

Binary file not shown.

55
crc/binhex.c Normal file
View File

@ -0,0 +1,55 @@
unsigned long binhex_crcinit = 0;
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
};
unsigned long binhex_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xff
#define M2 0xff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc<<8)&M2)^crctab[((crc>>8)&0xff)^*cp++];
}
return(crc);
}

BIN
crc/binhex.o Normal file

Binary file not shown.

55
crc/ccitt.c Normal file
View File

@ -0,0 +1,55 @@
unsigned long ccitt_crcinit = 65535;
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
};
unsigned long ccitt_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xff
#define M2 0xff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc<<8)&M2)^crctab[((crc>>8)&0xff)^*cp++];
}
return(crc);
}

BIN
crc/ccitt.o Normal file

Binary file not shown.

87
crc/ccitt32.c Normal file
View File

@ -0,0 +1,87 @@
unsigned long ccitt32_crcinit = -1;
static unsigned long crctab[256] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
};
unsigned long ccitt32_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xffffff
#define M2 0xffffff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc<<8)&M2)^crctab[((crc>>24)&0xff)^*cp++];
}
return(crc);
}

BIN
crc/ccitt32.o Normal file

Binary file not shown.

55
crc/kermit.c Normal file
View File

@ -0,0 +1,55 @@
unsigned long kermit_crcinit = 0;
static unsigned short crctab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78,
};
unsigned long kermit_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xff
#define M2 0xff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc>>8)&M1)^crctab[(crc&0xff)^*cp++];
}
return(crc);
}

BIN
crc/kermit.o Normal file

Binary file not shown.

BIN
crc/libcrc.a Normal file

Binary file not shown.

BIN
crc/makecrc Executable file

Binary file not shown.

155
crc/makecrc.c Executable file
View File

@ -0,0 +1,155 @@
/* This program will write six C routines for the calculation of
* the following CRC's. */
/* 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].
*/
/* This tables assumes CCITT is MSB first. Swapped means LSB first. In that
* case the polynomial is also swapped
*/
/* 16 bit crc's */
/* Value used by: CCITT KERMIT ARC BINHEX */
/* the poly: 0x1021 0x8408 0xA001 0x1021 */
/* original: 0x1021 0x1021 0x8005 0x1021 */
/* init value: -1 0 0 0 */
/* swapped: no yes yes no */
/* bits in CRC: 16 16 16 16 */
/* ARC used by LHARC, ZOO, STUFFIT */
/* BINHEX used by XMODEM, PACKIT */
/* 32 bit crc's */
/* Value used by: CCITT32 ZIP */
/* the poly: 0x04c11db7 0xedb88320 */
/* original: 0x04c11db7 0x04c11db7 */
/* init value: -1 -1 */
/* swapped no yes */
/* bits in CRC: 32 32 */
/* ZIP used by COMPACTOR */
#include <stdio.h>
extern void exit();
extern char *strcat();
static void initcrctab();
main()
{
initcrctab("ccitt", 0x1021, 0xffff, 0, 16);
initcrctab("kermit", 0x8408, 0, 1, 16);
initcrctab("arc", 0xa001, 0, 1, 16);
initcrctab("binhex", 0x1021, 0, 0, 16);
initcrctab("ccitt32",0x04c11db7,0xffffffff,0,32);
initcrctab("zip",0xedb88320,0xffffffff,1,32);
exit(0);
/*NOTREACHED*/
}
static void initcrctab(name, poly, init, swapped, bits)
char *name;
int poly, init, swapped, bits;
{
register int b, i;
unsigned short v;
unsigned long vv;
FILE *fd;
char buf[20];
buf[0] = 0;
(void)strcat(buf, name);
(void)strcat(buf, ".c");
if((fd = fopen(buf, "w")) == NULL) {
(void)fprintf(stderr, "Cannot open %s for writing\n", buf);
exit(1);
}
(void)fprintf(fd, "unsigned long %s_crcinit = %d;\n", name, init);
(void)fprintf(fd, "\n");
if(bits == 16) {
(void)fprintf(fd, "static unsigned short crctab[256] = {\n");
} else {
(void)fprintf(fd, "static unsigned long crctab[256] = {\n");
}
(void)fprintf(fd, " ");
if(bits == 16) {
for(b = 0; b < 256; ++b) {
if(swapped) {
for(v = b, i = 8; --i >= 0;)
v = v & 1 ? (v>>1)^poly : v>>1;
} else {
for(v = b<<8, i = 8; --i >= 0;)
v = v & 0x8000 ? (v<<1)^poly : v<<1;
}
(void)fprintf(fd, "0x%.4x,", v & 0xffff);
if((b&7) == 7) {
(void)fprintf(fd, "\n");
if(b != 255) (void)fprintf(fd, " ");
} else {
(void)fprintf(fd, " ");
}
}
} else {
for(b = 0; b < 256; ++b) {
if(swapped) {
for(vv = b, i = 8; --i >= 0;)
vv = vv & 1 ? (vv>>1)^poly : vv>>1;
} else {
for(vv = b<<24, i = 8; --i >= 0;)
vv = vv & 0x80000000 ? (vv<<1)^poly : vv<<1;
}
(void)fprintf(fd, "0x%.8x,", vv & 0xffffffff);
if((b&3) == 3) {
(void)fprintf(fd, "\n");
if(b != 255) (void)fprintf(fd, " ");
} else {
(void)fprintf(fd, " ");
}
}
}
(void)fprintf(fd, "};\n");
(void)fprintf(fd, "\n");
(void)fprintf(fd, "unsigned long %s_updcrc(icrc, icp, icnt)\n", name);
(void)fprintf(fd, " unsigned long icrc;\n");
(void)fprintf(fd, " unsigned char *icp;\n");
(void)fprintf(fd, " int icnt;\n");
(void)fprintf(fd, "{\n");
if(bits == 16) {
(void)fprintf(fd, "#define M1 0xff\n");
(void)fprintf(fd, "#define M2 0xff00\n");
} else {
(void)fprintf(fd, "#define M1 0xffffff\n");
(void)fprintf(fd, "#define M2 0xffffff00\n");
}
(void)fprintf(fd, " register unsigned long crc = icrc;\n");
(void)fprintf(fd, " register unsigned char *cp = icp;\n");
(void)fprintf(fd, " register int cnt = icnt;\n");
(void)fprintf(fd, "\n");
(void)fprintf(fd, " while(cnt--) {\n");
if(bits == 16) {
if (swapped) {
(void)fprintf(fd,
"\tcrc=((crc>>8)&M1)^crctab[(crc&0xff)^*cp++];\n");
} else {
(void)fprintf(fd,
"\tcrc=((crc<<8)&M2)^crctab[((crc>>8)&0xff)^*cp++];\n");
}
} else {
if(swapped) {
(void)fprintf(fd,
"\tcrc=((crc>>8)&M1)^crctab[(crc&0xff)^*cp++];\n");
} else {
(void)fprintf(fd,
"\tcrc=((crc<<8)&M2)^crctab[((crc>>24)&0xff)^*cp++];\n");
}
}
(void)fprintf(fd, " }\n");
(void)fprintf(fd, "\n");
(void)fprintf(fd, " return(crc);\n");
(void)fprintf(fd, "}\n");
(void)fprintf(fd, "\n");
(void)fclose(fd);
}

BIN
crc/makecrc.o Normal file

Binary file not shown.

27
crc/makefile Executable file
View File

@ -0,0 +1,27 @@
CFLAGS = -O $(CF)
CRCC = arc.c ccitt.c kermit.c binhex.c ccitt32.c zip.c
CRCO = arc.o ccitt.o kermit.o binhex.o ccitt32.o zip.o
libcrc.a: $(CRCO)
ar r libcrc.a $(CRCO)
if test -f /usr/bin/ranlib ;\
then \
ranlib libcrc.a ;\
fi
clean:
-rm -f $(CRCC) $(CRCO) libcrc.a makecrc makecrc.o
$(CRCC): makecrc
./makecrc
makecrc: makecrc.o
cc -O -o makecrc makecrc.o
arc.o: arc.c
ccitt.o: ccitt.c
kermit.o: kermit.c
binhex.o: binhex.c
ccitt32.o: ccitt32.c
zip.o: zip.c

87
crc/zip.c Normal file
View File

@ -0,0 +1,87 @@
unsigned long zip_crcinit = -1;
static unsigned long crctab[256] = {
0x00000000, 0x09073096, 0x120e612c, 0x1b0951ba,
0xff6dc419, 0xf66af48f, 0xed63a535, 0xe46495a3,
0xfedb8832, 0xf7dcb8a4, 0xecd5e91e, 0xe5d2d988,
0x01b64c2b, 0x08b17cbd, 0x13b82d07, 0x1abf1d91,
0xfdb71064, 0xf4b020f2, 0xefb97148, 0xe6be41de,
0x02dad47d, 0x0bdde4eb, 0x10d4b551, 0x19d385c7,
0x036c9856, 0x0a6ba8c0, 0x1162f97a, 0x1865c9ec,
0xfc015c4f, 0xf5066cd9, 0xee0f3d63, 0xe7080df5,
0xfb6e20c8, 0xf269105e, 0xe96041e4, 0xe0677172,
0x0403e4d1, 0x0d04d447, 0x160d85fd, 0x1f0ab56b,
0x05b5a8fa, 0x0cb2986c, 0x17bbc9d6, 0x1ebcf940,
0xfad86ce3, 0xf3df5c75, 0xe8d60dcf, 0xe1d13d59,
0x06d930ac, 0x0fde003a, 0x14d75180, 0x1dd06116,
0xf9b4f4b5, 0xf0b3c423, 0xebba9599, 0xe2bda50f,
0xf802b89e, 0xf1058808, 0xea0cd9b2, 0xe30be924,
0x076f7c87, 0x0e684c11, 0x15611dab, 0x1c662d3d,
0xf6dc4190, 0xffdb7106, 0xe4d220bc, 0xedd5102a,
0x09b18589, 0x00b6b51f, 0x1bbfe4a5, 0x12b8d433,
0x0807c9a2, 0x0100f934, 0x1a09a88e, 0x130e9818,
0xf76a0dbb, 0xfe6d3d2d, 0xe5646c97, 0xec635c01,
0x0b6b51f4, 0x026c6162, 0x196530d8, 0x1062004e,
0xf40695ed, 0xfd01a57b, 0xe608f4c1, 0xef0fc457,
0xf5b0d9c6, 0xfcb7e950, 0xe7beb8ea, 0xeeb9887c,
0x0add1ddf, 0x03da2d49, 0x18d37cf3, 0x11d44c65,
0x0db26158, 0x04b551ce, 0x1fbc0074, 0x16bb30e2,
0xf2dfa541, 0xfbd895d7, 0xe0d1c46d, 0xe9d6f4fb,
0xf369e96a, 0xfa6ed9fc, 0xe1678846, 0xe860b8d0,
0x0c042d73, 0x05031de5, 0x1e0a4c5f, 0x170d7cc9,
0xf005713c, 0xf90241aa, 0xe20b1010, 0xeb0c2086,
0x0f68b525, 0x066f85b3, 0x1d66d409, 0x1461e49f,
0x0edef90e, 0x07d9c998, 0x1cd09822, 0x15d7a8b4,
0xf1b33d17, 0xf8b40d81, 0xe3bd5c3b, 0xeaba6cad,
0xedb88320, 0xe4bfb3b6, 0xffb6e20c, 0xf6b1d29a,
0x12d54739, 0x1bd277af, 0x00db2615, 0x09dc1683,
0x13630b12, 0x1a643b84, 0x016d6a3e, 0x086a5aa8,
0xec0ecf0b, 0xe509ff9d, 0xfe00ae27, 0xf7079eb1,
0x100f9344, 0x1908a3d2, 0x0201f268, 0x0b06c2fe,
0xef62575d, 0xe66567cb, 0xfd6c3671, 0xf46b06e7,
0xeed41b76, 0xe7d32be0, 0xfcda7a5a, 0xf5dd4acc,
0x11b9df6f, 0x18beeff9, 0x03b7be43, 0x0ab08ed5,
0x16d6a3e8, 0x1fd1937e, 0x04d8c2c4, 0x0ddff252,
0xe9bb67f1, 0xe0bc5767, 0xfbb506dd, 0xf2b2364b,
0xe80d2bda, 0xe10a1b4c, 0xfa034af6, 0xf3047a60,
0x1760efc3, 0x1e67df55, 0x056e8eef, 0x0c69be79,
0xeb61b38c, 0xe266831a, 0xf96fd2a0, 0xf068e236,
0x140c7795, 0x1d0b4703, 0x060216b9, 0x0f05262f,
0x15ba3bbe, 0x1cbd0b28, 0x07b45a92, 0x0eb36a04,
0xead7ffa7, 0xe3d0cf31, 0xf8d99e8b, 0xf1deae1d,
0x1b64c2b0, 0x1263f226, 0x096aa39c, 0x006d930a,
0xe40906a9, 0xed0e363f, 0xf6076785, 0xff005713,
0xe5bf4a82, 0xecb87a14, 0xf7b12bae, 0xfeb61b38,
0x1ad28e9b, 0x13d5be0d, 0x08dcefb7, 0x01dbdf21,
0xe6d3d2d4, 0xefd4e242, 0xf4ddb3f8, 0xfdda836e,
0x19be16cd, 0x10b9265b, 0x0bb077e1, 0x02b74777,
0x18085ae6, 0x110f6a70, 0x0a063bca, 0x03010b5c,
0xe7659eff, 0xee62ae69, 0xf56bffd3, 0xfc6ccf45,
0xe00ae278, 0xe90dd2ee, 0xf2048354, 0xfb03b3c2,
0x1f672661, 0x166016f7, 0x0d69474d, 0x046e77db,
0x1ed16a4a, 0x17d65adc, 0x0cdf0b66, 0x05d83bf0,
0xe1bcae53, 0xe8bb9ec5, 0xf3b2cf7f, 0xfab5ffe9,
0x1dbdf21c, 0x14bac28a, 0x0fb39330, 0x06b4a3a6,
0xe2d03605, 0xebd70693, 0xf0de5729, 0xf9d967bf,
0xe3667a2e, 0xea614ab8, 0xf1681b02, 0xf86f2b94,
0x1c0bbe37, 0x150c8ea1, 0x0e05df1b, 0x0702ef8d,
};
unsigned long zip_updcrc(icrc, icp, icnt)
unsigned long icrc;
unsigned char *icp;
int icnt;
{
#define M1 0xffffff
#define M2 0xffffff00
register unsigned long crc = icrc;
register unsigned char *cp = icp;
register int cnt = icnt;
while(cnt--) {
crc=((crc>>8)&M1)^crctab[(crc&0xff)^*cp++];
}
return(crc);
}

BIN
crc/zip.o Normal file

Binary file not shown.

7
doc/README.crc Executable file
View File

@ -0,0 +1,7 @@
This code is based on the code described in README.ORIG.
Changes are:
1. A program (makecrc) will create the different C source
files to do crc calculations.
2. The crc calculation method of binhex is added.
3. 32 bit crc's are added.

193
doc/README.crc.orig Executable file
View File

@ -0,0 +1,193 @@
/* 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
****************************************************************************

31
doc/README.hexbin Executable file
View File

@ -0,0 +1,31 @@
The comment for the predecessor of hexbin.
/*
* xbin -- unpack BinHex format file into suitable
* format for downloading with macput
* Dave Johnson, Brown University Computer Science
*
* (c) 1984 Brown University
* may be used but not sold without permission
*
* created ddj 12/16/84
* revised ddj 03/10/85 -- version 4.0 compatibility, other minor mods
* revised ddj 03/11/85 -- strip LOCKED bit from m_flags
* revised ahm 03/12/85 -- System V compatibility
* revised dba 03/16/85 -- (Darin Adler, TMQ Software) 4.0 EOF fixed,
* 4.0 checksum added
* revised ddj 03/17/85 -- extend new features to older formats: -l, stdin
* revised ddj 03/24/85 -- check for filename truncation, allow multiple files
* revised ddj 03/26/85 -- fixed USG botches, many problems w/multiple files
* revised jcb 03/30/85 -- (Jim Budler, amdcad!jimb), revised for compatibility
* with 16-bit int machines
* revised dl 06/16/85 -- (Dan LaLiberte, liberte@uiucdcs) character
* translation speedup
* revised ddj 09/30/85 -- fixed problem with run of RUNCHAR
* revised gvr 11/15/86 -- speed-up: rewrote .hqx decoding (mcvax!guido)
* revised jwm 04/26/88 -- now recognizes "(Convert with" as a starting line
* -- the widely-used Stuffit uses this as a header
* revised dtw ../../89 -- hqx format will skip garbage lines; undoes some of
* -- gvr's work. will now also recognize .dl format.
*/

14
doc/README.macget Executable file
View File

@ -0,0 +1,14 @@
/*
* macget -- receive file from macintosh using xmodem protocol
* Dave Johnson, Brown University Computer Science
*
* (c) 1984 Brown University
* may be used but not sold without permission
*
* created ddj 5/22/84
* revised ddj 6/29/84 -- added [-rdu] options
* revised ddj 7/16/84 -- protocol changes for MacTerminal Beta Version 0.5X
* revised ddj 7/31/84 -- pre-4.2 signal bugs fixed in timedout()
* revised ddj 11/7/84 -- renamed send_sync() -> get_sync()
* revised lra 1/01/87 -- multiple file uploads added (VersTerm compatible)
*/

18
doc/README.macput Executable file
View File

@ -0,0 +1,18 @@
/*
*
* Here is the source for the current incarnation of macput . . . .
* It is compatible with the 1.1 Release version of MacTerminal,
* though in case you still need to use the -0.15X version, there's
* the "-o" option to provide compatibility. Versions 0.5 and 0.9
* have a bug in the record checksum calculation which will break
* file transfers, so 1.1 is recommended.
*
* Please pass any improvements/bug fixes on to me, and
* if you know of any good protocols for use on a flow-controlled
* line, let me know.
*
* Dave Johnson
* ddj%brown@csnet-relay.arpa
* Brown University Computer Science
*
*/

92
doc/README.scan Executable file
View File

@ -0,0 +1,92 @@
Preliminary info about the Unix scanner.
----------------------------------------
This file states mostly how to use it, it is not yet full documentation.
There are a few utilities in this package that help scanning: macidf,
macscan, macstream, hexbin and macunpack. I will give examples of use
where every use highlights some factilities.
The main program is macscan. It reads from standard input (NB: no file
parameters) and will scan the input for offensive stuff. The input
consists of a stream of files in MacBinary format, with additional
information between (about Unix file name, Archive/Packed file name,
folder entry/exit in an archive etc.).
To scan a single MacBinary file just do:
macscan <file
This will read the file and macscan will mark everything it does not like.
Also when macscan detects that it is an archive, it will unpack the archive,
and recursively so for embedded archives. When given the opion -l macscan
will list the contents of the archive during its scan. When given the
option -v it will also list all resources found, with type, number,
name (if defined) and size.
If you have multiple MacBinary files (e.g. a set of MacBinary files in a
directory tree), you can do the following (supposing the filenames end in
'.bin'):
find directory -name '*.bin' -exec xxx {} \; | macscan
Where xxx is the following shellscript:
#!/bin/sh
macidf $1
cat $1
The macidf is needed so that macscan knows the original Unix file name.
Of course macscan can also get the -l and -v options.
If you have a directory tree with binhexed files, the following is
appropriate:
find directory -name '*.hqx' -exec hexbin -S {} \; | macscan
The flag -S tells hexbin that filename info for macscan must be included.
And here again, macscan can have options. Note: every binhexed file must
be contained in a single Unix file, unlike mcvert. But, like mcvert,
mailheaders and such can preceed and follow the binhexed file, and can
also be in the middle.
You can of course have compressed binhexed files, in that case:
find directory -name '*.hqx.Z' -exec xxx {} \; | macscan
with xxx the following shellscript:
#!/bin/sh
macidf $1
zcat $1 | hexbin -s
(Note, lower case s here. Hexbin has no knowledge about the Unix filename.)
If the directory is an AUFS directory the following can be done:
macstream directory | macscan
Note: in this case it is not yet possible to include the Unix filename in
the output of macscan. With the option -l Mac names are listed.
The previous method might also work with AppleDouble directories, but I am
not sure about that.
-------
What macscan can at this moment.
It currently uses a subset of Jeff's VirusDetective strings during the scan.
Not all strings are yet implemented, so not all viruses are already detected.
Moreover, it includes warnings for CDEF 0, WDEF 0 etc. resources, as per
Zig's suggestion.
Finally, it warns about resources compressed by the resource compressor of
Ben Haller.
-------
The status.
This version is preliminary and confidential. Do not distribute.
There are probably a number of bugs present, although my testing
on a Sun (actually an FPS == very fast Sun) worked pretty well.
Lint does not complain too much ;-). Also SGI's lint has not
many problems with it. Mostly because the difference between
(char *)malloc();
and
(void *)malloc();
etc. That must be straightened out sometime.
Any bug-reports, suggestions are wellcome. Please support bug-reports
with input or somesuch.
dik
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland
dik@cwi.nl

62
doc/README.unpit Executable file
View File

@ -0,0 +1,62 @@
/*
* @(#)unpit.c 1.2 (CWI) 87/11/05
*/
/*
unpit - Macintosh PackIt file unpacker
Version 2, for PackIt II
This program will unpack a Macintosh PackIt file into separate files. The
data fork of a PackIt 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 syntax is much like macput/macget:
unpit [-rdu] packit-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.
Some of the program is borrowed from the macput.c/macget.c programs.
Author: Allan G. Weber, (Weber%Brand@USC-ECL)
Date: September 30, 1985
Revised: January 24, 1986 - added CRC checking
March 25, 1986 - support compressed mode of PackIt II,
check for illegal Unix file names
*/
/* There is some confusion as to what to do with the "inited" flag in the
finder info bytes that are in the header of each file in the packit file.
If this flag bit is copied to the .info file, it seems to confuse
MacTerminal into placing the file icons in the upper left corner of the
window on top of each other. Setting this bit to zero in the .info file
seems to fix that problem but may cause others. I haven't been able to
find any .info files that have this flag set so making it zero may be OK.
Anyway, MacTerminal seems to set the flag when it create the file on the
Mac. The "#define INITED_BUG" can be used to try both settings. */
/*
Format of a Packit file:
Repeat the following sequence for each file in the Packit file:
4 byte identifier ("PMag" = not compressed, "Pma4" = compressed)
variable length compression data (if compressed file)
92 byte header (see struct pit_header below) *
2 bytes CRC number *
data fork (length from header) *
resource fork (length from header) *
2 bytes CRC number *
Last file is followed by the 4 byte Ascii string, "Pend", and then the EOF.
* these are in compressed form if compression is on for the file
*/

46
doc/README.unsit Executable file
View File

@ -0,0 +1,46 @@
/*
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
*/

101
doc/README.zoom Executable file
View File

@ -0,0 +1,101 @@
Taken from the file plugins.h in the Zoom distribution.
/*
* The Zoom archive format is:
*
* (char) Magic1
* (char) Magic2 - or - (char) Magic2B
* (char) Magic3
* (char) Magic4
*
* IF Magic2B was received THEN
* (long) logicalEof /* For multi-file archives * /
* END IF
*
* <EntryChain>
*
* The format of <EntryChain> is a linked list of
* EntryInfo, where "next" points to the next logical address
* on disk. "next" as 0 means no more entries.
*
* For a directory, the "creator" field points to the
* first file/folder entry inside the directory.
*
* For a file, IF the "what" field is ZOOM_PLUGIN,
* the EntryInfo is followed by a length byte and that
* many characters naming the compression engine.
* Right after that (or right after the EntryInfo in the
* case of uncompressed files or default compressed files)
* follows the data fork compressed, followed by the
* resource fork compressed.
*
* Note that there is no "end of compressed data" marker;
* your compressor engine will have to figure that out by
* itself. You could for instance do an ftell before
* compressing; writing a (long)0 and then write your
* compressed data, seek back and write the actual length.
*
* Note that new entries always are added last in the file,
* so you need not worry about overrunning anything else.
*/
/*
* The default compressor in Zoom is the same as used in
* "better" compression mode in ZOO 2.10. A Zoo extractor
* or convertor could parse the ZOO header format, and use
* the built-in engine for "lzh" compressed files.
*
* The simplest way to do this is to call SetEngine(-1) and
* call Encode / Decode. -1 is the default compressor, 0 is
* the null compressor (fork copy)
*
* Likewise, a UNIX zoom packer/unpacker could use the source
* for zoo 2.10 functions "lzh_encode" and "lzh_decode"
* (they're wrappers) for compression.
*/
/*
* This "EntryInfo" is presently also a file header.
* Some fields may be non-obvious. Don't use these.
* For instance, "comment" is currently unsupported,
* and should be left as 0
*/
#ifndef ZOOM_TYPES
typedef enum zoomWhatType {
ZOOM_NOTHING , ZOOM_FILE , ZOOM_UCFILE , ZOOM_DIR , ZOOM_PLUGIN
} ZoomWhatType ;
#define ZOOM_TYPES
#endif
/*
* Remember to fill in "hlen" correctly as well. When reading a header,
* Zoom checks with this field to see if it should skip some more data
* or seek back a little, so as to make future field additions at the
* end possible. You should NOT add your own fields to this structure.
*/
typedef struct EntryInfo {
/* "what" is a ZoomWhatType */
char what ; /* Negative if deleted */
unsigned char hlen ; /* Header length */
unsigned short boolFlags ; /* Boolean flags */
long next ; /* Next entry */
long complen ; /* Length of compressed data */
long compdata ; /* Data fork portion of compressed data - for dirs, number of entries */
long uclen ; /* Length of uncompressed entry */
long ucdata ; /* Data fork part of uncompressed */
long type ; /* File type */
long creator ; /* File creator - for dir, offset of file */
long mdate ; /* Modification date */
long comment ; /* Comment offset */
short flags ; /* Macintosh file flags */
short dataCrc ; /* Data fork crc */
short resCrc ; /* Resource fork crc */
unsigned char name [ 32 ] ; /* File/Dir name */
} EntryInfo ;

0
fileio/all Normal file
View File

53
fileio/appledouble.h Executable file
View File

@ -0,0 +1,53 @@
#define FI_MAGIC 333319
#define FI_VERSION 1
#define FI_FILL5 5
#define FI_FILL6 2
#define FI_HLEN 589
#define FI_FILL7 3
#define FI_NAMPTR 86
#define FI_FILL9 4
#define FI_COMMPTR 341
#define FI_FILL12 7
#define FI_TIMEPTR 541
#define FI_TIMESIZE 16
#define FI_FILL15 9
#define FI_INFOPTR 557
#define FI_INFOSIZE 32
/* All as char[n] because of possible alignment problems. But is this needed?
Is this stuff in host order or in client order? Assuming client order for
the moment. Will not be a problem on big-endian machines. */
typedef struct {
char fi_magic[4]; /* magic header */
char fi_version[2]; /* version number */
char fi_fill1[4]; /* = 0, ???? */
char fi_fill2[4]; /* = 0, ???? */
char fi_fill3[4]; /* = 0, ???? */
char fi_fill4[4]; /* = 0, ???? */
char fi_fill5[4]; /* = 5, ???? */
char fi_fill6[4]; /* = 2, ???? */
char fi_hlen[4]; /* = 589, header length */
char fi_rsrc[4]; /* resource length */
char fi_fill7[4]; /* = 3, ???? */
char fi_namptr[4]; /* = 86, filename pointer */
char fi_namlen[4]; /* Mac filename length */
char fi_fill9[4]; /* = 4, ???? */
char fi_commptr[4]; /* = 341, comment pointer */
char fi_commsize[4]; /* = 0, comment size */
char fi_fill12[4]; /* = 7, ???? */
char fi_timeptr[4]; /* = 541, pointer to times */
char fi_timesize[4]; /* = 16, size of times */
char fi_fill15[4]; /* = 9, ???? */
char fi_infoptr[4]; /* = 557, finder info pointer */
char fi_infosize[4]; /* = 32, finder info size */
char fi_name[255]; /* Macintosh filename */
char fi_comment[200];/* = 0, Comment */
char fi_ctime[4]; /* Creation time (Unix time) */
char fi_mtime[4]; /* Modification time (Unix time) */
char fi_fill19[4]; /* = 0, ???? */
char fi_fill20[4]; /* = 0, ???? */
char fi_type[4]; /* File type */
char fi_auth[4]; /* File creator */
char fi_finfo[24]; /* Finder info */
} FileInfo;

33
fileio/aufs.h Executable file
View File

@ -0,0 +1,33 @@
#define MAXCLEN 199 /* max size of a comment string */
#define FINFOLEN 32 /* Finder info is 32 bytes */
#define MAXMACFLEN 31 /* max Mac file name length */
#define FI_MAGIC1 255
#define FI_VERSION 0x10 /* version major 1, minor 0 */
/* if we have more than 8 versions wer're */
/* doiong something wrong anyway */
#define FI_MAGIC 0xda
#define FI_BM_SHORTFILENAME 0x1 /* is this included? */
#define FI_BM_MACINTOSHFILENAME 0x2 /* is this included? */
#define FI_MDATE 0x01 /* mtime & utime are valid */
#define FI_CDATE 0x02 /* ctime is valid */
typedef struct {
char fi_fndr[FINFOLEN]; /* finder info */
short fi_attr; /* attributes */
char fi_magic1; /* addional magic word check */
char fi_version; /* version number */
char fi_magic; /* magic word check */
char fi_bitmap; /* bitmap of included info */
char fi_shortfilename[12+1]; /* possible short file name */
char fi_macfilename[32+1]; /* possible macintosh file name */
char fi_comln; /* comment length */
char fi_comnt[MAXCLEN+1]; /* comment string */
#ifdef AUFSPLUS
char fi_datemagic; /* sanity check */
char fi_datevalid; /* validity flags */
char fi_ctime[4]; /* mac file create time */
char fi_mtime[4]; /* mac file modify time */
char fi_utime[4]; /* (real) time mtime was set */
#endif /* AUFSPLUS */
} FileInfo;

2
fileio/fileglob.c Executable file
View File

@ -0,0 +1,2 @@
int bytes_read, bytes_written;

2
fileio/fileglob.h Executable file
View File

@ -0,0 +1,2 @@
extern int bytes_read, bytes_written;

BIN
fileio/fileglob.o Normal file

Binary file not shown.

10
fileio/kind.h Executable file
View File

@ -0,0 +1,10 @@
#ifdef SCAN
#define UNIX_NAME 0
#define PACK_NAME 1
#define ARCH_NAME 2
#define UNKNOWN 16
#define PROTECTED 17
#define ERROR 32
#define COPY 33
#endif /* SCAN */

20
fileio/machdr.h Executable file
View File

@ -0,0 +1,20 @@
#define INFOBYTES 128
/* 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 F_NAMELEN 63
#define I_NAMELEN 69 /* 63 + strlen(".info") + 1 */
#define INITED_MASK 1
#define PROTCT_MASK 0x40

33
fileio/makefile Executable file
View File

@ -0,0 +1,33 @@
CFLAGS= -O $(CF)
all: wrfile.o rdfile.o fileglob.o
touch all
wrfile.o: wrfile.c
rdfile.o: rdfile.c
clean:
-rm -f wrfile.o
-rm -f rdfile.o
-rm -f fileglob.o
-rm -f all
wrfile.o: machdr.h
wrfile.o: wrfile.h
wrfile.o: wrfileopt.h
wrfile.o: fileglob.h
wrfile.o: aufs.h
wrfile.o: appledouble.h
wrfile.o: ../util/util.h
wrfile.o: ../util/curtime.h
rdfile.o: machdr.h
rdfile.o: rdfile.h
rdfile.o: rdfileopt.h
rdfile.o: ../util/util.h
rdfile.o: ../util/curtime.h
rdfile.o: ../util/masks.h
rdfile.o: aufs.h
rdfile.o: appledouble.h
fileglob.o: fileglob.h

1010
fileio/rdfile.c Executable file

File diff suppressed because it is too large Load Diff

13
fileio/rdfile.h Executable file
View File

@ -0,0 +1,13 @@
#define ISATEND 0
#define ISFILE 1
#define ISDIR 2
#define ENDDIR 3
extern char file_info[INFOBYTES];
extern char *data_fork, *rsrc_fork;
extern int data_size, rsrc_size;
extern void setup();
extern int nextfile();
extern char *get_minb();

BIN
fileio/rdfile.o Normal file

Binary file not shown.

5
fileio/rdfileopt.h Executable file
View File

@ -0,0 +1,5 @@
extern int rdfileopt();
extern void give_rdfileopt();
extern void set_norecurse();
extern char *get_rdfileopt();

847
fileio/wrfile.c Executable file
View File

@ -0,0 +1,847 @@
#ifdef TYPES_H
#include <sys/types.h>
#endif /* TYPES_H */
#include <sys/stat.h>
#include <ctype.h>
#include <stdio.h>
#include "machdr.h"
#include "wrfile.h"
#include "wrfileopt.h"
#include "../util/util.h"
#ifdef AUFSPLUS
#include "../util/curtime.h"
#define AUFS
#endif /* AUFSPLUS */
#ifdef AUFS
#include "aufs.h"
#define APPLESHARE
#endif /* AUFS */
#ifdef APPLEDOUBLE
#include "appledouble.h"
#include "../util/curtime.h"
#define APPLESHARE
#endif /* APPLEDOUBLE */
#define TEXT 0
#define DATA 1
#define RSRC 2
#define FULL 3
#define MACB 4
#define FORK 5
#define APSH 6
#define MACS 7
#define UNIX 8
#ifdef SCAN
#define MACI 9
#endif /* SCAN */
extern char *malloc();
extern char *realloc();
extern char *strcpy();
extern char *strncpy();
extern char *strcat();
extern void exit();
#ifdef UNDEF /* Do not declare sprintf; not portable (but lint will complain) */
char *sprintf();
#endif /* UNDEF */
#ifdef AUFS
static void check_aufs();
static void aufs_namings();
static void wr_aufs_info();
#endif /* AUFS */
#ifdef APPLEDOUBLE
static void check_appledouble();
static void appledouble_namings();
static void wr_appledouble_info();
#endif /* APPLEDOUBLE */
#ifdef APPLESHARE
static void mk_share_name();
#endif /* APPLESHARE */
#ifndef BSD
/* all those stupid differences! */
#define bcopy(src,dest,length) memcpy((dest),(src),(length))
#define bzero(block,length) memset((block),0,(length))
#endif /* BSD */
#define INFO_FORK 1
#define RSRC_FORK 2
#define DATA_FORK 3
static char f_info[I_NAMELEN];
static char f_data[I_NAMELEN*3];
static char f_rsrc[I_NAMELEN];
static char f_text[I_NAMELEN];
static char f_unix[I_NAMELEN];
static char f_bin[I_NAMELEN];
static char f_folder[] = ".foldername";
static char share_name[256];
#ifdef APPLESHARE
static char hex[] = "0123456789abcdef";
#endif /* APPLESHARE */
#ifdef AUFS
static char infodir[] = ".finderinfo";
static char rsrcdir[] = ".resource";
#define INFOSZ sizeof(infodir)
#define RSRCSZ sizeof(rsrcdir)
static char f_info_aufs[I_NAMELEN*3+INFOSZ];
static char f_rsrc_aufs[I_NAMELEN*3+RSRCSZ];
#endif /* AUFS */
#ifdef APPLEDOUBLE
static char infodir[] = ".AppleDouble";
#define INFOSZ sizeof(infodir)
static char f_info_appledouble[I_NAMELEN*3+INFOSZ];
#endif /* APPLEDOUBLE */
static int mode = MACB;
static int mode_restricted = 0;
static int mode_s_restricted = 0;
char *out_buffer, *out_ptr;
static char init_buffer[128];
static char *buffer = &(init_buffer[0]);
static char *rbuffer = NULL, *dbuffer = NULL;
static char *ptr;
static unsigned long rsz, dsz, totsize, maxsize;
void define_name(text)
char *text;
{
(void)sprintf(f_info, "%s.info", text);
(void)sprintf(f_rsrc, "%s.rsrc", text);
(void)sprintf(f_data, "%s.data", text);
(void)sprintf(f_text, "%s.text", text);
(void)sprintf(f_bin, "%s.bin", text);
(void)sprintf(f_unix, "%s", text);
#ifdef APPLESHARE
/* Do not do namestuffing here. We want to base again on the information in
the info header, so this is delayed
*/
#endif /* APPLESHARE */
}
void start_info(info, rsize, dsize)
char *info;
unsigned long rsize, dsize;
{
int rs, ds;
rsz = rsize;
dsz = dsize;
rs = (((rsz + 127) >> 7) << 7);
ds = (((dsz + 127) >> 7) << 7);
totsize = rs + ds + 128;
if(buffer == &(init_buffer[0])) {
buffer = (char *)malloc((unsigned)totsize);
} else if(maxsize < totsize) {
buffer = (char *)realloc(buffer, (unsigned)totsize);
}
maxsize = totsize;
if(buffer == NULL) {
(void)fprintf(stderr, "Insufficient memory, aborting\n");
exit(1);
}
dbuffer = buffer + 128;
rbuffer = dbuffer + ds;
(void)bzero(buffer, (int)totsize);
ptr = buffer;
(void)bcopy(info, ptr, 128);
#ifdef AUFS
/* Now we do filenaming etc. */
if(mode == APSH) {
aufs_namings();
}
#endif /* AUFS */
#ifdef APPLEDOUBLE
/* Now we do filenaming etc. */
if(mode == APSH) {
appledouble_namings();
}
#endif /* APPLEDOUBLE */
}
void start_rsrc()
{
out_buffer = out_ptr = rbuffer;
}
void start_data()
{
out_buffer = out_ptr = dbuffer;
}
void end_file()
{
FILE *fp;
int i, c;
buffer[I_FLAGOFF] &= (~INITED_MASK);
switch(mode) {
case FULL:
case FORK:
fp = fopen(f_info, "w");
if(fp == NULL) {
perror(f_info);
exit(1);
}
(void)fwrite(buffer, 1, 128, fp);
(void)fclose(fp);
if(rsz != 0 || mode == FULL) {
fp = fopen(f_rsrc, "w");
if(fp == NULL) {
perror(f_rsrc);
exit(1);
}
(void)fwrite(rbuffer, 1, (int)rsz, fp);
(void)fclose(fp);
}
if(dsz != 0 || mode == FULL) {
fp = fopen(f_data, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
}
break;
case RSRC:
fp = fopen(f_rsrc, "w");
if(fp == NULL) {
perror(f_rsrc);
exit(1);
}
(void)fwrite(rbuffer, 1, (int)rsz, fp);
(void)fclose(fp);
break;
case DATA:
fp = fopen(f_data, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
break;
case TEXT:
fp = fopen(f_text, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
for(i = 0; i < dsz; i++) {
c = dbuffer[i];
if(c == '\012' || c == '\015') {
dbuffer[i] = '\027' -c;
}
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
break;
case UNIX:
fp = fopen(f_unix, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
for(i = 0; i < dsz; i++) {
c = dbuffer[i];
if(c == '\012' || c == '\015') {
dbuffer[i] = '\027' -c;
}
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
break;
case MACB:
fp = fopen(f_bin, "w");
if(fp == NULL) {
perror(f_bin);
exit(1);
}
if(buffer[I_FLAGOFF + 1] & PROTCT_MASK) {
buffer[I_LOCKOFF] = 1;
}
buffer[I_FLAGOFF + 1] = 0;
buffer[I_LOCKOFF + 1] = 0;
(void)fwrite(buffer, 1, (int)totsize, fp);
(void)fclose(fp);
break;
case MACS:
#ifdef SCAN
case MACI:
#endif /* SCAN */
if(buffer[I_FLAGOFF + 1] & PROTCT_MASK) {
buffer[I_LOCKOFF] = 1;
}
buffer[I_FLAGOFF + 1] = 0;
buffer[I_LOCKOFF + 1] = 0;
(void)fwrite(buffer, 1, (int)totsize, stdout);
break;
#ifdef AUFS
case APSH:
fp = fopen(f_info_aufs, "w");
if(fp == NULL) {
perror(f_info_aufs);
exit(1);
}
wr_aufs_info(fp);
(void) fclose(fp);
fp = fopen(f_rsrc_aufs, "w");
if(fp == NULL) {
perror(f_rsrc_aufs);
exit(1);
}
(void)fwrite(rbuffer, 1, (int)rsz, fp);
(void)fclose(fp);
fp = fopen(f_data, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
break;
#endif /* AUFS */
#ifdef APPLEDOUBLE
case APSH:
fp = fopen(f_info_appledouble, "w");
if(fp == NULL) {
perror(f_info_appledouble);
exit(1);
}
wr_appledouble_info(fp);
(void)fwrite(rbuffer, 1, (int)rsz, fp);
(void)fclose(fp);
fp = fopen(f_data, "w");
if(fp == NULL) {
perror(f_data);
exit(1);
}
(void)fwrite(dbuffer, 1, (int)dsz, fp);
(void)fclose(fp);
break;
#endif /* APPLEDOUBLE */
}
}
#ifdef SCAN
void do_idf(name, kind)
char *name;
int kind;
{
int n;
if(mode != MACI) {
return;
}
n = strlen(name);
(void)bzero(buffer, INFOBYTES);
buffer[I_NAMEOFF + 1] = kind;
put4(buffer + I_DLENOFF, (unsigned long)n);
(void)fwrite(buffer, 1, INFOBYTES, stdout);
if(n != 0) {
(void)fwrite(name, 1, n, stdout);
n = (((n + 127) >> 7) << 7) - n;
while(n-- > 0) {
(void)fputc(0, stdout);
}
}
}
#endif /* SCAN */
void do_mkdir(name, header)
char *name, *header;
{
struct stat sbuf;
FILE *fp;
#ifdef NOMKDIR
char command[21]; /* Systems without mkdir system call but more than 14
char file names? Ridiculous! */
int sysreturn;
#endif /* MKDIR */
#ifdef APPLESHARE
char dirinfo[I_NAMELEN*3+INFOSZ+10];
#endif /* APPLESHARE */
#ifndef SCAN
if(mode == MACS) {
#else /* SCAN */
if(mode == MACS || mode == MACI) {
#endif /* SCAN */
header[I_NAMEOFF] |= 0x80;
(void)fwrite(header, 1, INFOBYTES, stdout);
header[I_NAMEOFF] &= 0x7f;
return;
}
#ifdef APPLESHARE
if(mode == APSH) {
(void)bcopy(header, buffer, INFOBYTES);
mk_share_name();
} else {
(void)strcpy(share_name, name);
}
#else /* APPLESHARE */
(void)strcpy(share_name, name);
#endif /* APPLESHARE */
if(stat(share_name, &sbuf) == -1) { /* directory doesn't exist */
#ifndef NOMKDIR
if(mkdir(share_name, 0777) == -1) {
(void)fprintf(stderr, "Can't create subdirectory %s\n", share_name);
exit(1);
}
#else /* NOMKDIR */
sprintf(command, "mkdir %s", share_name);
if((sysreturn = system(command)) != 0) {
(void)fprintf(stderr, "Can't create subdirectory %s\n", share_name);
exit(sysreturn);
}
#endif /* NOMKDIR */
} else { /* something exists with this name */
if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
(void)fprintf(stderr, "Directory name %s already in use\n",
share_name);
exit(1);
}
}
(void)chdir(share_name);
#ifdef APPLESHARE
#ifdef AUFS
if(mode == APSH) {
if(stat(rsrcdir, &sbuf) == -1) { /* directory doesn't exist */
if(mkdir(rsrcdir, 0777) == -1) {
(void)fprintf(stderr, "Can't create subdirectory %s\n",
rsrcdir);
exit(1);
}
} else {
if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
(void)fprintf(stderr, "Directory name %s already in use\n",
rsrcdir);
exit(1);
}
}
if(stat(infodir, &sbuf) == -1) { /* directory doesn't exist */
if(mkdir(infodir, 0777) == -1) {
(void)fprintf(stderr, "Can't create subdirectory %s\n",
infodir);
exit(1);
}
} else {
if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
(void)fprintf(stderr, "Directory name %s already in use\n",
infodir);
exit(1);
}
}
dirinfo[0] = 0;
(void)strcat(dirinfo, "../");
(void)strcat(dirinfo, infodir);
(void)strcat(dirinfo, "/");
(void)strcat(dirinfo, share_name);
fp = fopen(dirinfo, "w");
if(fp == NULL) {
perror(dirinfo);
exit(1);
}
wr_aufs_info(fp);
(void)fclose(fp);
} else {
fp = fopen(f_folder, "w");
if(fp == NULL) {
perror(f_folder);
exit(1);
}
header[I_NAMEOFF] |= 0x80;
(void)fwrite(header, 1, INFOBYTES, fp);
header[I_NAMEOFF] &= 0x7f;
(void)fclose(fp);
}
#endif /* AUFS */
#ifdef APPLEDOUBLE
if(mode == APSH) {
if(stat(infodir, &sbuf) == -1) { /* directory doesn't exist */
if(mkdir(infodir, 0777) == -1) {
(void)fprintf(stderr, "Can't create subdirectory %s\n",
infodir);
exit(1);
}
} else {
if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
(void)fprintf(stderr, "Directory name %s already in use\n",
infodir);
exit(1);
}
}
dirinfo[0] = 0;
(void)strcat(dirinfo, infodir);
(void)strcat(dirinfo, "/.Parent");
fp = fopen(dirinfo, "w");
if(fp == NULL) {
perror(dirinfo);
exit(1);
}
rsz = 0;
wr_appledouble_info(fp);
(void)fclose(fp);
} else {
fp = fopen(f_folder, "w");
if(fp == NULL) {
perror(f_folder);
exit(1);
}
header[I_NAMEOFF] |= 0x80;
(void)fwrite(header, 1, INFOBYTES, fp);
header[I_NAMEOFF] &= 0x7f;
(void)fclose(fp);
}
#endif /* APPLEDOUBLE */
#else /* APPLESHARE */
fp = fopen(f_folder, "w");
if(fp == NULL) {
perror(f_folder);
exit(1);
}
header[I_NAMEOFF] |= 0x80;
(void)fwrite(header, 1, INFOBYTES, fp);
header[I_NAMEOFF] &= 0x7f;
(void)fclose(fp);
#endif /* APPLESHARE */
}
void enddir()
{
char header[INFOBYTES];
int i;
#ifndef SCAN
if(mode == MACS) {
#else /* SCAN */
if(mode == MACS || mode == MACI) {
#endif /* SCAN */
for(i = 0; i < INFOBYTES; i++) {
header[i] = 0;
}
header[I_NAMEOFF] = 0x80;
(void)fwrite(header, 1, INFOBYTES, stdout);
} else {
(void)chdir("..");
}
}
#ifdef APPLESHARE
#ifdef AUFS
static void check_aufs()
{
/* check for .resource/ and .finderinfo/ */
struct stat stbuf;
int error = 0;
if(stat(rsrcdir,&stbuf) < 0) {
error ++;
} else {
if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
error ++;
}
}
if(stat(infodir,&stbuf) < 0) {
error ++;
} else {
if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
error++;
}
}
if(error) {
(void)fprintf(stderr, "Not in an Aufs folder.\n");
exit(1);
}
}
static void aufs_namings()
{
mk_share_name();
(void)sprintf(f_info_aufs, "%s/%s", infodir, share_name);
(void)sprintf(f_rsrc_aufs, "%s/%s", rsrcdir, share_name);
(void)sprintf(f_data, "%s", share_name);
}
static void wr_aufs_info(fp)
FILE *fp;
{
FileInfo theinfo;
int n;
bzero((char *) &theinfo, sizeof theinfo);
theinfo.fi_magic1 = FI_MAGIC1;
theinfo.fi_version = FI_VERSION;
theinfo.fi_magic = FI_MAGIC;
theinfo.fi_bitmap = FI_BM_MACINTOSHFILENAME;
/* AUFS stores Unix times. */
#ifdef AUFSPLUS
theinfo.fi_datemagic = FI_MAGIC;
theinfo.fi_datevalid = FI_CDATE | FI_MDATE;
put4(theinfo.fi_ctime, get4(buffer + I_CTIMOFF) - TIMEDIFF);
put4(theinfo.fi_mtime, get4(buffer + I_MTIMOFF) - TIMEDIFF);
put4(theinfo.fi_utime, (unsigned long)time((time_t *)0));
#endif /* AUFSPLUS */
bcopy(buffer + I_TYPEOFF, theinfo.fi_fndr, 4);
bcopy(buffer + I_AUTHOFF, theinfo.fi_fndr + 4, 4);
bcopy(buffer + I_FLAGOFF, theinfo.fi_fndr + 8, 2);
if((n = buffer[I_NAMEOFF] & 0xff) > F_NAMELEN) {
n = F_NAMELEN;
}
(void)strncpy((char *)theinfo.fi_macfilename, buffer + I_NAMEOFF + 1,n);
/* theinfo.fi_macfilename[n] = '\0'; */
(void)strcpy((char *)theinfo.fi_comnt,
"Converted by Unix utility to Aufs format");
theinfo.fi_comln = strlen((char *)theinfo.fi_comnt);
(void)fwrite((char *) &theinfo, 1, sizeof theinfo, fp);
}
#endif /* AUFS */
#ifdef APPLEDOUBLE
static void check_appledouble()
{
/* check for .AppleDouble/ */
struct stat stbuf;
int error = 0;
if(stat(infodir,&stbuf) < 0) {
error ++;
} else {
if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
error++;
}
}
if(error) {
(void)fprintf(stderr, "Not in an AppleDouble folder.\n");
exit(1);
}
}
static void appledouble_namings()
{
mk_share_name();
(void)sprintf(f_info_appledouble, "%s/%s", infodir, share_name);
(void)sprintf(f_data, "%s", share_name);
}
static void wr_appledouble_info(fp)
FILE *fp;
{
FileInfo theinfo;
int n;
bzero((char *) &theinfo, sizeof theinfo);
put4(theinfo.fi_magic, (unsigned long)FI_MAGIC);
put2(theinfo.fi_version, (unsigned long)FI_VERSION);
put4(theinfo.fi_fill5, (unsigned long)FI_FILL5);
put4(theinfo.fi_fill6, (unsigned long)FI_FILL6);
put4(theinfo.fi_hlen, (unsigned long)FI_HLEN);
put4(theinfo.fi_fill7, (unsigned long)FI_FILL7);
put4(theinfo.fi_namptr, (unsigned long)FI_NAMPTR);
put4(theinfo.fi_fill9, (unsigned long)FI_FILL9);
put4(theinfo.fi_commptr, (unsigned long)FI_COMMPTR);
put4(theinfo.fi_fill12, (unsigned long)FI_FILL12);
put4(theinfo.fi_timeptr, (unsigned long)FI_TIMEPTR);
put4(theinfo.fi_timesize, (unsigned long)FI_TIMESIZE);
put4(theinfo.fi_fill15, (unsigned long)FI_FILL15);
put4(theinfo.fi_infoptr, (unsigned long)FI_INFOPTR);
put4(theinfo.fi_infosize, (unsigned long)FI_INFOSIZE);
bcopy(buffer + I_TYPEOFF, theinfo.fi_type, 4);
bcopy(buffer + I_AUTHOFF, theinfo.fi_auth, 4);
bcopy(buffer + I_FLAGOFF, theinfo.fi_finfo, 2);
/* AppleDouble stores Unix times. */
put4(theinfo.fi_ctime, get4(buffer + I_CTIMOFF) - TIMEDIFF);
put4(theinfo.fi_mtime, get4(buffer + I_MTIMOFF) - TIMEDIFF);
if((n = buffer[I_NAMEOFF] & 0xff) > F_NAMELEN) {
n = F_NAMELEN;
}
put4(theinfo.fi_namlen, (unsigned long)n);
(void)strncpy((char *)theinfo.fi_name, buffer + I_NAMEOFF + 1,n);
/* theinfo.fi_macfilename[n] = '\0'; */
(void)strcpy((char *)theinfo.fi_comment,
"Converted by Unix utility to AppleDouble format");
put4(theinfo.fi_commsize, (unsigned long)strlen(theinfo.fi_comment));
put4(theinfo.fi_rsrc, (unsigned long)rsz);
/* Still TODO */
/* char fi_ctime[4]; /* Creation time (Unix time) */
/* char fi_mtime[4]; /* Modification time (Unix time) */
(void)fwrite((char *) &theinfo, 1, sizeof theinfo, fp);
}
#endif /* APPLEDOUBLE */
static void mk_share_name()
{
int ch;
char *mp, *up;
mp = buffer + 2;
up = &(share_name[0]);
while(ch = *mp++) {
if(isascii(ch) && ! iscntrl(ch) && isprint(ch) && ch != '/') {
*up++ = ch;
} else {
*up++ = ':';
*up++ = hex[(ch >> 4) & 0xf];
*up++ = hex[ch & 0xf];
}
}
*up = 0;
}
#endif /* APPLESHARE */
int wrfileopt(c)
char c;
{
switch(c) {
case 'b':
mode = MACB;
break;
case 'r':
if(mode_restricted) {
return 0;
}
mode = RSRC;
break;
case 'd':
if(mode_restricted) {
return 0;
}
mode = DATA;
break;
case 'u':
if(mode_restricted) {
return 0;
}
mode = TEXT;
break;
case 'U':
if(mode_restricted) {
return 0;
}
mode = UNIX;
break;
case 'f':
mode = FORK;
break;
case '3':
mode = FULL;
break;
case 's':
if(mode_s_restricted) {
return 0;
}
mode = MACS;
break;
#ifdef SCAN
case 'S':
if(mode_s_restricted) {
return 0;
}
mode = MACI;
break;
#endif /* SCAN */
case 'a':
#ifdef APPLESHARE
#ifdef AUFS
check_aufs();
mode = APSH;
break;
#endif /* AUFS */
#ifdef APPLEDOUBLE
check_appledouble();
mode = APSH;
break;
#endif /* APPLEDOUBLE */
#else /* APPLESHARE */
(void)fprintf(stderr, "Sorry, Apple-Unix sharing is not supported.\n");
(void)fprintf(stderr, "Recompile or omit -a option.\n");
exit(1);
#endif /* APPLESHARE */
default:
return 0;
}
return 1;
}
void give_wrfileopt()
{
(void)fprintf(stderr, "File output options:\n");
(void)fprintf(stderr, "-b:\tMacBinary (default)\n");
if(!mode_s_restricted) {
(void)fprintf(stderr, "-s:\tMacBinary stream to standard output\n");
#ifdef SCAN
(void)fprintf(stderr,
"-S:\tas -s but with indication of orignal Unix filename\n");
#endif /* SCAN */
}
(void)fprintf(stderr, "-f:\tthree fork mode, skipping empty forks\n");
(void)fprintf(stderr, "-3:\tthe same, writing also empty forks\n");
if(!mode_restricted) {
(void)fprintf(stderr, "-r:\tresource forks only\n");
(void)fprintf(stderr, "-d:\tdata forks only\n");
(void)fprintf(stderr,
"-u:\tdata forks only with Mac -> Unix text file translation\n");
(void)fprintf(stderr,
"-U:\tas -u, but filename will not have an extension\n");
}
#ifdef APPLESHARE
#ifdef AUFS
(void)fprintf(stderr, "-a:\tAUFS format\n");
#endif /* AUFS */
#ifdef APPLEDOUBLE
(void)fprintf(stderr, "-a:\tAppleDouble format\n");
#endif /* APPLEDOUBLE */
#else /* APPLESHARE */
(void)fprintf(stderr, "-a:\tnot supported, needs recompilation\n");
#endif /* APPLESHARE */
}
void set_wrfileopt(restricted)
{
mode_restricted = restricted;
}
void set_s_wrfileopt(restricted)
{
mode_s_restricted = restricted;
}
char *get_wrfileopt()
{
static char options[20];
(void)strcpy(options, "b");
if(!mode_s_restricted) {
(void)strcat(options, "s");
#ifdef SCAN
(void)strcat(options, "S");
#endif /* SCAN */
}
(void)strcat(options, "f3");
if(!mode_restricted) {
(void)strcat(options, "rduU");
}
(void)strcat(options, "a");
return options;
}
char *get_mina()
{
#ifdef APPLESHARE
#ifdef AUFS
return ", AUFS supported";
#endif /* AUFS */
#ifdef APPLEDOUBLE
return ", AppleDouble supported";
#endif /* APPLEDOUBLE */
#else /* APPLESHARE */
return ", no Apple-Unix sharing supported";
#endif /* APPLESHARE */
}

14
fileio/wrfile.h Executable file
View File

@ -0,0 +1,14 @@
extern char *out_buffer, *out_ptr;
extern void define_name();
extern void start_info();
extern void start_rsrc();
extern void start_data();
extern void end_file();
#ifdef SCAN
extern void do_idf();
#endif /* SCAN */
extern void do_mkdir();
extern void enddir();
extern char *get_mina();

BIN
fileio/wrfile.o Normal file

Binary file not shown.

6
fileio/wrfileopt.h Executable file
View File

@ -0,0 +1,6 @@
extern int wrfileopt();
extern void give_wrfileopt();
extern void set_wrfileopt();
extern void set_s_wrfileopt();
extern char *get_wrfileopt();

76
hexbin/buffer.c Executable file
View File

@ -0,0 +1,76 @@
#include "globals.h"
#include "../util/util.h"
#include "buffer.h"
#include "../fileio/wrfile.h"
extern char *malloc();
extern char *realloc();
extern void exit();
char *data_fork, *rsrc_fork;
int data_size, rsrc_size;
static int max_data_size, max_rsrc_size;
static int do_data;
void put_byte(c)
char c;
{
if(do_data) {
if(data_size >= max_data_size) {
if(max_data_size == 0) {
data_fork = malloc(1024);
} else {
data_fork = realloc(data_fork, (unsigned)max_data_size + 1024);
}
max_data_size += 1024;
if(data_fork == NULL) {
(void)fprintf(stderr, "Insufficient memory.\n");
exit(1);
}
}
data_fork[data_size++] = c;
} else {
if(rsrc_size >= max_rsrc_size) {
if(max_rsrc_size == 0) {
rsrc_fork = malloc(1024);
} else {
rsrc_fork = realloc(rsrc_fork, (unsigned)max_rsrc_size + 1024);
}
max_rsrc_size += 1024;
if(rsrc_fork == NULL) {
(void)fprintf(stderr, "Insufficient memory.\n");
exit(1);
}
}
rsrc_fork[rsrc_size++] = c;
}
}
void set_put(data)
int data;
{
do_data = data;
if(do_data) {
data_size = 0;
} else {
rsrc_size = 0;
}
}
void end_put()
{
if(info_only) {
return;
}
start_info(info, (unsigned long)rsrc_size, (unsigned long)data_size);
if(data_size != 0) {
start_data();
copy(out_ptr, data_fork, data_size);
}
if(rsrc_size != 0) {
start_rsrc();
copy(out_ptr, rsrc_fork, rsrc_size);
}
end_file();
}

6
hexbin/buffer.h Executable file
View File

@ -0,0 +1,6 @@
extern char *data_fork, *rsrc_fork;
extern int data_size, rsrc_size;
extern void put_byte();
extern void set_put();
extern void end_put();

44
hexbin/crc.c Executable file
View File

@ -0,0 +1,44 @@
/* crc.c; do crc calculation. */
#include <stdio.h>
#include "hexbin.h"
#include "crc.h"
#include "../util/masks.h"
#include "globals.h"
extern void exit();
unsigned long crc;
#ifdef HQX
void comp_q_crc(c)
register unsigned int c;
{
unsigned char cc = c;
crc = binhex_updcrc(crc, &cc, 1);
}
void comp_q_crc_n(s, e)
register unsigned char *s, *e;
{
crc = binhex_updcrc(crc, s, e - s);
}
#endif /* HQX */
void verify_crc(calc_crc, file_crc)
unsigned long calc_crc, file_crc;
{
calc_crc &= WORDMASK;
file_crc &= WORDMASK;
if(calc_crc != file_crc) {
(void)fprintf(stderr, "CRC mismatch: got 0x%04lx, need 0x%04lx\n",
file_crc, calc_crc);
#ifdef SCAN
do_error("hexbin: CRC error");
#endif /* SCAN */
exit(1);
}
}

10
hexbin/crc.h Executable file
View File

@ -0,0 +1,10 @@
#define INITCRC binhex_crcinit
extern unsigned long crc;
extern unsigned long binhex_crcinit;
extern unsigned long binhex_updcrc();
extern void comp_q_crc();
extern void comp_q_crc_n();
extern void verify_crc();

134
hexbin/dl.c Executable file
View File

@ -0,0 +1,134 @@
#include "hexbin.h"
#ifdef DL
#include "globals.h"
#include "crc.h"
#include "readline.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../util/util.h"
#include "buffer.h"
#include "printhdr.h"
extern void exit();
static long dl_fork();
static int nchar();
static int nextc();
static char *icp = &line[0];
/* oldest format -- process .dl files */
void dl(macname, filename)
char *macname, *filename;
{
int n;
if(listmode) {
(void)fprintf(stderr, "This file is in \"dl\" format.\n");
}
for(n = 0; n < INFOBYTES; n++) {
info[n] = 0;
}
/* set up for Mac name */
if(macname[0] == '\0') {
/* strip directories */
macname = search_last(filename, '/');
if(macname == NULL) {
macname = filename;
} else {
macname++;
}
/* strip extension */
n = strlen(macname);
if(n > 3) {
n -= 3;
if(!strncmp(macname + n, ".dl", 3)) {
macname[n] = '\0';
}
}
}
n = strlen(macname);
if(n > F_NAMELEN) {
n = F_NAMELEN;
}
(void)strncpy(mh.m_name, macname, n);
(void)strncpy(mh.m_type, "APPL", 4);
(void)strncpy(mh.m_author, "????", 4);
mh.m_name[n] = '\0';
transname(mh.m_name, trname, n);
define_name(trname);
print_header0(0);
print_header1(0, 0);
set_put(1);
mh.m_datalen = 0;
set_put(0);
mh.m_rsrclen = dl_fork();
info[I_NAMEOFF] = n;
(void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
(void)strncpy(info + I_TYPEOFF, mh.m_type, 4);
(void)strncpy(info + I_AUTHOFF, mh.m_author, 4);
put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
print_header2(0);
end_put();
}
static long dl_fork()
{
register unsigned long i, v, c;
register unsigned long n, bytes;
n = 0;
bytes = 0;
v = 0;
crc = 0;
while((i = nchar()) != '|') {
if(i < '@' || i > 'O') {
continue;
}
v = (v << 4) | (i & 0xF);
if((++n & 1) == 0) {
put_byte((char)v);
crc += v;
v = 0;
bytes++;
}
}
c = 0;
for(i = 0 ; i < 8 ; i++) {
c = (c << 4) | (nchar() & 0xF);
}
verify_crc(bytes + crc, c);
return bytes;
}
static int nchar()
{
int i;
if((i = nextc()) == EOF) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
return i & 0177;
}
static int nextc()
{
while(*icp == 0) {
if(readline() == 0) {
return EOF;
}
icp = &line[0];
}
return *icp++;
}
#else /* DL */
int dl; /* keep lint and some compilers happy */
#endif /* DL */

27
hexbin/globals.c Executable file
View File

@ -0,0 +1,27 @@
#include "globals.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../fileio/kind.h"
struct macheader mh;
char info[INFOBYTES];
char trname[64];
int listmode;
int info_only;
int verbose;
int uneven_lines;
int to_read;
int was_macbin;
FILE *ifp;
#ifdef SCAN
void do_error(string)
char *string;
{
do_idf(string, ERROR);
}
#endif /* SCAN */

39
hexbin/globals.h Executable file
View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <string.h>
#ifdef BSD
extern char *rindex();
#define search_last rindex
#else /* BSD */
extern char *strrchr();
#define search_last strrchr
#endif /* BSD */
extern void transname();
extern char info[];
extern char trname[];
typedef struct macheader {
char m_name[128];
char m_type[4];
char m_author[4];
short m_flags;
long m_datalen;
long m_rsrclen;
long m_createtime;
long m_modifytime;
};
extern struct macheader mh;
extern int listmode;
extern int verbose;
extern int info_only;
extern int uneven_lines;
extern int to_read;
extern int was_macbin;
extern FILE *ifp;
extern void do_error();

256
hexbin/hecx.c Executable file
View File

@ -0,0 +1,256 @@
#include "hexbin.h"
#ifdef HECX
#include "globals.h"
#include "crc.h"
#include "readline.h"
#include "../util/masks.h"
#include "../util/util.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "buffer.h"
#include "printhdr.h"
extern void exit();
static void do_o_forks();
static long make_file();
static void comp_c_crc();
static void comp_e_crc();
static int comp_to_bin();
static int hex_to_bin();
static int hexit();
static int compressed;
/* old format -- process .hex and .hcx files */
void hecx(macname, filename)
char *macname, *filename;
{
int n;
for(n = 0; n < INFOBYTES; n++) {
info[n] = 0;
}
compressed = 0;
/* set up name for output files */
if(macname[0] == '\0') {
/* strip directories */
macname = search_last(filename, '/');
if(macname == NULL) {
macname = filename;
} else {
macname++;
}
/* strip extension */
n = strlen(macname);
if(n > 4) {
n -= 4;
if(!strncmp(macname + n, ".hex", 4) ||
!strncmp(macname + n, ".hcx", 4)) {
macname[n] = '\0';
}
}
}
n = strlen(macname);
if(n > F_NAMELEN) {
n = F_NAMELEN;
}
(void)strncpy(mh.m_name, macname, n);
mh.m_name[n] = '\0';
/* "#TYPEAUTH$flag" line already read */
n = strlen(line);
if(n >= 6 && line[0] == '#' && line[n-5] == '$') {
if(n >= 10) {
(void)strncpy(mh.m_type, &line[1], 4);
}
if(n >= 14) {
(void)strncpy(mh.m_author, &line[5], 4);
}
(void)sscanf(&line[n-4], "%4hx", &mh.m_flags);
}
transname(mh.m_name, trname, n);
define_name(trname);
do_o_forks();
if(listmode) {
if(!compressed) {
(void)fprintf(stderr, "This file is in \"hex\" format.\n");
} else {
(void)fprintf(stderr, "This file is in \"hcx\" format.\n");
}
}
print_header0(0);
print_header1(0, 0);
info[I_NAMEOFF] = n;
(void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
(void)strncpy(info + I_TYPEOFF, mh.m_type, 4);
(void)strncpy(info + I_AUTHOFF, mh.m_author, 4);
put2(info + I_FLAGOFF, (unsigned long)mh.m_flags);
put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
print_header2(0);
end_put();
}
static void do_o_forks()
{
int forks = 0, found_crc = 0;
unsigned long calc_crc, file_crc;
crc = 0; /* calculate a crc for both forks */
set_put(0);
set_put(1);
while(!found_crc && readline()) {
if(line[0] == 0) {
continue;
}
if(forks == 0 && strncmp(line, "***COMPRESSED", 13) == 0) {
compressed++;
continue;
}
if(strncmp(line, "***DATA", 7) == 0) {
set_put(1);
mh.m_datalen = make_file(compressed);
forks++;
continue;
}
if(strncmp(line, "***RESOURCE", 11) == 0) {
set_put(0);
mh.m_rsrclen = make_file(compressed);
forks++;
continue;
}
if(compressed && strncmp(line, "***CRC:", 7) == 0) {
found_crc++;
calc_crc = crc;
(void)sscanf(&line[7], "%lx", &file_crc);
break;
}
if(!compressed && strncmp(line, "***CHECKSUM:", 12) == 0) {
found_crc++;
calc_crc = crc & BYTEMASK;
(void)sscanf(&line[12], "%lx", &file_crc);
file_crc &= BYTEMASK;
break;
}
}
if(found_crc) {
verify_crc(calc_crc, file_crc);
} else {
(void)fprintf(stderr, "missing CRC\n");
#ifdef SCAN
do_error("hexbin: missing CRC");
#endif /* SCAN */
exit(1);
}
}
static long make_file(compressed)
int compressed;
{
register long nbytes = 0L;
while(readline()) {
if(line[0] == 0) {
continue;
}
if(strncmp(line, "***END", 6) == 0) {
break;
}
if(compressed) {
nbytes += comp_to_bin();
} else {
nbytes += hex_to_bin();
}
}
return nbytes;
}
static void comp_c_crc(c)
unsigned char c;
{
crc = (crc + c) & WORDMASK;
crc = ((crc << 3) & WORDMASK) | (crc >> 13);
}
static void comp_e_crc(c)
unsigned char c;
{
crc += c;
}
#define SIXB(c) (((c)-0x20) & 0x3f)
static int comp_to_bin()
{
char obuf[BUFSIZ];
register char *ip = line;
register char *op = obuf;
register int n, outcount;
int numread, incount;
numread = strlen(line);
outcount = (SIXB(ip[0]) << 2) | (SIXB(ip[1]) >> 4);
incount = ((outcount / 3) + 1) * 4;
for(n = numread; n < incount; n++) { /* restore lost spaces */
line[n] = ' ';
}
n = 0;
while(n <= outcount) {
*op++ = SIXB(ip[0]) << 2 | SIXB(ip[1]) >> 4;
*op++ = SIXB(ip[1]) << 4 | SIXB(ip[2]) >> 2;
*op++ = SIXB(ip[2]) << 6 | SIXB(ip[3]);
ip += 4;
n += 3;
}
for(n = 1; n <= outcount; n++) {
comp_c_crc((unsigned)obuf[n]);
put_byte(obuf[n]);
}
return outcount;
}
static int hex_to_bin()
{
register char *ip = line;
register int n, outcount;
int c;
n = strlen(line);
outcount = n / 2;
for(n = 0; n < outcount; n++) {
c = hexit((int)*ip++);
comp_e_crc((unsigned)(c = (c << 4) | hexit((int)*ip++)));
put_byte((char)c);
}
return outcount;
}
static int hexit(c)
int c;
{
if('0' <= c && c <= '9') {
return c - '0';
}
if('A' <= c && c <= 'F') {
return c - 'A' + 10;
}
(void)fprintf(stderr, "illegal hex digit: %c", c);
#ifdef SCAN
do_error("hexbin: illegal hex digit");
#endif /* SCAN */
exit(1);
/* NOTREACHED */
}
#else /* HECX */
int hecx; /* keep lint and some compilers happy */
#endif /* HECX */

362
hexbin/hexbin.c Executable file
View File

@ -0,0 +1,362 @@
#ifdef TYPES_H
#include <sys/types.h>
#endif /* TYPES_H */
#include <sys/stat.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 exit();
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");
}

11
hexbin/hexbin.h Executable file
View File

@ -0,0 +1,11 @@
#define DL /* recognize dl format */
#define HECX /* recognize hex and hcx formats */
#define HQX /* recognize hqx format */
#define MU /* recognize mu format */
#define form_dl 0
#define form_hecx 1
#define form_hqx 2
#define form_mu 3
#define form_none (-1)

396
hexbin/hqx.c Executable file
View File

@ -0,0 +1,396 @@
#include "hexbin.h"
#ifdef HQX
#include "globals.h"
#include "readline.h"
#include "crc.h"
#include "buffer.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../util/util.h"
#include "printhdr.h"
extern void exit();
static void get_header();
static void oflush();
static int getq();
static long get2q();
static long get4q();
static getqbuf();
static char *g_macname;
/* New stuff which hopes to improve the speed. */
#define RUNCHAR 0x90
#define DONE 0x7F
#define SKIP 0x7E
#define FAIL 0x7D
static char lookup[256] = {
/* ^@ ^A ^B ^C ^D ^E ^F ^G */
/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
/* \b \t \n ^K ^L \r ^N ^O */
/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
/* ^P ^Q ^R ^S ^T ^U ^V ^W */
/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
/* ! " # $ % & ' */
/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
/* ( ) * + , - . / */
/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
/* 0 1 2 3 4 5 6 7 */
/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
/* 8 9 : ; < = > ? */
/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
/* @ A B C D E F G */
/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
/* H I J K L M N O */
/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
/* P Q R S T U V W */
/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
/* X Y Z [ \ ] ^ _ */
/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
/* ` a b c d e f g */
/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
/* h i j k l m n o */
/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
/* p q r s t u v w */
/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
/* x y z { | } ~ ^? */
/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
};
static int stop = 0;
static unsigned char obuf[BUFSIZ];
static unsigned char *op = obuf;
static unsigned char *oq;
#define S_HEADER 0
#define S_DATAOPEN 1
#define S_DATAWRITE 2
#define S_DATAC1 3
#define S_DATAC2 4
#define S_RSRCOPEN 5
#define S_RSRCWRITE 6
#define S_RSRCC1 7
#define S_RSRCC2 8
#define S_EXCESS 9
static int ostate = S_HEADER;
static unsigned long calc_crc;
static unsigned long file_crc;
static long todo;
#define output(c) { *op++ = (c); if(op >= &obuf[BUFSIZ]) oflush(); }
void hqx(macname)
char *macname;
{
int n, normlen, c;
register char *in, *out;
register int b6, b8, data, lastc = 0;
char state68 = 0, run = 0, linestate, first = 1;
g_macname = macname;
ostate = S_HEADER;
stop = 0;
while(!stop) {
n = strlen((char *)line);
while(n > 0 && line[n - 1] == ' ') {
n--;
}
out = line+n;
if(uneven_lines) {
goto skipcheck;
}
if(first) {
normlen = n;
}
/* Check line for intermediate garbage */
linestate = SKIP;
for(in = line; in < out; in++) {
if((linestate = lookup[*in & 0xff]) == FAIL ||
((linestate == DONE) && !first)) {
break;
}
}
if(linestate != FAIL && n != normlen && linestate != DONE) {
c = fgetc(ifp);
(void)ungetc(c, ifp);
if(lookup[c] == DONE) {
linestate = DONE;
}
}
if(linestate == FAIL || (n != normlen && linestate != DONE)) {
if(verbose && n > 0) {
*out = 0;
(void)fprintf(stderr, "Skip:%s\n", line);
}
if(readline()) {
continue;
} else {
break;
}
}
skipcheck:
in = line;
do {
if((b6 = lookup[*in & 0xff]) >= 64) {
switch (b6) {
case DONE:
first = !first;
if(first) {
goto done;
}
case SKIP:
break;
default:
if(uneven_lines) {
break;
}
(void)fprintf(stderr, "bad char '%c'(%d)\n", *in, *in);
goto done;
}
} else {
/* Pack 6 bits to 8 bits */
switch (state68++) {
case 0:
b8 = b6<<2;
continue; /* No data byte */
case 1:
data = b8 | (b6>>4);
b8 = (b6&0xF) << 4;
break;
case 2:
data = b8 | (b6>>2);
b8 = (b6&0x3) << 6;
break;
case 3:
data = b8 | b6;
state68 = 0;
break;
}
if(!run) {
if(data == RUNCHAR) {
run = 1;
} else {
output(lastc = data);
}
}
else {
if(data == 0) {
output(lastc = RUNCHAR);
} else {
while(--data > 0) {
output(lastc);
}
}
run = 0;
}
}
} while(++in < out);
if(!stop) {
if(!readline()) {
break;
}
}
}
done:
oflush();
if(!stop && ostate != S_EXCESS) {
(void)fprintf(stderr, "premature EOF\n");
#ifdef SCAN
do_error("hexbin: premature EOF");
#endif /* SCAN */
exit(1);
}
end_put();
print_header2(verbose);
}
static void get_header()
{
int n;
unsigned long calc_crc, file_crc;
crc = INITCRC; /* compute a crc for the header */
for(n = 0; n < INFOBYTES; n++) {
info[n] = 0;
}
n = getq(); /* namelength */
n++; /* must read trailing null also */
getqbuf(trname, n); /* read name */
if(g_macname[0] == '\0') {
g_macname = trname;
}
n = strlen(g_macname);
if(n > F_NAMELEN) {
n = F_NAMELEN;
}
(void)strncpy(mh.m_name, g_macname, n);
mh.m_name[n] = '\0';
getqbuf(mh.m_type, 4);
getqbuf(mh.m_author, 4);
mh.m_flags = get2q();
mh.m_datalen = get4q();
mh.m_rsrclen = get4q();
calc_crc = crc;
file_crc = get2q();
verify_crc(calc_crc, file_crc);
if(listmode) {
(void)fprintf(stderr, "This file is in \"hqx\" format.\n");
}
transname(mh.m_name, trname, n);
define_name(trname);
print_header0(0);
print_header1(0, verbose);
info[I_NAMEOFF] = n;
(void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
(void)strncpy(info + I_TYPEOFF, mh.m_type, 4);
(void)strncpy(info + I_AUTHOFF, mh.m_author, 4);
put2(info + I_FLAGOFF, (unsigned long)mh.m_flags);
put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
}
static void oflush()
{
int n, i;
oq = obuf;
while(oq < op && !stop) {
switch (ostate) {
case S_HEADER:
get_header();
++ostate;
break;
case S_DATAOPEN:
set_put(1);
todo = mh.m_datalen;
crc = INITCRC;
++ostate;
break;
case S_RSRCOPEN:
set_put(0);
todo = mh.m_rsrclen;
crc = INITCRC;
++ostate;
break;
case S_DATAWRITE:
case S_RSRCWRITE:
n = op-oq;
if(n > todo) {
n = todo;
}
for(i = 0; i < n; i++) {
put_byte((char)(oq[i]));
}
comp_q_crc_n(oq, oq+n);
oq += n;
todo -= n;
if(todo <= 0) {
++ostate;
}
break;
case S_DATAC1:
case S_RSRCC1:
calc_crc = crc;
file_crc = getq() << 8;
++ostate;
break;
case S_DATAC2:
case S_RSRCC2:
/* Skip crc bytes */
file_crc |= getq();
verify_crc(calc_crc, file_crc);
++ostate;
break;
case S_EXCESS:
(void)fprintf(stderr, "%d excess bytes ignored\n", op-oq);
oq = op;
break;
}
}
op = obuf;
}
static int getq()
{
int c;
if(oq >= op) {
(void)fprintf(stderr, "premature EOF\n");
#ifdef SCAN
do_error("hexbin: premature EOF");
#endif /* SCAN */
exit(1);
}
c = *oq++ & 0xff;
comp_q_crc((unsigned)c);
return c;
}
/* get2q(); q format -- read 2 bytes from input, return short */
static long get2q()
{
short high = getq() << 8;
return high | getq();
}
/* get4q(); q format -- read 4 bytes from input, return long */
static long get4q()
{
int i;
long value = 0;
for(i = 0; i < 4; i++) {
value = (value<<8) | getq();
}
return value;
}
/* getqbuf(); q format -- read n characters from input into buf */
static getqbuf(buf, n)
char *buf;
int n;
{
int i;
for(i = 0; i < n; i++) {
*buf++ = getq();
}
}
#else /* HQX */
int hqx; /* keep lint and some compilers happy */
#endif /* HQX */

35
hexbin/hqx.diff Executable file
View File

@ -0,0 +1,35 @@
*** hqx.c Mon Mar 9 21:36:57 1992
--- n.hqx.c Mon Mar 9 22:07:53 1992
***************
*** 108,114 ****
void hqx(macname)
char *macname;
{
! int n, normlen;
register char *in, *out;
register int b6, b8, data, lastc = 0;
char state68 = 0, run = 0, linestate, first = 1;
--- 108,114 ----
void hqx(macname)
char *macname;
{
! int n, normlen, c;
register char *in, *out;
register int b6, b8, data, lastc = 0;
char state68 = 0, run = 0, linestate, first = 1;
***************
*** 136,141 ****
--- 136,148 ----
if((linestate = lookup[*in & 0xff]) == FAIL ||
((linestate == DONE) && !first)) {
break;
+ }
+ }
+ if(linestate != FAIL && n != normlen && linestate != DONE) {
+ c = fgetc(ifp);
+ (void)ungetc(c, ifp);
+ if(lookup[c] == DONE) {
+ linestate = DONE;
}
}
if(linestate == FAIL || (n != normlen && linestate != DONE)) {

130
hexbin/makefile Executable file
View File

@ -0,0 +1,130 @@
CFLAGS= -O $(CF)
SRCS = hexbin.c \
dl.c \
hecx.c \
hqx.c \
mu.c \
buffer.c \
crc.c \
readline.c \
printhdr.c \
globals.c
OBJS = hexbin.o \
dl.o \
hecx.o \
hqx.o \
mu.o \
buffer.o \
crc.o \
readline.o \
printhdr.o \
globals.o
LIB = ../crc/libcrc.a
TNAME = ../util/transname
BNAME = ../util/backtrans
UNAME = ../util/util
ONAME = ../fileio/wrfile
GNAME = ../fileio/fileglob
XOBJS = $(TNAME).o $(BNAME).o $(UNAME).o $(ONAME).o $(GNAME).o
XSRCS = $(TNAME).c $(BNAME).c $(UNAME).c $(ONAME).c $(GNAME).c
CRCS = ../crc/binhex.c
hexbin: $(OBJS) $(LIB) $(XOBJS)
$(CC) $(CFLAGS) -o hexbin $(OBJS) $(XOBJS) $(LIB)
$(LIB): ../crc/makecrc.c
(cd ../crc; make CC=$(CC) CF="$(CF)" )
$(TNAME).o: $(TNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(BNAME).o: $(BNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(UNAME).o: $(UNAME).c
(cd ../util; make CC=$(CC) CF="$(CF)" )
$(ONAME).o: $(ONAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
$(GNAME).o: $(GNAME).c
(cd ../fileio; make CC=$(CC) CF="$(CF)" )
lint:
lint $(CF) $(LFLAGS) $(SRCS) $(XSRCS) $(CRCS)
clean:
-rm -f *.o
clobber:clean
-rm -f hexbin
hexbin.o: globals.h
hexbin.o: crc.h
hexbin.o: readline.h
hexbin.o: ../util/masks.h
hexbin.o: ../util/util.h
hexbin.o: ../util/patchlevel.h
hexbin.o: ../fileio/wrfile.h
hexbin.o: ../fileio/wrfileopt.h
hexbin.o: ../fileio/machdr.h
hexbin.o: ../fileio/kind.h
hexbin.o: ../util/curtime.h
hexbin.o: hexbin.h
dl.o: hexbin.h
dl.o: globals.h
dl.o: crc.h
dl.o: readline.h
dl.o: ../fileio/machdr.h
dl.o: ../fileio/wrfile.h
dl.o: ../util/util.h
dl.o: buffer.h
dl.o: printhdr.h
hecx.o: hexbin.h
hecx.o: globals.h
hecx.o: crc.h
hecx.o: readline.h
hecx.o: ../util/masks.h
hecx.o: ../util/util.h
hecx.o: ../fileio/machdr.h
hecx.o: ../fileio/wrfile.h
hecx.o: buffer.h
hecx.o: printhdr.h
hqx.o: hexbin.h
hqx.o: globals.h
hqx.o: readline.h
hqx.o: crc.h
hqx.o: buffer.h
hqx.o: ../fileio/machdr.h
hqx.o: ../fileio/wrfile.h
hqx.o: ../util/util.h
hqx.o: printhdr.h
mu.o: hexbin.h
mu.o: globals.h
mu.o: readline.h
mu.o: ../util/masks.h
mu.o: ../util/util.h
mu.o: ../fileio/machdr.h
mu.o: ../fileio/wrfile.h
mu.o: buffer.h
mu.o: printhdr.h
buffer.o: globals.h
buffer.o: ../util/util.h
buffer.o: buffer.h
buffer.o: ../fileio/wrfile.h
crc.o: hexbin.h
crc.o: crc.h
crc.o: ../util/masks.h
crc.o: globals.h
readline.o: readline.h
readline.o: globals.h
printhdr.o: printhdr.h
printhdr.o: globals.h
globals.o: globals.h
globals.o: ../fileio/machdr.h
globals.o: ../fileio/wrfile.h
globals.o: ../fileio/kind.h

225
hexbin/mu.c Executable file
View File

@ -0,0 +1,225 @@
#include "hexbin.h"
#ifdef MU
#include "globals.h"
#include "readline.h"
#include "../util/masks.h"
#include "../util/util.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "buffer.h"
#include "printhdr.h"
extern void exit();
static void do_mu_fork();
static int mu_comp_to_bin();
static int mu_convert();
/* mu format -- process .mu files */
void mu(macname)
char *macname;
{
int n;
for(n = 0; n < INFOBYTES; n++) {
info[n] = 0;
}
/* set up name for output files */
if(macname[0] == '\0') {
n = 0;
while(line[n] != '"') {
n++;
}
macname = line + n + 1;
line[strlen(line) - 1] = 0;
}
n = strlen(macname);
if(n > F_NAMELEN) {
n = F_NAMELEN;
}
(void)strncpy(mh.m_name, macname, n);
mh.m_name[n] = '\0';
info[I_NAMEOFF] = n;
(void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
if(listmode) {
(void)fprintf(stderr, "This file is in \"mu\" format.\n");
}
transname(mh.m_name, trname, n);
define_name(trname);
print_header0(0);
set_put(0);
set_put(1);
do_mu_fork();
mh.m_datalen = data_size;
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
if(strncmp(line, "begin ", 6)) {
(void)fprintf(stderr, "No UU header found.\n");
#ifdef SCAN
do_error("hexbin: No UU header found");
#endif /* SCAN */
exit(1);
}
if(!strncmp(line + 10, " .rsrc", 6)) {
set_put(0);
do_mu_fork();
mh.m_rsrclen = rsrc_size;
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
if(strncmp(line, "begin ", 6)) {
(void)fprintf(stderr, "No UU header found.\n");
#ifdef SCAN
do_error("hexbin: No UU header found");
#endif /* SCAN */
exit(1);
}
} else {
mh.m_rsrclen = 0;
}
if(strncmp(line + 10, " .finfo", 7)) {
(void)fprintf(stderr, "No finder info found.\n");
#ifdef SCAN
do_error("hexbin: No finder info found");
#endif /* SCAN */
exit(1);
}
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
(void)mu_convert(line, info + I_TYPEOFF);
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
if(mu_convert(line, line)) {
(void)fprintf(stderr, "Long finderinfo.\n");
#ifdef SCAN
do_error("hexbin: Long finderinfo");
#endif /* SCAN */
exit(1);
}
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
if(strncmp(line, "end", 3)) {
(void)fprintf(stderr, "\"end\" line missing.\n");
#ifdef SCAN
do_error("hexbin: \"end\" line missing");
#endif /* SCAN */
exit(1);
}
(void)strncpy(mh.m_type, info + I_TYPEOFF, 4);
(void)strncpy(mh.m_author, info + I_AUTHOFF, 4);
print_header1(0, 0);
put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
print_header2(0);
end_put();
}
static void do_mu_fork()
{
long newbytes;
while(readline()) {
if(line[0] == 0) {
continue;
}
newbytes = mu_comp_to_bin();
if(newbytes != 0) {
continue;
}
if(!readline()) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
}
if(strncmp(line, "end", 3)) {
(void)fprintf(stderr, "\"end\" line missing.\n");
#ifdef SCAN
do_error("hexbin: \"end\" line missing");
#endif /* SCAN */
exit(1);
}
return;
}
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("hexbin: Premature EOF");
#endif /* SCAN */
exit(1);
/*NOTREACHED*/
}
static int mu_comp_to_bin()
{
char obuf[BUFSIZ];
int outcount, n;
outcount = mu_convert(line, obuf);
for(n = 0; n < outcount; n++) {
put_byte(obuf[n]);
}
return outcount;
}
#define SIXB(c) (((c)-0x20) & 0x3f)
static int mu_convert(ibuf, obuf)
char *ibuf, *obuf;
{
register char *ip = ibuf;
register char *op = obuf;
register int n, outcount;
int numread, incount;
numread = strlen(ip);
outcount = SIXB(ip[0]);
incount = ((outcount / 3) + 1) * 4;
for(n = numread; n < incount; n++) { /* restore lost spaces */
ip[n] = ' ';
}
ip++;
n = 0;
while(n <= outcount) {
*op++ = SIXB(ip[0]) << 2 | SIXB(ip[1]) >> 4;
*op++ = SIXB(ip[1]) << 4 | SIXB(ip[2]) >> 2;
*op++ = SIXB(ip[2]) << 6 | SIXB(ip[3]);
ip += 4;
n += 3;
}
return outcount;
}
#else /* MU */
int mu; /* keep lint and some compilers happy */
#endif /* MU */

46
hexbin/printhdr.c Executable file
View File

@ -0,0 +1,46 @@
#include "printhdr.h"
#include "globals.h"
/* print out header information in human-readable format */
void print_header0(skip)
int skip;
{
if(listmode) {
(void)fprintf(stderr, "name=\"%s\", ", trname);
if(skip) {
(void)fprintf(stderr, "\n");
}
}
}
/* print out header information in human-readable format */
void print_header1(skip1, skip2)
int skip1, skip2;
{
char ftype[5], fauth[5];
transname(mh.m_type, ftype, 4);
transname(mh.m_author, fauth, 4);
if(listmode) {
if(skip1) {
(void)fprintf(stderr, "\t");
}
(void)fprintf(stderr, "type=%4.4s, author=%4.4s, ", ftype, fauth);
if(skip2) {
(void)fprintf(stderr, "\n");
}
}
}
/* print out header information in human-readable format */
void print_header2(skip)
{
if(listmode) {
if(skip) {
(void)fprintf(stderr, "\t");
}
(void)fprintf(stderr, "data=%ld, rsrc=%ld\n",
mh.m_datalen, mh.m_rsrclen);
}
}

4
hexbin/printhdr.h Executable file
View File

@ -0,0 +1,4 @@
extern void print_header0();
extern void print_header1();
extern void print_header2();

40
hexbin/readline.c Executable file
View File

@ -0,0 +1,40 @@
#include "globals.h"
#include "readline.h"
char line[1024]; /* Allow a lot! */
/* Read a line. Allow termination by CR or LF or both. Also allow for
a non-terminated line at end-of-file. Returns 1 if a line is read,
0 otherwise. */
int readline()
{
int ptr = 0, c;
while(1) {
if(was_macbin && to_read-- <= 0) {
c = EOF;
} else {
c = getc(ifp);
}
if(c == EOF || c == '\n' || c == '\r' || ptr == 1023) {
break;
}
line[ptr++] = c;
}
line[ptr++] = 0;
if(c == EOF) {
if(ptr == 1) {
return 0;
} else {
return 1;
}
}
c = getc(ifp);
if(c != '\n' || c != '\r') {
(void)ungetc(c, ifp);
} else {
to_read--;
}
return 1;
}

2
hexbin/readline.h Executable file
View File

@ -0,0 +1,2 @@
extern char line[];

51
macunpack/arc.h Executable file
View File

@ -0,0 +1,51 @@
#define MAGIC1 0 /* Should be 0x1b, marks Mac extension */
#define KIND 1 /* KIND == 0 marks end of archive */
#define FNAME 2
#define FILLER 33
#define FTYPE 34
#define FAUTH 38
#define FINFO 42
#define FDATA 50
#define FRSRC 54
#define FILLER 58
#define MAGIC2 59 /* Should be 0x1a, true Arc header start */
#define KIND2 60 /* Should be identical to KIND */
#define FNAME2 61 /* A PC-ified version of the filename */
#define SIZE 74
#define DATE 78
#define TIME 80
#define CRC 82
#define SIZE2 84 /* Not present if KIND == 1 */
#define HEADERBYTES 88
typedef struct fileHdr { /* 84 or 88 bytes */
char magic1;
char kind;
char fname[31];
char filler; /* ??? */
char ftype[4];
char fauth[4];
char finfo[8];
unsigned long dataLength;
unsigned long rsrcLength;
char filler;
char magic2;
char kind2;
char fname2[13];
unsigned long size;
unsigned short date;
unsigned short time;
unsigend short crc;
unsigned long size2; /* Identical to size; this is wrong for Arc! */
};
#define smallstored 1
#define stored 2
#define packed 3
#define squeezed 4
#define crunched1 5
#define crunched2 6
#define crunched3 7
#define crunched4 8
#define squashed 9

68
macunpack/bin.c Executable file
View File

@ -0,0 +1,68 @@
#include "macunpack.h"
#ifdef BIN
#include "globals.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../fileio/kind.h"
#include "../util/util.h"
#include "../util/masks.h"
extern void mcb();
void bin(header, data_size, UMcp)
char *header;
int data_size, UMcp;
{
char hdr[INFOBYTES];
unsigned long rsrcLength, dataLength;
hdr[0] = getb(infp);
(void)ungetc(hdr[0], infp);
if(hdr[0] != 0) {
if(!strncmp(header + I_AUTHOFF, "BnHq", 4) && hdr[0] == '(') {
do_indent(indent);
(void)fprintf(stderr, "Sorry, this is a fake BinHex 5.0 file. ");
(void)fprintf(stderr, "Debinhex with hexbin first.\n");
#ifdef SCAN
do_error("macunpack: fake BinHex 5.0");
#endif /* SCAN */
} else {
do_indent(indent);
(void)fprintf(stderr, "Sorry, contents not recognized.\n");
#ifdef SCAN
do_error("macunpack: contents not recognized");
#endif /* SCAN */
}
do_indent(indent);
(void)fprintf(stderr, "Copying as a plain file.\n");
#ifdef SCAN
do_idf("", COPY);
#endif /* SCAN */
mcb(header, (unsigned long)in_data_size, (unsigned long)in_rsrc_size,
in_ds + in_rs);
ds_skip = 0;
rs_skip = 0;
in_ds = 0;
in_rs = 0;
return;
}
if(fread(hdr, 1, INFOBYTES - 1, infp) != INFOBYTES) {
(void)fprintf(stderr, "Can't read file header\n");
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
rsrcLength = get4(hdr + I_RLENOFF);
dataLength = get4(hdr + I_DLENOFF);
if(UMcp) {
/* Why this? Moreover, we are losing the bundle bit! */
put4(hdr + I_RLENOFF, ++rsrcLength);
put4(hdr + I_DLENOFF, ++dataLength);
}
mcb(hdr, rsrcLength, dataLength, data_size - INFOBYTES);
}
#else /* BIN */
int bin; /* keep lint and some compilers happy */
#endif /* BIN */

BIN
macunpack/bin.o Normal file

Binary file not shown.

46
macunpack/bits_be.c Executable file
View File

@ -0,0 +1,46 @@
#include "../util/masks.h"
#include "bits_be.h"
unsigned int bit_be_bitbuf;
char *bit_be_filestart;
int bit_be_inbytes;
static unsigned int bit_be_subbitbuf;
static int bit_be_bitcount;
void bit_be_fillbuf(n) /* Shift bit_be_bitbuf n bits left, read n bits */
int n;
{
bit_be_bitbuf <<= n;
while (n > bit_be_bitcount) {
bit_be_bitbuf |= bit_be_subbitbuf << (n -= bit_be_bitcount);
if(bit_be_inbytes == 0) {
bit_be_subbitbuf = 0;
} else {
bit_be_subbitbuf = *bit_be_filestart++ & BYTEMASK;
bit_be_inbytes--;
}
bit_be_bitcount = 8;
}
bit_be_bitbuf |= bit_be_subbitbuf >> (bit_be_bitcount -= n);
bit_be_bitbuf &= WORDMASK;
}
unsigned int bit_be_getbits(n)
int n;
{
unsigned int x;
x = bit_be_bitbuf >> (BITBUFSIZ - n);
bit_be_fillbuf(n);
return x;
}
void bit_be_init_getbits()
{
bit_be_bitbuf = 0;
bit_be_subbitbuf = 0;
bit_be_bitcount = 0;
bit_be_fillbuf(BITBUFSIZ);
}

10
macunpack/bits_be.h Executable file
View File

@ -0,0 +1,10 @@
#define BITBUFSIZ 16
extern unsigned int bit_be_bitbuf;
extern char *bit_be_filestart;
extern int bit_be_inbytes;
extern void bit_be_fillbuf();
extern unsigned int bit_be_getbits();
extern void bit_be_init_getbits();

719
macunpack/cpt.c Executable file
View File

@ -0,0 +1,719 @@
#include "macunpack.h"
#ifdef DD
#ifndef CPT
#define CPT
#endif /* CPT */
#endif /* DD */
#ifdef CPT
#include "globals.h"
#include "cpt.h"
#include "crc.h"
#include "../util/util.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../fileio/kind.h"
#include "../util/masks.h"
#include "huffman.h"
#define ESC1 0x81
#define ESC2 0x82
#define NONESEEN 0
#define ESC1SEEN 1
#define ESC2SEEN 2
extern char *malloc();
extern char *realloc();
extern int free();
static void cpt_uncompact();
static unsigned char *cpt_data;
static unsigned long cpt_datamax;
static unsigned long cpt_datasize;
static unsigned char cpt_LZbuff[CIRCSIZE];
static unsigned int cpt_LZptr;
static unsigned char *cpt_char;
static unsigned long cpt_crc;
static unsigned long cpt_inlength;
static unsigned long cpt_outlength;
static int cpt_outstat;
static unsigned char cpt_savechar;
static unsigned long cpt_newbits;
static int cpt_bitsavail;
static int cpt_blocksize;
/* Lengths is twice the max number of entries, and include slack. */
#define SLACK 6
static node cpt_Hufftree[512 + SLACK], cpt_LZlength[128 + SLACK],
cpt_LZoffs[256 + SLACK];
static int readcpthdr();
static int cpt_filehdr();
static void cpt_folder();
static void cpt_uncompact();
static void cpt_wrfile();
void cpt_wrfile1();
static void cpt_outch();
static void cpt_rle();
static void cpt_rle_lzh();
static void cpt_readHuff();
static int cpt_get6bits();
static int cpt_getbit();
void cpt()
{
struct cptHdr cpthdr;
struct fileHdr filehdr;
char *cptindex;
int cptindsize;
char *cptptr;
int i;
updcrc = zip_updcrc;
crcinit = zip_crcinit;
cpt_crc = INIT_CRC;
if(readcpthdr(&cpthdr) == 0) {
(void)fprintf(stderr, "Can't read archive header\n");
#ifdef SCAN
do_error("macunpack: Can't read archive header");
#endif /* SCAN */
exit(1);
}
cptindsize = cpthdr.entries * FILEHDRSIZE;
if(cpthdr.commentsize > cptindsize) {
cptindsize = cpthdr.commentsize;
}
cptindex = malloc((unsigned)cptindsize);
if(cptindex == NULL) {
(void)fprintf(stderr, "Insufficient memory, aborting\n");
exit(1);
}
cptptr = cptindex;
if(fread(cptptr, 1, (int)cpthdr.commentsize, infp) != cpthdr.commentsize) {
(void)fprintf(stderr, "Can't read comment.\n");
#ifdef SCAN
do_error("macunpack: Can't read comment");
#endif /* SCAN */
exit(1);
}
cpt_crc = (*updcrc)(cpt_crc, cptptr, cpthdr.commentsize);
for(i = 0; i < cpthdr.entries; i++) {
*cptptr = getc(infp);
cpt_crc = (*updcrc)(cpt_crc, cptptr, 1);
if(*cptptr & 0x80) {
cptptr[F_FOLDER] = 1;
*cptptr &= 0x3f;
} else {
cptptr[F_FOLDER] = 0;
}
if(fread(cptptr + 1, 1, *cptptr, infp) != *cptptr) {
(void)fprintf(stderr, "Can't read file header #%d\n", i+1);
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
cpt_crc = (*updcrc)(cpt_crc, cptptr + 1, *cptptr);
if(cptptr[F_FOLDER]) {
if(fread(cptptr + F_FOLDERSIZE, 1, 2, infp) != 2) {
(void)fprintf(stderr, "Can't read file header #%d\n", i+1);
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
cpt_crc = (*updcrc)(cpt_crc, cptptr + F_FOLDERSIZE, 2);
} else {
if(fread(cptptr + F_VOLUME, 1, FILEHDRSIZE - F_VOLUME, infp) !=
FILEHDRSIZE - F_VOLUME) {
(void)fprintf(stderr, "Can't read file header #%d\n", i+1);
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
cpt_crc = (*updcrc)(cpt_crc, cptptr + F_VOLUME,
FILEHDRSIZE - F_VOLUME);
}
cptptr += FILEHDRSIZE;
}
if(cpt_crc != cpthdr.hdrcrc) {
(void)fprintf(stderr, "Header CRC mismatch: got 0x%08x, need 0x%08x\n",
(int)cpthdr.hdrcrc, (int)cpt_crc);
#ifdef SCAN
do_error("macunpack: Header CRC mismatch");
#endif /* SCAN */
exit(1);
}
cptptr = cptindex;
for(i = 0; i < cpthdr.entries; i++) {
if(cpt_filehdr(&filehdr, cptptr) == -1) {
(void)fprintf(stderr, "Can't read file header #%d\n", i+1);
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
if(filehdr.folder) {
cpt_folder(text, filehdr, cptptr);
i += filehdr.foldersize;
cptptr += filehdr.foldersize * FILEHDRSIZE;
} else {
cpt_uncompact(filehdr);
}
cptptr += FILEHDRSIZE;
}
(void)free(cptindex);
}
static int readcpthdr(s)
struct cptHdr *s;
{
char temp[CHDRSIZE];
if(fread(temp, 1, CPTHDRSIZE, infp) != CPTHDRSIZE) {
return 0;
}
if(temp[C_SIGNATURE] != 1) {
(void)fprintf(stderr, "Not a Compactor file\n");
return 0;
}
cpt_datasize = get4(temp + C_IOFFSET);
s->offset = cpt_datasize;
if(cpt_datasize > cpt_datamax) {
if(cpt_datamax == 0) {
cpt_data = (unsigned char *)malloc((unsigned)cpt_datasize);
} else {
cpt_data = (unsigned char *)realloc((char *)cpt_data,
(unsigned)cpt_datasize);
}
cpt_datamax = cpt_datasize;
}
if(cpt_data == NULL) {
(void)fprintf(stderr, "Insufficient memory, aborting\n");
exit(1);
}
if(fread((char *)(cpt_data + CPTHDRSIZE), 1,
(int)s->offset - CPTHDRSIZE, infp) != s->offset - CPTHDRSIZE) {
return 0;
}
if(fread(temp + CPTHDRSIZE, 1, CPTHDR2SIZE, infp) != CPTHDR2SIZE) {
return 0;
}
cpt_crc = (*updcrc)(cpt_crc, temp + CPTHDRSIZE + C_ENTRIES, 3);
s->hdrcrc = get4(temp + CPTHDRSIZE + C_HDRCRC);
s->entries = get2(temp + CPTHDRSIZE + C_ENTRIES);
s->commentsize = temp[CPTHDRSIZE + C_COMMENT];
return 1;
}
static int cpt_filehdr(f, hdr)
struct fileHdr *f;
char *hdr;
{
register int i;
int n;
char ftype[5], fauth[5];
for(i = 0; i < INFOBYTES; i++) {
info[i] = '\0';
}
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);
transname(hdr + F_FNAME + 1, text, n);
f->folder = hdr[F_FOLDER];
if(f->folder) {
f->foldersize = get2(hdr + F_FOLDERSIZE);
} else {
f->cptFlag = get2(hdr + F_CPTFLAG);
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->fileCRC = get4(hdr + F_FILECRC);
f->FndrFlags = get2(hdr + F_FNDRFLAGS);
f->filepos = get4(hdr + F_FILEPOS);
f->volume = hdr[F_VOLUME];
}
write_it = 1;
if(list) {
do_indent(indent);
if(f->folder) {
(void)fprintf(stderr, "folder=\"%s\"", text);
} else {
transname(hdr + F_FTYPE, ftype, 4);
transname(hdr + F_CREATOR, fauth, 4);
(void)fprintf(stderr,
"name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
text, ftype, fauth,
(long)f->dataLength, (long)f->rsrcLength);
}
if(info_only) {
write_it = 0;
}
if(query) {
write_it = do_query();
} else {
(void)fputc('\n', stderr);
}
}
if(write_it) {
define_name(text);
if(!f->folder) {
copy(info + I_TYPEOFF, hdr + F_FTYPE, 4);
copy(info + I_AUTHOFF, hdr + F_CREATOR, 4);
copy(info + I_FLAGOFF, hdr + F_FNDRFLAGS, 2);
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);
}
}
return 1;
}
static void cpt_folder(name, fileh, cptptr)
char *name;
struct fileHdr fileh;
char *cptptr;
{
int i, nfiles;
char loc_name[64];
struct fileHdr filehdr;
for(i = 0; i < 64; i++) {
loc_name[i] = name[i];
}
if(write_it || info_only) {
cptptr += FILEHDRSIZE;
nfiles = fileh.foldersize;
if(write_it) {
do_mkdir(text, info);
}
indent++;
for(i = 0; i < nfiles; i++) {
if(cpt_filehdr(&filehdr, cptptr) == -1) {
(void)fprintf(stderr, "Can't read file header #%d\n", i+1);
#ifdef SCAN
do_error("macunpack: Can't read file header");
#endif /* SCAN */
exit(1);
}
if(filehdr.folder) {
cpt_folder(text, filehdr, cptptr);
i += filehdr.foldersize;
cptptr += filehdr.foldersize * FILEHDRSIZE;
} else {
cpt_uncompact(filehdr);
}
cptptr += FILEHDRSIZE;
}
if(write_it) {
enddir();
}
indent--;
if(list) {
do_indent(indent);
(void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name);
}
}
}
static void cpt_uncompact(filehdr)
struct fileHdr filehdr;
{
if(filehdr.cptFlag & 1) {
(void)fprintf(stderr, "\tFile is password protected, skipping file\n");
#ifdef SCAN
do_idf("", PROTECTED);
#endif /* SCAN */
return;
}
if(write_it) {
start_info(info, filehdr.rsrcLength, filehdr.dataLength);
cpt_crc = INIT_CRC;
cpt_char = cpt_data + filehdr.filepos;
}
if(verbose) {
(void)fprintf(stderr, "\tRsrc: ");
if(filehdr.compRLength == 0) {
(void)fprintf(stderr, "empty");
} else if(filehdr.cptFlag & 2) {
(void)fprintf(stderr, "RLE/LZH compressed (%4.1f%%)",
100.0 * filehdr.compRLength / filehdr.rsrcLength);
} else {
(void)fprintf(stderr, "RLE compressed (%4.1f%%)",
100.0 * filehdr.compRLength / filehdr.rsrcLength);
}
}
if(write_it) {
start_rsrc();
cpt_wrfile(filehdr.compRLength, filehdr.rsrcLength,
filehdr.cptFlag & 2);
cpt_char = cpt_data + filehdr.filepos + filehdr.compRLength;
}
if(verbose) {
(void)fprintf(stderr, ", Data: ");
if(filehdr.compDLength == 0) {
(void)fprintf(stderr, "empty");
} else if(filehdr.cptFlag & 4) {
(void)fprintf(stderr, "RLE/LZH compressed (%4.1f%%)",
100.0 * filehdr.compDLength / filehdr.dataLength);
} else {
(void)fprintf(stderr, "RLE compressed (%4.1f%%)",
100.0 * filehdr.compDLength / filehdr.dataLength);
}
}
if(write_it) {
start_data();
cpt_wrfile(filehdr.compDLength, filehdr.dataLength,
filehdr.cptFlag & 4);
if(filehdr.fileCRC != cpt_crc) {
(void)fprintf(stderr,
"CRC error on file: need 0x%08lx, got 0x%08lx\n",
(long)filehdr.fileCRC, (long)cpt_crc);
#ifdef SCAN
do_error("macunpack: CRC error on file");
#endif /* SCAN */
exit(1);
}
end_file();
}
if(verbose) {
(void)fprintf(stderr, ".\n");
}
}
static void cpt_wrfile(ibytes, obytes, type)
unsigned long ibytes, obytes;
unsigned short type;
{
if(ibytes == 0) {
return;
}
cpt_outstat = NONESEEN;
cpt_inlength = ibytes;
cpt_outlength = obytes;
cpt_LZptr = 0;
cpt_blocksize = 0x1fff0;
if(type == 0) {
cpt_rle();
} else {
cpt_rle_lzh();
}
cpt_crc = (*updcrc)(cpt_crc, out_buffer, obytes);
}
void cpt_wrfile1(in_char, ibytes, obytes, type, blocksize)
unsigned char *in_char;
unsigned long ibytes, obytes, blocksize;
int type;
{
cpt_char = in_char;
if(ibytes == 0) {
return;
}
cpt_outstat = NONESEEN;
cpt_inlength = ibytes;
cpt_outlength = obytes;
cpt_LZptr = 0;
cpt_blocksize = blocksize;
if(type == 0) {
cpt_rle();
} else {
cpt_rle_lzh();
}
}
static void cpt_outch(ch)
unsigned char ch;
{
cpt_LZbuff[cpt_LZptr++ & (CIRCSIZE - 1)] = ch;
switch(cpt_outstat) {
case NONESEEN:
if(ch == ESC1 && cpt_outlength != 1) {
cpt_outstat = ESC1SEEN;
} else {
cpt_savechar = ch;
*out_ptr++ = ch;
cpt_outlength--;
}
break;
case ESC1SEEN:
if(ch == ESC2) {
cpt_outstat = ESC2SEEN;
} else {
cpt_savechar = ESC1;
*out_ptr++ = ESC1;
cpt_outlength--;
if(cpt_outlength == 0) {
return;
}
if(ch == ESC1 && cpt_outlength != 1) {
return;
}
cpt_outstat = NONESEEN;
cpt_savechar = ch;
*out_ptr++ = ch;
cpt_outlength--;
}
break;
case ESC2SEEN:
cpt_outstat = NONESEEN;
if(ch != 0) {
while(--ch != 0) {
*out_ptr++ = cpt_savechar;
cpt_outlength--;
if(cpt_outlength == 0) {
return;
}
}
} else {
*out_ptr++ = ESC1;
cpt_outlength--;
if(cpt_outlength == 0) {
return;
}
cpt_savechar = ESC2;
*out_ptr++ = cpt_savechar;
cpt_outlength--;
}
}
}
/*---------------------------------------------------------------------------*/
/* Run length encoding */
/*---------------------------------------------------------------------------*/
static void cpt_rle()
{
while(cpt_inlength-- > 0) {
cpt_outch(*cpt_char++);
}
}
/*---------------------------------------------------------------------------*/
/* Run length encoding plus LZ compression plus Huffman encoding */
/*---------------------------------------------------------------------------*/
static void cpt_rle_lzh()
{
int block_count;
unsigned int bptr;
int Huffchar, LZlength, LZoffs;
get_bit = cpt_getbit;
cpt_LZbuff[CIRCSIZE - 3] = 0;
cpt_LZbuff[CIRCSIZE - 2] = 0;
cpt_LZbuff[CIRCSIZE - 1] = 0;
cpt_LZptr = 0;
while(cpt_outlength != 0) {
cpt_readHuff(256, cpt_Hufftree);
cpt_readHuff(64, cpt_LZlength);
cpt_readHuff(128, cpt_LZoffs);
block_count = 0;
cpt_newbits = (*cpt_char++ << 8);
cpt_newbits = cpt_newbits | *cpt_char++;
cpt_newbits = cpt_newbits << 16;
cpt_bitsavail = 16;
while(block_count < cpt_blocksize && cpt_outlength != 0) {
if(cpt_getbit()) {
Huffchar = gethuffbyte(cpt_Hufftree);
cpt_outch((unsigned char)Huffchar);
block_count += 2;
} else {
LZlength = gethuffbyte(cpt_LZlength);
LZoffs = gethuffbyte(cpt_LZoffs);
LZoffs = (LZoffs << 6) | cpt_get6bits();
bptr = cpt_LZptr - LZoffs;
while(LZlength-- > 0) {
cpt_outch(cpt_LZbuff[bptr++ & (CIRCSIZE - 1)]);
}
block_count += 3;
}
}
}
}
/* Based on unimplod from unzip; difference are noted below. */
typedef struct sf_entry {
int Value;
int BitLength;
} sf_entry;
/* See routine LoadTree. The parameter tree (actually an array and
two integers) are only used locally in this version and hence locally
declared. The parameter nodes has been renamed Hufftree.... */
static void cpt_readHuff(size, Hufftree)
int size;
struct node *Hufftree;
{
sf_entry tree_entry[256 + SLACK]; /* maximal number of elements */
int tree_entries;
int tree_MaxLength; /* finishes local declaration of tree */
int treeBytes, i, len; /* declarations from ReadLengths */
/* declarations from SortLengths */
sf_entry *ejm1;
int j;
sf_entry *entry;
/* int i already above */
sf_entry tmp;
int entries;
unsigned a, b;
/* declarations from GenerateTrees */
int codelen, lvlstart, next, parents;
/* int i, j already above */
/* for Compactor */
int tree_count[32];
/* end declarations */
/* next paraphrased from ReadLengths with adaption for Compactor. */
treeBytes = *cpt_char++;
if(size < treeBytes * 2) { /* too many entries, something is wrong! */
(void)fprintf(stderr, "Bytes is: %d, expected: %d\n", treeBytes,
size / 2);
#ifdef SCAN
do_error("macunpack: error in coding tree");
#endif /* SCAN */
exit(1);
}
for(i = 0; i < 32; i++) {
tree_count[i] = 0;
}
i = 0;
tree_MaxLength = 0;
tree_entries = 0;
while(treeBytes-- > 0) { /* adaption for Compactor */
len = (*cpt_char) >> 4;
if(len != 0) { /* only if length unequal zero */
if(len > tree_MaxLength) {
tree_MaxLength = len;
}
tree_count[len]++;
tree_entry[tree_entries].Value = i;
tree_entry[tree_entries++].BitLength = len;
}
i++;
len = *cpt_char++ & NIBBLEMASK;
if(len != 0) { /* only if length unequal zero */
if(len > tree_MaxLength) {
tree_MaxLength = len;
}
tree_count[len]++;
tree_entry[tree_entries].Value = i;
tree_entry[tree_entries++].BitLength = len;
}
i++;
}
/* Compactor allows unused trailing codes in its Huffman tree! */
j = 0;
for(i = 0; i <= tree_MaxLength; i++) {
j = (j << 1) + tree_count[i];
}
j = (1 <<tree_MaxLength) - j;
/* Insert the unused entries for sorting purposes. */
for(i = 0; i < j; i++) {
tree_entry[tree_entries].Value = size;
tree_entry[tree_entries++].BitLength = tree_MaxLength;
}
/* adaption from SortLengths */
entry = &(tree_entry[0]);
entries = tree_entries;
for(i = 0; ++i < entries;) {
tmp = entry[i];
b = tmp.BitLength;
j = i;
while((j > 0) && ((a = (ejm1 = &(entry[j - 1]))->BitLength) >= b)) {
if((a == b) && (ejm1->Value <= tmp.Value)) {
break;
}
*(ejm1 + 1) = *ejm1;
--j;
}
entry[j] = tmp;
}
/* Adapted from GenerateTrees */
i = tree_entries - 1;
/* starting at the upper end (and reversing loop) because of Compactor */
lvlstart = next = size * 2 + SLACK - 1;
/* slight adaption because of different node format used */
for(codelen = tree_MaxLength; codelen >= 1; --codelen) {
while((i >= 0) && (tree_entry[i].BitLength == codelen)) {
Hufftree[next].byte = tree_entry[i].Value;
Hufftree[next].flag = 1;
next--;
i--;
}
parents = next;
if(codelen > 1) {
/* reversed loop */
for(j = lvlstart; j > parents + 1; j-= 2) {
Hufftree[next].one = &(Hufftree[j]);
Hufftree[next].zero = &(Hufftree[j - 1]);
Hufftree[next].flag = 0;
next--;
}
}
lvlstart = parents;
}
Hufftree[0].one = &(Hufftree[next + 2]);
Hufftree[0].zero = &(Hufftree[next + 1]);
Hufftree[0].flag = 0;
}
static int cpt_get6bits()
{
int b = 0, cn;
b = (cpt_newbits >> 26) & 0x3f;
cpt_bitsavail -= 6;
cpt_newbits <<= 6;
if(cpt_bitsavail < 16) {
cn = (*cpt_char++ << 8);
cn |= *cpt_char++;
cpt_newbits |= (cn << (16 - cpt_bitsavail));
cpt_bitsavail += 16;
}
return b;
}
static int cpt_getbit()
{
int b;
b = (cpt_newbits >> 31) & 1;
cpt_bitsavail--;
if(cpt_bitsavail < 16) {
cpt_newbits |= (*cpt_char++ << 8);
cpt_newbits |= *cpt_char++;
cpt_bitsavail += 16;
}
cpt_newbits <<= 1;
return b;
}
#else /* CPT */
int cpt; /* keep lint and some compilers happy */
#endif /* CPT */

93
macunpack/cpt.h Executable file
View File

@ -0,0 +1,93 @@
#define C_SIGNATURE 0
#define C_VOLUME 1
#define C_XMAGIC 2
#define C_IOFFSET 4
#define CPTHDRSIZE 8
#define C_HDRCRC 0
#define C_ENTRIES 4
#define C_COMMENT 6
#define CPTHDR2SIZE 7
#define CHDRSIZE (CPTHDRSIZE+CPTHDR2SIZE)
#define F_FNAME 0
#define F_FOLDER 32
#define F_FOLDERSIZE 33
#define F_VOLUME 35
#define F_FILEPOS 36
#define F_FTYPE 40
#define F_CREATOR 44
#define F_CREATIONDATE 48
#define F_MODDATE 52
#define F_FNDRFLAGS 56
#define F_FILECRC 58
#define F_CPTFLAG 62
#define F_RSRCLENGTH 64
#define F_DATALENGTH 68
#define F_COMPRLENGTH 72
#define F_COMPDLENGTH 76
#define FILEHDRSIZE 80
typedef long OSType;
typedef struct cptHdr { /* 8 bytes */
unsigned char signature; /* = 1 -- for verification */
unsigned char volume; /* for multi-file archives */
unsigned short xmagic; /* verification multi-file consistency*/
unsigned long offset; /* index offset */
/* The following are really in header2 at offset */
unsigned long hdrcrc; /* header crc */
unsigned short entries; /* number of index entries */
unsigned char commentsize; /* number of bytes comment that follow*/
};
typedef struct fileHdr { /* 78 bytes */
unsigned char fName[32]; /* a STR32 */
unsigned char folder; /* set to 1 if a folder */
unsigned short foldersize; /* number of entries in folder */
unsigned char volume; /* for multi-file archives */
unsigned long filepos; /* position of data in file */
OSType fType; /* file type */
OSType fCreator; /* er... */
unsigned long creationDate;
unsigned long modDate; /* !restored-compat w/backup prgms */
unsigned short FndrFlags; /* copy of Finder flags. For our
purposes, we can clear:
busy,onDesk */
unsigned long fileCRC; /* crc on file */
unsigned short cptFlag; /* cpt flags */
unsigned long rsrcLength; /* decompressed lengths */
unsigned long dataLength;
unsigned long compRLength; /* compressed lengths */
unsigned long compDLength;
};
/* file format is:
cptArchiveHdr
file1data
file1RsrcFork
file1DataFork
file2data
file2RsrcFork
file2DataFork
.
.
.
fileNdata
fileNRsrcFork
fileNDataFork
cptIndex
*/
/* cpt flags */
#define encryp 1 /* file is encrypted */
#define crsrc 2 /* resource fork is compressed */
#define cdata 4 /* data fork is compressed */
/* ???? 8 /* unknown */
#define CIRCSIZE 8192

BIN
macunpack/cpt.o Normal file

Binary file not shown.

4
macunpack/crc.c Executable file
View File

@ -0,0 +1,4 @@
unsigned long crcinit;
unsigned long (*updcrc)();

13
macunpack/crc.h Executable file
View File

@ -0,0 +1,13 @@
#define INIT_CRC crcinit
extern unsigned long arc_crcinit;
extern unsigned long binhex_crcinit;
extern unsigned long zip_crcinit;
extern unsigned long arc_updcrc();
extern unsigned long binhex_updcrc();
extern unsigned long zip_updcrc();
extern unsigned long crcinit;
extern unsigned long (*updcrc)();

1042
macunpack/dd.c Executable file

File diff suppressed because it is too large Load Diff

125
macunpack/dd.h Executable file
View File

@ -0,0 +1,125 @@
#define MAGIC1 "DDAR"
#define MAGIC2 "\253\315\000\124"
/* Initial header */
#define ARCHHDRCRC 76
#define ARCHHDRSIZE 78
/* File headers */
#define D_MAGIC 0
#define D_FILL1 4
#define D_FNAME 8
#define D_ISDIR 72
#define D_ENDDIR 73
#define D_DATALENGTH 74
#define D_RSRCLENGTH 78
#define D_CTIME 82
#define D_MTIME 86
#define D_FTYPE 90
#define D_CREATOR 94
#define D_FNDRFLAGS 98
#define D_FILL2 100
#define D_DATACRC 118
#define D_RSRCCRC 120
#define D_HDRCRC 122
#define FILEHDRSIZE 124
/* Compressed file header */
#define C_MAGIC 0
#define C_DATALENGTH 4
#define C_DATACLENGTH 8
#define C_RSRCLENGTH 12
#define C_RSRCCLENGTH 16
#define C_DATAMETHOD 20
#define C_RSRCMETHOD 21
#define C_INFO1 22
#define C_MTIME 24
#define C_CTIME 28
#define C_FTYPE 32
#define C_CREATOR 36
#define C_FNDRFLAGS 40
#define C_FILL1 42
#define C_DATACRC 48
#define C_RSRCCRC 50
#define C_INFO2 52
#define C_DATAINFO 54
#define C_RSRCINFO 56
#define C_FILL2 58
#define C_DATACRC2 78
#define C_RSRCCRC2 80
#define C_HDRCRC 82
#define CFILEHDRSIZE 84
typedef long OSType;
typedef struct fileHdr { /* 124 bytes */
unsigned char magic[4]; /* "DDAR" */
unsigned char fill1[4]; /* ??? */
unsigned char fName[64]; /* a STR63 */
unsigned char isdir; /* starts a directory? */
unsigned char enddir; /* terminates a directory? */
unsigned long dataLength; /* lengths */
unsigned long rsrcLength;
unsigned long creationDate;
unsigned long modDate;
OSType fType; /* file type */
OSType fCreator; /* er... */
unsigned short FndrFlags; /* copy of Finder flags. For our
purposes, we can clear:
busy,onDesk */
unsigned char fill2[18]; /* ??? */
unsigned short datacrc; /* checksum */
unsigned short rsrccrc;
unsigned short hdrcrc; /* true crc */
};
typedef struct fileCHdr { /* 84 bytes */
unsigned char magic[4]; /* "\253\315\000\124" */
unsigned long dataLength; /* lengths */
unsigned long dataCLength;
unsigned long rsrcLength;
unsigned long rsrcCLength;
unsigned char datamethod; /* compression method used */
unsigned char rsrcmethod;
unsigned char info1; /* flags ??? */
unsigned char fill3;
unsigned long modDate;
unsigned long creationDate;
OSType fType; /* file type */
OSType fCreator; /* er... */
unsigned short FndrFlags; /* copy of Finder flags. For our
purposes, we can clear:
busy,onDesk */
unsigned char fill1[6]; /* ??? */
unsigned short datacrc; /* checksum */
unsigned short rsrccrc;
unsigned char info2; /* flags ??? */
unsigned char fill4;
unsigned short datainfo; /* ??? */
unsigned short rsrcinfo; /* ??? */
unsigned char fill2[20]; /* ??? */
unsigned short datacrc2; /* other checksum */
unsigned short rsrccrc2;
unsigned short hdrcrc; /* true crc */
};
#define DD_FILE 0
#define DD_COPY 1
#define DD_SDIR 2
#define DD_EDIR 3
#define DD_IVAL 4
/* Methods used */
#define nocomp 0
#define lzc 1
#define method2 2
#define rle 3
#define huffman 4
#define method5 5
#define method6 6
#define lzss 7
#define cpt_compat 8
#define method9 9
#define ESC 0x144 /* Repeat packing escape */

225
macunpack/de_compress.c Executable file
View File

@ -0,0 +1,225 @@
#include "macunpack.h"
#ifdef SIT
#define DECOMPRESS
#endif /* SIT */
#ifdef LZC
#define DECOMPRESS
#endif /* LZC */
#ifdef DECOMPRESS
#include "globals.h"
#include "../fileio/wrfile.h"
/* Written to allow for bits to be upto 16, MacCompress can use 16 bits */
#define BITS 16
#define HSIZE 69001 /* 95% occupancy */
#define INIT_BITS 9 /* initial number of bits/code */
static int n_bits; /* number of bits/code */
static int maxbits; /* user settable max # bits/code */
static long maxcode; /* maximum code, given n_bits */
static long maxmaxcode; /* should NEVER generate this code */
# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
static long htab [HSIZE];
static unsigned short codetab [HSIZE];
#define tab_prefixof(i) codetab[i]
#define tab_suffixof(i) ((unsigned char *)(htab))[i]
#define de_stack ((unsigned char *)&tab_suffixof(1<<BITS))
static long free_ent = 0; /* first unused entry */
static long getcode();
static int clear_flg = 0;
/*
* the next two codes should not be changed lightly, as they must not
* lie within the contiguous general code space.
*/
#define FIRST 257 /* first free entry */
#define CLEAR 256 /* table clear output code */
static int toread;
void de_compress(ibytes, mb)
unsigned long ibytes;
int mb;
{
register unsigned char *stackp;
register int finchar;
register long code, oldcode, incode;
toread = ibytes;
maxbits = mb;
maxmaxcode = 1 << maxbits;
maxcode = MAXCODE(n_bits = INIT_BITS);
for(code = 255; code >= 0; code--) {
tab_prefixof(code) = 0;
tab_suffixof(code) = (unsigned char)code;
}
free_ent = FIRST;
finchar = oldcode = getcode();
if(oldcode == -1) { /* EOF already? */
return; /* Get out of here */
}
/* first code must be 8 bits = char */
*out_ptr++ = (char)finchar;
stackp = de_stack;
while((code = getcode()) > -1) {
if(code == CLEAR) {
for(code = 255; code >= 0; code--) {
tab_prefixof(code) = 0;
}
clear_flg = 1;
free_ent = FIRST - 1;
if((code = getcode()) == -1) { /* O, untimely death! */
break;
}
}
incode = code;
/*
* Special case for KwKwK string.
*/
if(code >= free_ent) {
*stackp++ = finchar;
code = oldcode;
}
/*
* Generate output characters in reverse order
*/
while(code >= 256) {
*stackp++ = tab_suffixof(code);
code = tab_prefixof(code);
}
*stackp++ = finchar = tab_suffixof(code);
/*
* And put them out in forward order
*/
do {
*out_ptr++ = (char)*--stackp;
} while(stackp > de_stack);
/*
* Generate the new entry.
*/
if((code=free_ent) < maxmaxcode) {
tab_prefixof(code) = (unsigned short)oldcode;
tab_suffixof(code) = finchar;
free_ent = code+1;
}
/*
* Remember previous code.
*/
oldcode = incode;
}
return;
}
static unsigned char rmask[9] =
{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
static int get_core_bytes;
static char *core_ptr;
static int file_bytes();
static int core_bytes();
static long getcode()
{
register long code;
static int offset = 0, size = 0;
static unsigned char buf[BITS];
register int r_off, bits;
register unsigned char *bp = buf;
if(clear_flg > 0 || offset >= size || free_ent > maxcode) {
/*
* If the next entry will be too big for the current code
* size, then we must increase the size. This implies reading
* a new buffer full, too.
*/
if(free_ent > maxcode) {
n_bits++;
if(n_bits == maxbits) {
maxcode = maxmaxcode; /* won't get any bigger now */
} else {
maxcode = MAXCODE(n_bits);
}
}
if(clear_flg > 0) {
maxcode = MAXCODE (n_bits = INIT_BITS);
clear_flg = 0;
}
if(toread == 0) {
return -1;
}
if(get_core_bytes) {
size = core_bytes((char *)buf, (n_bits < toread ? n_bits : toread));
} else {
size = file_bytes((char *)buf, (n_bits < toread ? n_bits : toread));
}
toread -= size;
if(size <= 0) {
(void)fprintf(stderr, "Premature EOF\n");
#ifdef SCAN
do_error("macunpack: Premature EOF");
#endif /* SCAN */
exit(1);
}
offset = 0;
/* Round size down to integral number of codes */
size = (size << 3) - (n_bits - 1);
}
r_off = offset;
bits = n_bits;
/*
* Get to the first byte.
*/
bp += (r_off >> 3);
r_off &= 7;
/* Get first part (low order bits) */
code = (*bp++ >> r_off);
bits -= (8 - r_off);
r_off = 8 - r_off; /* now, offset into code word */
/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
if(bits >= 8) {
code |= *bp++ << r_off;
r_off += 8;
bits -= 8;
}
/* high order bits. */
code |= (*bp & rmask[bits]) << r_off;
offset += n_bits;
return code;
}
static int file_bytes(buf, length)
char *buf;
int length;
{
return fread(buf, 1, length, infp);
}
static int core_bytes(buf, length)
char *buf;
int length;
{
int i;
for(i = 0; i < length; i++) {
*buf++ = *core_ptr++;
}
return length;
}
void core_compress(ptr)
char *ptr;
{
core_ptr = ptr;
get_core_bytes = ptr != NULL;
}
#else /* DECOMPRESS */
int decompress; /* keep lint and some compilers happy */
#endif /* DECOMPRESS */

154
macunpack/de_huffman.c Executable file
View File

@ -0,0 +1,154 @@
#include "macunpack.h"
#ifdef JDW
#define DEHUFFMAN
#endif /* JDW */
#ifdef STF
#define DEHUFFMAN
#endif /* STF */
#ifdef PIT
#define DEHUFFMAN
#endif /* PIT */
#ifdef SIT
#define DEHUFFMAN
#endif /* SIT */
#ifdef CPT
#define DEHUFFMAN
#endif /* CPT */
#ifdef DEHUFFMAN
#include "globals.h"
#include "../util/masks.h"
#include "../fileio/wrfile.h"
#include "huffman.h"
#include "../util/util.h"
int (*get_bit)();
int bytesread;
/* 515 because StuffIt Classic needs more than the needed 511 */
struct node nodelist[515];
static int getbit_be();
static int getbit_le();
static int getdecodebyte();
static node *nodeptr, *read_sub_tree();
static int bit;
void de_huffman(obytes)
unsigned long obytes;
{
while(obytes != 0) {
*out_ptr++ = gethuffbyte(nodelist);
obytes--;
}
return;
}
void de_huffman_end(term)
unsigned int term;
{
int c;
while((c = gethuffbyte(nodelist)) != term) {
*out_ptr++ = c;
}
}
void set_huffman(endian)
int endian;
{
if(endian == HUFF_LE) {
get_bit = getbit_le;
} else if(endian == HUFF_BE) {
get_bit = getbit_be;
}
}
void read_tree()
{
nodeptr = nodelist;
bit = 0; /* put us on a boundary */
(void)read_sub_tree();
}
/* This routine recursively reads the Huffman encoding table and builds
a decoding tree. */
static node *read_sub_tree()
{
node *np;
np = nodeptr++;
if((*get_bit)() == 1) {
np->flag = 1;
np->byte = getdecodebyte();
} else {
np->flag = 0;
np->zero = read_sub_tree();
np->one = read_sub_tree();
}
return np;
}
/* This routine returns the next bit in the input stream (MSB first) */
static int getbit_be()
{
static int b;
if(bit == 0) {
b = getb(infp) & BYTEMASK;
bit = 8;
bytesread++;
}
bit--;
return (b >> bit) & 1;
}
/* This routine returns the next bit in the input stream (LSB first) */
static int getbit_le()
{
static int b;
if(bit == 0) {
b = getb(infp) & BYTEMASK;
bit = 8;
bytesread++;
}
bit--;
return (b >> (7 - bit)) & 1;
}
void clrhuff()
{
bit = 0;
}
int gethuffbyte(l_nodelist)
node *l_nodelist;
{
register node *np;
np = l_nodelist;
while(np->flag == 0) {
np = (*get_bit)() ? np->one : np->zero;
}
return np->byte;
}
int getihuffbyte()
{
return gethuffbyte(nodelist);
}
static int getdecodebyte()
{
register int i, b;
b = 0;
for(i = 8; i > 0; i--) {
b = (b << 1) + (*get_bit)();
}
return b;
}
#else /* DEHUFFMAN */
int dehuffman; /* keep lint and some compilers happy */
#endif /* DEHUFFMAN */

276
macunpack/de_lzah.c Executable file
View File

@ -0,0 +1,276 @@
#include "macunpack.h"
#ifdef SIT
#define DELZAH
#endif /* SIT */
#ifdef LZH
#define DELZAH
#endif /* LZH */
#ifdef DELZAH
#include "globals.h"
#include "../util/masks.h"
#include "../fileio/wrfile.h"
/* Note: compare with LZSS decoding in lharc! */
#define N 314
#define T (2*N-1)
/* Huffman table used for first 6 bits of offset:
#bits codes
3 0x000
4 0x040-0x080
5 0x100-0x2c0
6 0x300-0x5c0
7 0x600-0xbc0
8 0xc00-0xfc0
*/
static unsigned short HuffCode[] = {
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040,
0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040,
0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080,
0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080,
0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0,
0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0,
0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100,
0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140,
0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180,
0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0,
0x200, 0x200, 0x200, 0x200, 0x200, 0x200, 0x200, 0x200,
0x240, 0x240, 0x240, 0x240, 0x240, 0x240, 0x240, 0x240,
0x280, 0x280, 0x280, 0x280, 0x280, 0x280, 0x280, 0x280,
0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0,
0x300, 0x300, 0x300, 0x300, 0x340, 0x340, 0x340, 0x340,
0x380, 0x380, 0x380, 0x380, 0x3c0, 0x3c0, 0x3c0, 0x3c0,
0x400, 0x400, 0x400, 0x400, 0x440, 0x440, 0x440, 0x440,
0x480, 0x480, 0x480, 0x480, 0x4c0, 0x4c0, 0x4c0, 0x4c0,
0x500, 0x500, 0x500, 0x500, 0x540, 0x540, 0x540, 0x540,
0x580, 0x580, 0x580, 0x580, 0x5c0, 0x5c0, 0x5c0, 0x5c0,
0x600, 0x600, 0x640, 0x640, 0x680, 0x680, 0x6c0, 0x6c0,
0x700, 0x700, 0x740, 0x740, 0x780, 0x780, 0x7c0, 0x7c0,
0x800, 0x800, 0x840, 0x840, 0x880, 0x880, 0x8c0, 0x8c0,
0x900, 0x900, 0x940, 0x940, 0x980, 0x980, 0x9c0, 0x9c0,
0xa00, 0xa00, 0xa40, 0xa40, 0xa80, 0xa80, 0xac0, 0xac0,
0xb00, 0xb00, 0xb40, 0xb40, 0xb80, 0xb80, 0xbc0, 0xbc0,
0xc00, 0xc40, 0xc80, 0xcc0, 0xd00, 0xd40, 0xd80, 0xdc0,
0xe00, 0xe40, 0xe80, 0xec0, 0xf00, 0xf40, 0xf80, 0xfc0};
static short HuffLength[] = {
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
unsigned char (*lzah_getbyte)();
static void lzah_inithuf();
static void lzah_reorder();
static void lzah_move();
static void lzah_getbit();
static void lzah_outchar();
static char lzah_buf[4096];
static int lzah_bufptr;
static int lzah_bitsavail;
static int lzah_bits;
static int Frequ[1000];
static int ForwTree[1000];
static int BackTree[1000];
void de_lzah(obytes)
unsigned long obytes;
{
int i, i1, j, ch, byte, offs, skip;
lzah_inithuf();
lzah_bitsavail = 0;
for(i = 0; i < 4036; i++) {
lzah_buf[i] = ' ';
}
lzah_bufptr = 4036;
while(obytes != 0) {
ch = ForwTree[T - 1];
while(ch < T) {
lzah_getbit();
if(lzah_bits & 0x80) {
ch = ch + 1;
}
ch = ForwTree[ch];
}
ch -= T;
if(Frequ[T - 1] >= 0x8000) {
lzah_reorder();
}
i = BackTree[ch + T];
do {
j = ++Frequ[i];
i1 = i + 1;
if(Frequ[i1] < j) {
while(Frequ[++i1] < j) ;
i1--;
Frequ[i] = Frequ[i1];
Frequ[i1] = j;
j = ForwTree[i];
BackTree[j] = i1;
if(j < T) {
BackTree[j + 1] = i1;
}
ForwTree[i] = ForwTree[i1];
ForwTree[i1] = j;
j = ForwTree[i];
BackTree[j] = i;
if(j < T) {
BackTree[j + 1] = i;
}
i = i1;
}
i = BackTree[i];
} while(i != 0);
if(ch < 256) {
lzah_outchar((char)ch);
obytes--;
} else {
if(lzah_bitsavail != 0) {
byte = (lzah_bits << 1) & BYTEMASK;
lzah_bits = (*lzah_getbyte)() & BYTEMASK;
byte |= (lzah_bits >> lzah_bitsavail);
lzah_bits = lzah_bits << (7 - lzah_bitsavail);
} else {
byte = (*lzah_getbyte)() & BYTEMASK;
}
offs = HuffCode[byte];
skip = HuffLength[byte] - 2;
while(skip-- != 0) {
byte = byte + byte;
lzah_getbit();
if(lzah_bits & 0x80) {
byte++;
}
}
offs |= (byte & 0x3f);
offs = ((lzah_bufptr - offs - 1) & 0xfff);
ch = ch - 253;
while(ch-- > 0) {
lzah_outchar(lzah_buf[offs++ & 0xfff]);
obytes--;
if(obytes == 0) {
break;
}
}
}
}
}
static void lzah_inithuf()
{
int i, j;
for(i = 0; i < N; i++) {
Frequ[i] = 1;
ForwTree[i] = i + T;
BackTree[i + T] = i;
}
for(i = 0, j = N; j < T; i += 2, j++) {
Frequ[j] = Frequ[i] + Frequ[i + 1];
ForwTree[j] = i;
BackTree[i] = j;
BackTree[i + 1] = j;
}
Frequ[T] = 0xffff;
BackTree[T - 1] = 0;
}
static void lzah_reorder()
{
int i, j, k, l;
j = 0;
for(i = 0; i < T; i++) {
if(ForwTree[i] >= T) {
Frequ[j] = ((Frequ[i] + 1) >> 1);
ForwTree[j] = ForwTree[i];
j++;
}
}
for(i = 0, j = N; i < T; i += 2, j++) {
k = i + 1;
l = Frequ[i] + Frequ[k];
Frequ[j] = l;
k = j - 1;
while(l < Frequ[k]) {
k--;
}
k = k + 1;
lzah_move(Frequ + k, Frequ + k + 1, j - k);
Frequ[k] = l;
lzah_move(ForwTree + k, ForwTree + k + 1, j - k);
ForwTree[k] = i;
}
for(i = 0; i < T; i++) {
k = ForwTree[i];
if(k >= T) {
BackTree[k] = i;
} else {
BackTree[k] = i;
BackTree[k + 1] = i;
}
}
}
static void lzah_move(p, q, n)
int *p, *q, n;
{
if(p > q) {
while(n-- > 0) {
*q++ = *p++;
}
} else {
p += n;
q += n;
while(n-- > 0) {
*--q = *--p;
}
}
}
static void lzah_getbit()
{
if(lzah_bitsavail != 0) {
lzah_bits = lzah_bits + lzah_bits;
lzah_bitsavail--;
} else {
lzah_bits = (*lzah_getbyte)() & BYTEMASK;
lzah_bitsavail = 7;
}
}
static void lzah_outchar(ch)
char ch;
{
*out_ptr++ = ch;
lzah_buf[lzah_bufptr++] = ch;
lzah_bufptr &= 0xfff;
}
#else /* DELZAH */
int delzah; /* keep lint and some compilers happy */
#endif /* DELZAH */

314
macunpack/de_lzh.c Executable file
View File

@ -0,0 +1,314 @@
#include "macunpack.h"
#ifdef ZMA
#define DELZH
#endif /* ZMA */
#ifdef LZH
#define DELZH
#endif /* LZH */
#ifdef DELZH
#include "globals.h"
#include "../util/masks.h"
#include "../fileio/wrfile.h"
#include "bits_be.h"
/* This code is valid for bitsused upto 15. */
#define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
#define UCHAR_MAX 255
#define THRESHOLD 3
static int decoded;
static int bitsused;
static unsigned int blocksize;
static unsigned int decode_c();
static unsigned int decode_p();
static void make_table();
/* lzh compression */
void de_lzh(ibytes, obytes, data, bits)
long ibytes;
long obytes;
char **data;
int bits;
{
unsigned int i, r, c;
int remains;
bit_be_inbytes = ibytes;
bit_be_filestart = *data;
bitsused = bits;
bit_be_init_getbits();
blocksize = 0;
decoded = 0;
r = 0;
for(;;) {
c = decode_c();
if(decoded) {
*data = bit_be_filestart;
return;
}
if(c <= UCHAR_MAX) {
out_ptr[r++] = c;
obytes--;
if(obytes == 0) {
*data = bit_be_filestart;
return;
}
} else {
remains = c - (UCHAR_MAX + 1 - THRESHOLD);
i = (r - decode_p() - 1);
while(--remains >= 0) {
out_ptr[r++] = out_ptr[i++];
obytes--;
if(obytes == 0) {
*data = bit_be_filestart;
return;
}
}
}
}
}
#define MAXMATCH 256
#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
#define CBIT 9
#define CODE_BIT 16
#define NP (DICBIT + 1)
#define NT (CODE_BIT + 3)
#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
#if NT > NP
# define NPT NT
#else
# define NPT NP
#endif
static unsigned int left[2 * NC - 1], right[2 * NC - 1];
static unsigned char c_len[NC], pt_len[NPT];
static unsigned int c_table[4096], pt_table[256];
static void read_pt_len(nn, nbit, i_special)
int nn;
int nbit;
int i_special;
{
int i, c, n;
unsigned int mask;
n = bit_be_getbits(nbit);
if (n == 0) {
c = bit_be_getbits(nbit);
for (i = 0; i < nn; i++) {
pt_len[i] = 0;
}
for (i = 0; i < 256; i++) {
pt_table[i] = c;
}
} else {
i = 0;
while (i < n) {
c = bit_be_bitbuf >> (BITBUFSIZ - 3);
if (c == 7) {
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3);
while (mask & bit_be_bitbuf) {
mask >>= 1;
c++;
}
}
bit_be_fillbuf((c < 7) ? 3 : c - 3);
pt_len[i++] = c;
if (i == i_special) {
c = bit_be_getbits(2);
while (--c >= 0) {
pt_len[i++] = 0;
}
}
}
while (i < nn) {
pt_len[i++] = 0;
}
make_table(nn, pt_len, 8, pt_table);
}
}
static void read_c_len()
{
int i, c, n;
unsigned int mask;
n = bit_be_getbits(CBIT);
if (n == 0) {
c = bit_be_getbits(CBIT);
for (i = 0; i < NC; i++) {
c_len[i] = 0;
}
for (i = 0; i < 4096; i++) {
c_table[i] = c;
}
} else {
i = 0;
while (i < n) {
c = pt_table[bit_be_bitbuf >> (BITBUFSIZ - 8)];
if (c >= NT) {
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
do {
if (bit_be_bitbuf & mask) {
c = right[c];
} else {
c = left [c];
}
mask >>= 1;
} while (c >= NT);
}
bit_be_fillbuf((int)pt_len[c]);
if (c <= 2) {
if (c == 0) {
c = 1;
} else if (c == 1) {
c = bit_be_getbits(4) + 3;
} else {
c = bit_be_getbits(CBIT) + 20;
}
while (--c >= 0) {
c_len[i++] = 0;
}
} else {
c_len[i++] = c - 2;
}
}
while (i < NC) {
c_len[i++] = 0;
}
make_table(NC, c_len, 12, c_table);
}
}
static unsigned int decode_c()
{
unsigned int j, mask;
if (blocksize == 0) {
blocksize = bit_be_getbits(16);
if (blocksize == 0) {
decoded = 1;
return 0;
}
read_pt_len(NT, TBIT, 3);
read_c_len();
read_pt_len(bitsused + 1, PBIT, -1);
}
blocksize--;
j = c_table[bit_be_bitbuf >> (BITBUFSIZ - 12)];
if (j >= NC) {
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
do {
if (bit_be_bitbuf & mask) {
j = right[j];
} else {
j = left [j];
}
mask >>= 1;
} while (j >= NC);
}
bit_be_fillbuf((int)c_len[j]);
return j;
}
static unsigned int decode_p()
{
unsigned int j, mask;
j = pt_table[bit_be_bitbuf >> (BITBUFSIZ - 8)];
if (j > bitsused) {
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
do {
if (bit_be_bitbuf & mask) {
j = right[j];
} else {
j = left [j];
}
mask >>= 1;
} while (j > bitsused);
}
bit_be_fillbuf((int)pt_len[j]);
if (j != 0) {
j = ((unsigned) 1 << (j - 1)) + bit_be_getbits((int) (j - 1));
}
return j;
}
static void make_table(nchar, bitlen, tablebits, table)
int nchar;
unsigned char bitlen[];
int tablebits;
unsigned int table[];
{
unsigned int count[17], weight[17], start[18], *p;
unsigned int i, k, len, ch, jutbits, avail, nextcode, mask;
for (i = 1; i <= 16; i++) {
count[i] = 0;
}
for (i = 0; i < nchar; i++) {
count[bitlen[i]]++;
}
start[1] = 0;
for (i = 1; i <= 16; i++) {
start[i + 1] = start[i] + (count[i] << (16 - i));
}
jutbits = 16 - tablebits;
for (i = 1; i <= tablebits; i++) {
start[i] >>= jutbits;
weight[i] = (unsigned) 1 << (tablebits - i);
}
while (i <= 16) {
weight[i] = (unsigned) 1 << (16 - i);
i++;
}
i = start[tablebits + 1] >> jutbits;
if (i != (unsigned int)((unsigned) 1 << 16)) {
k = 1 << tablebits;
while (i != k) {
table[i++] = 0;
}
}
avail = nchar;
mask = (unsigned) 1 << (15 - tablebits);
for (ch = 0; ch < nchar; ch++) {
if ((len = bitlen[ch]) == 0) {
continue;
}
nextcode = start[len] + weight[len];
if (len <= tablebits) {
for (i = start[len]; i < nextcode; i++) {
table[i] = ch;
}
} else {
k = start[len];
p = &table[k >> jutbits];
i = len - tablebits;
while (i != 0) {
if (*p == 0) {
right[avail] = left[avail] = 0;
*p = avail++;
}
if (k & mask) {
p = &right[*p];
} else {
p = &left[*p];
}
k <<= 1;
i--;
}
*p = ch;
}
start[len] = nextcode;
}
}
#else /* DELZH */
int delzh; /* keep lint and some compilers happy */
#endif /* DELZH */

558
macunpack/dia.c Executable file
View File

@ -0,0 +1,558 @@
#include "macunpack.h"
#ifdef DIA
#include "globals.h"
#include "dia.h"
#include "../util/curtime.h"
#include "../util/masks.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../fileio/kind.h"
#include "../util/util.h"
extern char *malloc();
extern char *realloc();
static unsigned char *dia_archive;
static int dia_archive_size;
static int dia_max_archive_size;
static int dia_finfo;
static int dia_method;
static unsigned char *dia_archive_ptr;
static unsigned char *dia_header_ptr;
static unsigned char *dia_header_last;
static int dia_forklength;
static int dia_cforklength;
static unsigned char dia_bitbuf[BCHUNKSIZE];
static int dia_LZtab[BCHUNKSIZE];
static unsigned char *dia_bit_base;
static int dia_imask;
static void dia_folder();
static void dia_file();
static void dia_getlength();
static void dia_skipfork();
static void dia_getfork();
static void dia_getblock();
static int dia_decode();
static int dia_prevbit();
void dia(bin_hdr)
unsigned char *bin_hdr;
{
int i, folder, nlength;
unsigned char hdr;
unsigned char *header;
dir_skip = 0;
for(i = 0; i < INFOBYTES; i++) {
info[i] = 0;
}
if(in_data_size > dia_max_archive_size) {
if(dia_archive == NULL) {
dia_archive = (unsigned char *)malloc((unsigned)in_data_size);
} else {
dia_archive = (unsigned char *)realloc((char *)dia_archive,
(unsigned)in_data_size);
}
if(dia_archive == 0) {
(void)fprintf(stderr, "Insufficient memory.\n");
exit(1);
}
dia_max_archive_size = in_data_size;
}
dia_archive_size = in_data_size;
if(fread((char *)dia_archive, 1, in_data_size, infp) != in_data_size) {
(void)fprintf(stderr, "Can't read archive.\n");
#ifdef SCAN
do_error("macunpack: Can't read archive");
#endif /* SCAN */
exit(1);
}
nlength = bin_hdr[I_NAMEOFF] & BYTEMASK;
if(!strncmp((char *)bin_hdr + I_NAMEOFF + nlength - 1, " \272", 2)) {
nlength -= 2;
}
info[I_NAMEOFF] = nlength;
for(i = 1; i <= nlength; i++) {
info[I_NAMEOFF + i] = bin_hdr[I_NAMEOFF + i];
}
hdr = *dia_archive;
folder = hdr & IS_FOLDER;
dia_finfo = hdr & F_INFO;
if(hdr & VOLUME) {
(void)fprintf(stderr, "Multi-segment archives not implemented.\n");
#ifdef SCAN
do_error("macunpack: Multi-segment archive");
#endif /* SCAN */
exit(1);
}
if(hdr & CRYPTED) {
(void)fprintf(stderr, "Encrypted archives not implemented.\n");
#ifdef SCAN
do_idf("", PROTECTED);
#endif /* SCAN */
exit(1);
}
i = (hdr & N_BLOCKS) + 1;
header = (unsigned char *)malloc((unsigned)(i * CHUNKSIZE));
dia_archive_ptr = dia_archive + 1;
dia_header_last = header;
dia_method = 0;
while(i-- > 0) {
dia_getblock(&dia_archive_ptr, &dia_header_last);
}
dia_header_ptr = header;
if(folder) {
dia_folder((unsigned char *)NULL);
} else {
dia_file(*dia_header_ptr++, (unsigned char *)NULL);
}
free((char *)header);
}
static void dia_folder(name)
unsigned char *name;
{
unsigned char lname[32];
int i, length, doit;
unsigned char indicator, *old_ptr;
if(name != NULL) {
for(i = 0; i < INFOBYTES; i++) {
info[i] = 0;
}
length = *name++ & REMAINS;
info[I_NAMEOFF] = length;
for(i = 1; i <= length; i++) {
info[I_NAMEOFF + i] = *name++;
}
} else {
length = info[I_NAMEOFF];
}
if(dia_finfo) {
dia_header_ptr += 20;
}
if(!dir_skip) {
doit = 1;
if(list) {
transname(info + I_NAMEOFF + 1, (char *)lname, length);
do_indent(indent);
(void)fprintf(stderr, "folder=\"%s\"", lname);
if(query) {
doit = do_query();
} else {
(void)fputc('\n', stderr);
}
if(doit) {
indent++;
} else {
dir_skip = 1;
}
}
if(doit && !info_only) {
do_mkdir((char *)lname, info);
}
} else {
dir_skip++;
}
while(dia_header_ptr < dia_header_last) {
indicator = *dia_header_ptr;
if(indicator & LEAVE_FOLDER) {
*dia_header_ptr = indicator & ~LEAVE_FOLDER;
break;
} else if(indicator & ONLY_FOLDER) {
if(indicator == ONLY_FOLDER) {
dia_header_ptr++;
} else {
*dia_header_ptr -= 1;
}
break;
} else if(indicator & FOLDER) {
old_ptr = dia_header_ptr;
dia_header_ptr += (indicator & REMAINS) + 1;
dia_folder(old_ptr);
} else {
dia_header_ptr++;
old_ptr = dia_header_ptr;
dia_header_ptr += (*old_ptr & REMAINS) + 1;
dia_file(indicator, old_ptr);
}
}
if(!dir_skip) {
if(doit) {
indent--;
if(!info_only) {
enddir();
}
do_indent(indent);
(void)fprintf(stderr, "leaving folder \"%s\"\n", lname);
}
} else {
dir_skip--;
}
}
static void dia_file(indicator, name)
unsigned char indicator, *name;
{
unsigned char lname[32];
int i, length, doit;
int n_data, n_rsrc;
unsigned char *old_archive_ptr;
char ftype[5], fauth[5];
int dataLength, rsrcLength;
int cdataLength, crsrcLength;
int dataMethod, rsrcMethod;
unsigned long curtime;
if(name != NULL) {
for(i = 0; i < INFOBYTES; i++) {
info[i] = 0;
}
length = *name++ & REMAINS;
info[I_NAMEOFF] = length;
for(i = 1; i <= length; i++) {
info[I_NAMEOFF + i] = *name++;
}
} else {
length = info[I_NAMEOFF];
}
for(i = 0; i < 4; i++) {
info[I_TYPEOFF + i] = *dia_header_ptr++;
}
for(i = 0; i < 4; i++) {
info[I_AUTHOFF + i] = *dia_header_ptr++;
}
if(indicator & DATE_PRESENT) {
for(i = 0; i < 4; i++) {
info[I_CTIMOFF + i] = *dia_header_ptr++;
}
for(i = 0; i < 4; i++) {
info[I_MTIMOFF + i] = *dia_header_ptr++;
}
} else {
curtime = (unsigned long)time((time_t *)0) + TIMEDIFF;
put4(info + I_CTIMOFF, curtime);
put4(info + I_MTIMOFF, curtime);
}
if(dia_finfo) {
for(i = 0; i < 6; i++) {
info[I_FLAGOFF + i] = *dia_header_ptr++;
}
}
n_data = 0;
if(indicator & HAS_DATA) {
if(indicator & SHORT_DATA) {
n_data = 1;
} else {
n_data = *dia_header_ptr++ + 1;
}
}
n_rsrc = 0;
if(indicator & HAS_RSRC) {
if(indicator & SHORT_RSRC) {
n_rsrc = 1;
} else {
n_rsrc = *dia_header_ptr++ + 1;
}
}
if(!dir_skip) {
old_archive_ptr = dia_archive_ptr;
dia_getlength(n_data);
dataLength = dia_forklength;
cdataLength = dia_cforklength;
dataMethod = dia_method;
dia_getlength(n_rsrc);
rsrcLength = dia_forklength;
crsrcLength = dia_cforklength;
rsrcMethod = dia_method;
dia_archive_ptr = old_archive_ptr;
put4(info + I_DLENOFF, (unsigned long)dataLength);
put4(info + I_RLENOFF, (unsigned long)rsrcLength);
if(list) {
transname(info + I_NAMEOFF + 1, (char *)lname, length);
do_indent(indent);
transname(info + I_TYPEOFF, ftype, 4);
transname(info + I_AUTHOFF, fauth, 4);
(void)fprintf(stderr,
"name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
lname, ftype, fauth, (long)dataLength, (long)rsrcLength);
if(info_only) {
doit = 0;
} else {
doit = 1;
}
if(query) {
doit = do_query();
} else {
(void)fputc('\n', stderr);
}
} else {
doit = 1;
}
} else {
dia_skipfork(n_data);
dia_skipfork(n_rsrc);
return;
}
if(doit) {
define_name((char *)lname);
start_info(info, (unsigned long)rsrcLength, (unsigned long)dataLength);
}
if(verbose) {
(void)fprintf(stderr, "\tData: ");
if(dataLength == 0) {
(void)fprintf(stderr, "empty");
} else if(dataMethod == NOCOMP) {
(void)fprintf(stderr, "No compression");
} else {
if(dataMethod != COMP) {
(void)fprintf(stderr, "Partial ");
}
(void)fprintf(stderr, "LZFK compressed (%4.1f%%)",
100.0 * cdataLength / dataLength);
}
}
if(doit) {
start_data();
dia_getfork(n_data);
} else {
dia_skipfork(n_data);
}
if(verbose) {
(void)fprintf(stderr, ", Rsrc: ");
if(rsrcLength == 0) {
(void)fprintf(stderr, "empty");
} else if(rsrcMethod == NOCOMP) {
(void)fprintf(stderr, "No compression");
} else {
if(rsrcMethod != COMP) {
(void)fprintf(stderr, "Partial ");
}
(void)fprintf(stderr, "LZFK compressed (%4.1f%%)",
100.0 * crsrcLength / rsrcLength);
}
}
if(doit) {
start_rsrc();
dia_getfork(n_rsrc);
} else {
dia_skipfork(n_rsrc);
}
if(verbose) {
(void)fprintf(stderr, ".\n");
}
if(doit) {
end_file();
}
}
static void dia_getlength(nblocks)
int nblocks;
{
int length;
unsigned char *arch_ptr, *block_ptr;
unsigned char block[CHUNKSIZE];
dia_method = 0;
dia_forklength = 0;
dia_cforklength = 0;
while(nblocks > 1) {
nblocks--;
length = get2((char *)dia_archive_ptr);
if(length >= 0x8000) {
length = 0x10000 - length;
dia_method |= NOCOMP;
} else {
dia_method |= COMP;
}
dia_forklength += CHUNKSIZE;
dia_cforklength += length + 2;
dia_archive_ptr += length + 2;
}
if(nblocks == 1) {
arch_ptr = dia_archive_ptr;
block_ptr = block;
dia_getblock(&arch_ptr, &block_ptr);
dia_forklength += block_ptr - block;
dia_cforklength += arch_ptr - dia_archive_ptr;
dia_archive_ptr = arch_ptr;
}
}
static void dia_skipfork(nblocks)
int nblocks;
{
int length;
while(nblocks-- > 0) {
length = get2((char *)dia_archive_ptr);
if(length >= 0x8000) {
length = 0x10000 - length;
}
dia_archive_ptr += length + 2;
}
}
static void dia_getfork(nblocks)
int nblocks;
{
while(nblocks-- > 0) {
dia_getblock(&dia_archive_ptr, (unsigned char **)&out_ptr);
}
}
static void dia_getblock(archive_ptr, block_ptr)
unsigned char **archive_ptr, **block_ptr;
{
int length, i;
unsigned char *arch_ptr, *bl_ptr;
arch_ptr = *archive_ptr;
bl_ptr = *block_ptr;
length = get2((char *)arch_ptr);
arch_ptr += 2;
if(length >= 0x8000) {
length = 0x10000 - length;
for(i = 0; i < length; i++) {
*bl_ptr++ = *arch_ptr++;
}
*block_ptr += length;
dia_method |= NOCOMP;
} else {
*block_ptr += dia_decode(arch_ptr, bl_ptr, length);
dia_method |= COMP;
}
*archive_ptr += length + 2;
}
static int dia_decode(ibuff, obuff, in_length)
unsigned char *ibuff, *obuff; int in_length;
{
int nbits, set_zero, i, j;
unsigned char *bitbuf_ptr;
int count[4];
int *LZtab_ptr;
unsigned char *out_ptr, *buf_ptr, *in_ptr;
int omask;
int LZcount;
int *length_ptr, *nchars_ptr;
int *offsn_ptr, length, nchars, offset;
int *offs_ptr[4];
int nwords;
in_ptr = ibuff + in_length;
nbits = *--in_ptr;
nbits |= (*--in_ptr << 8);
if(nbits == WORDMASK) {
nbits = *--in_ptr;
nbits |= (*--in_ptr << 8);
nbits = nbits + WORDMASK;
}
bitbuf_ptr = dia_bitbuf + BCHUNKSIZE;
*--bitbuf_ptr = *--in_ptr;
set_zero = 0;
dia_bit_base = bitbuf_ptr;
dia_imask = 1 << (7 - (nbits & 7));
if(dia_prevbit()) {
set_zero = 1;
}
for(i = 0; i < nbits; i++) {
if(set_zero) {
*--bitbuf_ptr = 0;
} else {
*--bitbuf_ptr = *--in_ptr;
}
if(dia_prevbit()) {
set_zero = !set_zero;
}
}
/* Now we have the bits in longitudal order; reorder them */
nwords = ((dia_bit_base - bitbuf_ptr) >> 1);
for(i = 0; i < nwords; i++) {
dia_LZtab[i] = 0;
}
omask = 1;
for(i = 0; i < 16; i++) {
j = nwords;
LZtab_ptr = dia_LZtab + nwords;
while(j-- > 0) {
LZtab_ptr--;
if(dia_prevbit()) {
*LZtab_ptr |= omask;
}
}
omask <<= 1;
}
LZcount = nwords / 3;
/* At this point we have in LZtab LZcount triples. Each triple consists
of the following parts:
nchars: the number of characters to take from input
length: the number of characters - 1 to copy from output
offset: the offset in the output buffer
The ordering is as follows:
1. lengths
2. nchars
3. offsets for length 0
4. offsets for length 1
5. offsets for length 2
6. offsets for length 3
7. offsets for other lengths
*/
/* Now first count the occurences of lengths 0 to 3 */
count[0] = 0;
count[1] = 0;
count[2] = 0;
count[3] = 0;
for(i = 0; i < LZcount; i++) {
if((j = dia_LZtab[i]) < 4) {
count[j]++;
}
}
length_ptr = dia_LZtab;
nchars_ptr = dia_LZtab + LZcount;
offs_ptr[0] = nchars_ptr + LZcount;
offs_ptr[1] = offs_ptr[0] + count[0];
offs_ptr[2] = offs_ptr[1] + count[1];
offs_ptr[3] = offs_ptr[2] + count[2];
offsn_ptr = offs_ptr[3] + count[3];
out_ptr = obuff;
for(i = 0; i < LZcount; i++) {
length = *length_ptr++;
nchars = *nchars_ptr++;
if(length < 4) {
offset = *offs_ptr[length]++;
} else {
offset = *offsn_ptr++;
}
while(nchars-- > 0) {
*out_ptr++ = *ibuff++;
}
buf_ptr = out_ptr - length - offset - 1;
while(length-- >= 0) {
*out_ptr++ = *buf_ptr++;
}
}
i = in_ptr - ibuff;
while(i-- > 0) {
*out_ptr++ = *ibuff++;
}
return out_ptr - obuff;
}
static int dia_prevbit()
{
int c;
if(dia_imask == 0x100) {
dia_bit_base--;
dia_imask = 1;
}
c = *dia_bit_base & dia_imask;
dia_imask <<= 1;
return c;
}
#else /* DIA */
int dia; /* keep lint and some compilers happy */
#endif /* DIA */

22
macunpack/dia.h Executable file
View File

@ -0,0 +1,22 @@
#define IS_FOLDER 0x80
#define F_INFO 0x40
#define VOLUME 0x30
#define CRYPTED 0x08
#define N_BLOCKS 0x07
#define LEAVE_FOLDER 0x80
#define ONLY_FOLDER 0x40
#define FOLDER 0x20
#define DATE_PRESENT 0x10
#define HAS_DATA 0x08
#define HAS_RSRC 0x04
#define SHORT_DATA 0x02
#define SHORT_RSRC 0x01
#define REMAINS 0x1f
#define CHUNKSIZE 32767
#define BCHUNKSIZE (CHUNKSIZE * 16 / 7)
#define NOCOMP 1
#define COMP 2

BIN
macunpack/dia.o Normal file

Binary file not shown.

75
macunpack/dir.c Executable file
View File

@ -0,0 +1,75 @@
#include "globals.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "../util/util.h"
#include "../util/masks.h"
extern char *malloc();
extern char *realloc();
static char *dir_stack;
static int dir_ptr = -64;
static int dir_max;
void dir(hdr)
char *hdr;
{
int doit;
if((hdr[I_NAMEOFF] & BYTEMASK) == 0x80) {
if(dir_skip) {
dir_skip--;
return;
}
indent--;
if(list) {
do_indent(indent);
(void)fprintf(stderr, "leaving folder \"%s\"\n",
dir_stack + dir_ptr);
}
if(!info_only) {
enddir();
}
dir_ptr -= 64;
return;
}
if(dir_skip) {
dir_skip++;
return;
}
dir_ptr += 64;
if(dir_ptr == dir_max) {
if(dir_max == 0) {
dir_stack = malloc(64);
} else {
dir_stack = realloc(dir_stack, (unsigned)dir_max + 64);
}
dir_max += 64;
if(dir_stack == NULL) {
(void)fprintf(stderr, "Insufficient memory\n");
exit(1);
}
}
transname(hdr + I_NAMEOFF + 1, dir_stack + dir_ptr,
(int)(hdr[I_NAMEOFF] & 0x7f));
doit = 1;
if(list) {
do_indent(indent);
(void)fprintf(stderr, "folder=\"%s\"", dir_stack + dir_ptr);
if(query) {
doit = do_query();
} else {
(void)fputc('\n', stderr);
}
}
if(!doit) {
dir_ptr -= 64;
dir_skip = 1;
return;
}
if(!info_only) {
do_mkdir(dir_stack + dir_ptr, hdr);
}
indent++;
}

BIN
macunpack/dir.o Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More