mirror of
https://github.com/wnayes/macutils.git
synced 2024-10-12 05:24:04 +00:00
Create macutils repository
This commit is contained in:
commit
72ea2b578a
483
README
Executable file
483
README
Executable 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
174
binhex/binhex.c
Executable 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
192
binhex/dofile.c
Executable 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
51
binhex/makefile
Executable 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
4
comm/comm.h
Executable 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
167
comm/frommac.c
Executable 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
6
comm/globals.c
Executable 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
8
comm/globals.h
Executable 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
91
comm/makefile
Executable 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
22
comm/protocol.h
Executable 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
242
comm/tomac.c
Executable 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
146
comm/tty.c
Executable 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);
|