From 72ea2b578a49db9140f483500e0b97bae6269f4e Mon Sep 17 00:00:00 2001 From: Will Nayes Date: Thu, 22 Mar 2018 19:30:02 -0500 Subject: [PATCH] Create macutils repository --- README | 483 ++++++++++++++++++ binhex/binhex.c | 174 +++++++ binhex/dofile.c | 192 ++++++++ binhex/makefile | 51 ++ comm/comm.h | 4 + comm/frommac.c | 167 +++++++ comm/globals.c | 6 + comm/globals.h | 8 + comm/makefile | 91 ++++ comm/protocol.h | 22 + comm/tomac.c | 242 +++++++++ comm/tty.c | 146 ++++++ comm/xm_from.c | 164 ++++++ comm/xm_to.c | 98 ++++ comm/ym_from.c | 5 + comm/ym_to.c | 5 + comm/zm_from.c | 5 + comm/zm_to.c | 5 + crc/arc.c | 55 +++ crc/arc.o | Bin 0 -> 2024 bytes crc/binhex.c | 55 +++ crc/binhex.o | Bin 0 -> 2032 bytes crc/ccitt.c | 55 +++ crc/ccitt.o | Bin 0 -> 2064 bytes crc/ccitt32.c | 87 ++++ crc/ccitt32.o | Bin 0 -> 3608 bytes crc/kermit.c | 55 +++ crc/kermit.o | Bin 0 -> 2032 bytes crc/libcrc.a | Bin 0 -> 15994 bytes crc/makecrc | Bin 0 -> 14216 bytes crc/makecrc.c | 155 ++++++ crc/makecrc.o | Bin 0 -> 9048 bytes crc/makefile | 27 + crc/zip.c | 87 ++++ crc/zip.o | Bin 0 -> 3592 bytes doc/README.crc | 7 + doc/README.crc.orig | 193 ++++++++ doc/README.hexbin | 31 ++ doc/README.macget | 14 + doc/README.macput | 18 + doc/README.scan | 92 ++++ doc/README.unpit | 62 +++ doc/README.unsit | 46 ++ doc/README.zoom | 101 ++++ fileio/all | 0 fileio/appledouble.h | 53 ++ fileio/aufs.h | 33 ++ fileio/fileglob.c | 2 + fileio/fileglob.h | 2 + fileio/fileglob.o | Bin 0 -> 992 bytes fileio/kind.h | 10 + fileio/machdr.h | 20 + fileio/makefile | 33 ++ fileio/rdfile.c | 1010 +++++++++++++++++++++++++++++++++++++ fileio/rdfile.h | 13 + fileio/rdfile.o | Bin 0 -> 28608 bytes fileio/rdfileopt.h | 5 + fileio/wrfile.c | 847 +++++++++++++++++++++++++++++++ fileio/wrfile.h | 14 + fileio/wrfile.o | Bin 0 -> 20488 bytes fileio/wrfileopt.h | 6 + hexbin/buffer.c | 76 +++ hexbin/buffer.h | 6 + hexbin/crc.c | 44 ++ hexbin/crc.h | 10 + hexbin/dl.c | 134 +++++ hexbin/globals.c | 27 + hexbin/globals.h | 39 ++ hexbin/hecx.c | 256 ++++++++++ hexbin/hexbin.c | 362 ++++++++++++++ hexbin/hexbin.h | 11 + hexbin/hqx.c | 396 +++++++++++++++ hexbin/hqx.diff | 35 ++ hexbin/makefile | 130 +++++ hexbin/mu.c | 225 +++++++++ hexbin/printhdr.c | 46 ++ hexbin/printhdr.h | 4 + hexbin/readline.c | 40 ++ hexbin/readline.h | 2 + macunpack/arc.h | 51 ++ macunpack/bin.c | 68 +++ macunpack/bin.o | Bin 0 -> 4128 bytes macunpack/bits_be.c | 46 ++ macunpack/bits_be.h | 10 + macunpack/cpt.c | 719 +++++++++++++++++++++++++++ macunpack/cpt.h | 93 ++++ macunpack/cpt.o | Bin 0 -> 20616 bytes macunpack/crc.c | 4 + macunpack/crc.h | 13 + macunpack/dd.c | 1042 +++++++++++++++++++++++++++++++++++++++ macunpack/dd.h | 125 +++++ macunpack/de_compress.c | 225 +++++++++ macunpack/de_huffman.c | 154 ++++++ macunpack/de_lzah.c | 276 +++++++++++ macunpack/de_lzh.c | 314 ++++++++++++ macunpack/dia.c | 558 +++++++++++++++++++++ macunpack/dia.h | 22 + macunpack/dia.o | Bin 0 -> 15248 bytes macunpack/dir.c | 75 +++ macunpack/dir.o | Bin 0 -> 3952 bytes macunpack/globals.c | 22 + macunpack/globals.h | 14 + macunpack/globals.o | Bin 0 -> 1464 bytes macunpack/huffman.h | 14 + macunpack/jdw.c | 160 ++++++ macunpack/jdw.h | 23 + macunpack/jdw.o | Bin 0 -> 7256 bytes macunpack/lzc.c | 196 ++++++++ macunpack/lzc.h | 29 ++ macunpack/lzc.o | Bin 0 -> 8880 bytes macunpack/lzh.c | 776 +++++++++++++++++++++++++++++ macunpack/lzh.h | 67 +++ macunpack/macbinary.c | 555 +++++++++++++++++++++ macunpack/macbinary.o | Bin 0 -> 17816 bytes macunpack/macunpack.c | 201 ++++++++ macunpack/macunpack.h | 15 + macunpack/macunpack.o | Bin 0 -> 10808 bytes macunpack/makefile | 230 +++++++++ macunpack/mcb.c | 137 +++++ macunpack/mcb.o | Bin 0 -> 5808 bytes macunpack/pit.c | 285 +++++++++++ macunpack/pit.h | 32 ++ macunpack/pit.o | Bin 0 -> 9584 bytes macunpack/sit.c | 847 +++++++++++++++++++++++++++++++ macunpack/sit.h | 95 ++++ macunpack/sit.o | Bin 0 -> 23664 bytes macunpack/stf.c | 223 +++++++++ macunpack/stf.h | 15 + macunpack/stf.o | Bin 0 -> 7648 bytes macunpack/zma.c | 389 +++++++++++++++ macunpack/zma.h | 53 ++ macunpack/zma.o | Bin 0 -> 14976 bytes macunpack/zmahdr.h | 4 + makefile | 78 +++ man/binhex.1 | 104 ++++ man/frommac.1 | 99 ++++ man/hexbin.1 | 106 ++++ man/macsave.1 | 78 +++ man/macstream.1 | 95 ++++ man/macunpack.1 | 100 ++++ man/macutil.1 | 42 ++ man/tomac.1 | 124 +++++ mixed/dir.c | 75 +++ mixed/globals.c | 12 + mixed/globals.h | 13 + mixed/macbinary.c | 121 +++++ mixed/macsave.c | 96 ++++ mixed/macstream.c | 183 +++++++ mixed/makefile | 92 ++++ mixed/mcb.c | 109 ++++ util/all | 0 util/backtrans.c | 104 ++++ util/backtrans.o | Bin 0 -> 1936 bytes util/curtime.h | 14 + util/makefile | 22 + util/masks.h | 4 + util/patchlevel.h | 3 + util/transname.c | 109 ++++ util/transname.o | Bin 0 -> 1936 bytes util/util.c | 209 ++++++++ util/util.h | 23 + util/util.o | Bin 0 -> 4360 bytes 162 files changed, 17091 insertions(+) create mode 100755 README create mode 100755 binhex/binhex.c create mode 100755 binhex/dofile.c create mode 100755 binhex/makefile create mode 100755 comm/comm.h create mode 100755 comm/frommac.c create mode 100755 comm/globals.c create mode 100755 comm/globals.h create mode 100755 comm/makefile create mode 100755 comm/protocol.h create mode 100755 comm/tomac.c create mode 100755 comm/tty.c create mode 100755 comm/xm_from.c create mode 100755 comm/xm_to.c create mode 100755 comm/ym_from.c create mode 100755 comm/ym_to.c create mode 100755 comm/zm_from.c create mode 100755 comm/zm_to.c create mode 100644 crc/arc.c create mode 100644 crc/arc.o create mode 100644 crc/binhex.c create mode 100644 crc/binhex.o create mode 100644 crc/ccitt.c create mode 100644 crc/ccitt.o create mode 100644 crc/ccitt32.c create mode 100644 crc/ccitt32.o create mode 100644 crc/kermit.c create mode 100644 crc/kermit.o create mode 100644 crc/libcrc.a create mode 100755 crc/makecrc create mode 100755 crc/makecrc.c create mode 100644 crc/makecrc.o create mode 100755 crc/makefile create mode 100644 crc/zip.c create mode 100644 crc/zip.o create mode 100755 doc/README.crc create mode 100755 doc/README.crc.orig create mode 100755 doc/README.hexbin create mode 100755 doc/README.macget create mode 100755 doc/README.macput create mode 100755 doc/README.scan create mode 100755 doc/README.unpit create mode 100755 doc/README.unsit create mode 100755 doc/README.zoom create mode 100644 fileio/all create mode 100755 fileio/appledouble.h create mode 100755 fileio/aufs.h create mode 100755 fileio/fileglob.c create mode 100755 fileio/fileglob.h create mode 100644 fileio/fileglob.o create mode 100755 fileio/kind.h create mode 100755 fileio/machdr.h create mode 100755 fileio/makefile create mode 100755 fileio/rdfile.c create mode 100755 fileio/rdfile.h create mode 100644 fileio/rdfile.o create mode 100755 fileio/rdfileopt.h create mode 100755 fileio/wrfile.c create mode 100755 fileio/wrfile.h create mode 100644 fileio/wrfile.o create mode 100755 fileio/wrfileopt.h create mode 100755 hexbin/buffer.c create mode 100755 hexbin/buffer.h create mode 100755 hexbin/crc.c create mode 100755 hexbin/crc.h create mode 100755 hexbin/dl.c create mode 100755 hexbin/globals.c create mode 100755 hexbin/globals.h create mode 100755 hexbin/hecx.c create mode 100755 hexbin/hexbin.c create mode 100755 hexbin/hexbin.h create mode 100755 hexbin/hqx.c create mode 100755 hexbin/hqx.diff create mode 100755 hexbin/makefile create mode 100755 hexbin/mu.c create mode 100755 hexbin/printhdr.c create mode 100755 hexbin/printhdr.h create mode 100755 hexbin/readline.c create mode 100755 hexbin/readline.h create mode 100755 macunpack/arc.h create mode 100755 macunpack/bin.c create mode 100644 macunpack/bin.o create mode 100755 macunpack/bits_be.c create mode 100755 macunpack/bits_be.h create mode 100755 macunpack/cpt.c create mode 100755 macunpack/cpt.h create mode 100644 macunpack/cpt.o create mode 100755 macunpack/crc.c create mode 100755 macunpack/crc.h create mode 100755 macunpack/dd.c create mode 100755 macunpack/dd.h create mode 100755 macunpack/de_compress.c create mode 100755 macunpack/de_huffman.c create mode 100755 macunpack/de_lzah.c create mode 100755 macunpack/de_lzh.c create mode 100755 macunpack/dia.c create mode 100755 macunpack/dia.h create mode 100644 macunpack/dia.o create mode 100755 macunpack/dir.c create mode 100644 macunpack/dir.o create mode 100755 macunpack/globals.c create mode 100755 macunpack/globals.h create mode 100644 macunpack/globals.o create mode 100755 macunpack/huffman.h create mode 100755 macunpack/jdw.c create mode 100755 macunpack/jdw.h create mode 100644 macunpack/jdw.o create mode 100755 macunpack/lzc.c create mode 100755 macunpack/lzc.h create mode 100644 macunpack/lzc.o create mode 100755 macunpack/lzh.c create mode 100755 macunpack/lzh.h create mode 100755 macunpack/macbinary.c create mode 100644 macunpack/macbinary.o create mode 100755 macunpack/macunpack.c create mode 100755 macunpack/macunpack.h create mode 100644 macunpack/macunpack.o create mode 100755 macunpack/makefile create mode 100755 macunpack/mcb.c create mode 100644 macunpack/mcb.o create mode 100755 macunpack/pit.c create mode 100755 macunpack/pit.h create mode 100644 macunpack/pit.o create mode 100755 macunpack/sit.c create mode 100755 macunpack/sit.h create mode 100644 macunpack/sit.o create mode 100755 macunpack/stf.c create mode 100755 macunpack/stf.h create mode 100644 macunpack/stf.o create mode 100755 macunpack/zma.c create mode 100755 macunpack/zma.h create mode 100644 macunpack/zma.o create mode 100755 macunpack/zmahdr.h create mode 100755 makefile create mode 100755 man/binhex.1 create mode 100755 man/frommac.1 create mode 100755 man/hexbin.1 create mode 100755 man/macsave.1 create mode 100755 man/macstream.1 create mode 100755 man/macunpack.1 create mode 100755 man/macutil.1 create mode 100755 man/tomac.1 create mode 100755 mixed/dir.c create mode 100755 mixed/globals.c create mode 100755 mixed/globals.h create mode 100755 mixed/macbinary.c create mode 100755 mixed/macsave.c create mode 100755 mixed/macstream.c create mode 100755 mixed/makefile create mode 100755 mixed/mcb.c create mode 100644 util/all create mode 100755 util/backtrans.c create mode 100644 util/backtrans.o create mode 100755 util/curtime.h create mode 100755 util/makefile create mode 100755 util/masks.h create mode 100755 util/patchlevel.h create mode 100755 util/transname.c create mode 100644 util/transname.o create mode 100755 util/util.c create mode 100755 util/util.h create mode 100644 util/util.o diff --git a/README b/README new file mode 100755 index 0000000..3968c9a --- /dev/null +++ b/README @@ -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" + diff --git a/binhex/binhex.c b/binhex/binhex.c new file mode 100755 index 0000000..4e58d98 --- /dev/null +++ b/binhex/binhex.c @@ -0,0 +1,174 @@ +#include +#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"); +} + diff --git a/binhex/dofile.c b/binhex/dofile.c new file mode 100755 index 0000000..599127a --- /dev/null +++ b/binhex/dofile.c @@ -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; + } +} + diff --git a/binhex/makefile b/binhex/makefile new file mode 100755 index 0000000..f68ac7e --- /dev/null +++ b/binhex/makefile @@ -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 + diff --git a/comm/comm.h b/comm/comm.h new file mode 100755 index 0000000..715444e --- /dev/null +++ b/comm/comm.h @@ -0,0 +1,4 @@ +#define XM /* Know about XMODEM */ +#undef YM /* Know about YMODEM */ +#undef ZM /* Know about ZMODEM */ + diff --git a/comm/frommac.c b/comm/frommac.c new file mode 100755 index 0000000..41f346b --- /dev/null +++ b/comm/frommac.c @@ -0,0 +1,167 @@ +#include +#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"); +} + diff --git a/comm/globals.c b/comm/globals.c new file mode 100755 index 0000000..4036814 --- /dev/null +++ b/comm/globals.c @@ -0,0 +1,6 @@ +#include "globals.h" + +int xfertype = XMODEM; +int pre_beta = 0; +int time_out = 0; + diff --git a/comm/globals.h b/comm/globals.h new file mode 100755 index 0000000..74b8c19 --- /dev/null +++ b/comm/globals.h @@ -0,0 +1,8 @@ +#define XMODEM 0 +#define YMODEM 1 +#define ZMODEM 2 + +extern int xfertype; +extern int pre_beta; +extern int time_out; + diff --git a/comm/makefile b/comm/makefile new file mode 100755 index 0000000..3298daf --- /dev/null +++ b/comm/makefile @@ -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 + diff --git a/comm/protocol.h b/comm/protocol.h new file mode 100755 index 0000000..a19b7e4 --- /dev/null +++ b/comm/protocol.h @@ -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' + diff --git a/comm/tomac.c b/comm/tomac.c new file mode 100755 index 0000000..dbc6a1d --- /dev/null +++ b/comm/tomac.c @@ -0,0 +1,242 @@ +#include +#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"); +} + diff --git a/comm/tty.c b/comm/tty.c new file mode 100755 index 0000000..38b0708 --- /dev/null +++ b/comm/tty.c @@ -0,0 +1,146 @@ +#include +#include +#ifndef TERMIOS_H +#include +#else /* TERMIOS_H */ +#include +#endif /* TERMIOS_H */ +#include +#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); +} + diff --git a/comm/xm_from.c b/comm/xm_from.c new file mode 100755 index 0000000..d6e1af5 --- /dev/null +++ b/comm/xm_from.c @@ -0,0 +1,164 @@ +#include "comm.h" +#ifdef XM +#include +#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 */ diff --git a/comm/xm_to.c b/comm/xm_to.c new file mode 100755 index 0000000..868b82d --- /dev/null +++ b/comm/xm_to.c @@ -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 */ diff --git a/comm/ym_from.c b/comm/ym_from.c new file mode 100755 index 0000000..9fd9d43 --- /dev/null +++ b/comm/ym_from.c @@ -0,0 +1,5 @@ +#include "comm.h" +#ifdef YM +#else /* YM */ +int ym_from; /* Keep lint and some compilers happy */ +#endif /* YM */ diff --git a/comm/ym_to.c b/comm/ym_to.c new file mode 100755 index 0000000..4e1277b --- /dev/null +++ b/comm/ym_to.c @@ -0,0 +1,5 @@ +#include "comm.h" +#ifdef YM +#else /* YM */ +int ym_to; /* Keep lint and some compilers happy */ +#endif /* YM */ diff --git a/comm/zm_from.c b/comm/zm_from.c new file mode 100755 index 0000000..74ceba7 --- /dev/null +++ b/comm/zm_from.c @@ -0,0 +1,5 @@ +#include "comm.h" +#ifdef ZM +#else /* ZM */ +int zm_from; /* Keep lint and some compilers happy */ +#endif /* ZM */ diff --git a/comm/zm_to.c b/comm/zm_to.c new file mode 100755 index 0000000..741dfce --- /dev/null +++ b/comm/zm_to.c @@ -0,0 +1,5 @@ +#include "comm.h" +#ifdef ZM +#else /* ZM */ +int zm_to; /* Keep lint and some compilers happy */ +#endif /* ZM */ diff --git a/crc/arc.c b/crc/arc.c new file mode 100644 index 0000000..58fbbec --- /dev/null +++ b/crc/arc.c @@ -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); +} + diff --git a/crc/arc.o b/crc/arc.o new file mode 100644 index 0000000000000000000000000000000000000000..d04cd0ce03f8cfd9d38ecf257543b263e45f3737 GIT binary patch literal 2024 zcmb_bd3;kv5T0pDTcD+fs9;g!0T!iC3L+L2XIp5aR@5ruUDGt!3TZJ(wcx?7h>BW8 zyzssi@4I-rYqjEyi1&Shw}=NS8h4YoCcft9Urv5+XXcyvX7-rOpW0BDg9ug-CPUh@ zD8RDZv`tBqpa=?K;i`CLcTJ+9drBS#7HtT07nxvj&+5Q}J{(tqH#7!6liTx= z>~q*btr1_)DA-ngB0i<<@MF0R_p^`iT6qi)vg;tEZV=Z~Gt5*si(BYeyh(<63%e0! zt2@M<6v4Y?2XAM0;cfCbK8xKBZR%FBj9Q^fJtQ8cx%j9&iO*w?;1lvxKA$}ar>Mup zV{|e;AmhA~JqRbN<)Vj9fT+4p+)pvQS02yjuzTPDwOCw02jYeDAl}H9;3e`9K7(Bf z)78b|B03nalt=QT*j3P^t`S$$(QvrBTwFm%;AQeKekfatXUPEHn=OKU)j8s9+6Sho z^TheIKX%Lgcmq2Zrl`}!LYj(a%6eYM&cM@T4XtIT5QL(kc(56? z)6_YqMSDq8>$di`xM@;m7A@u&rt8K;O8nY3V(^S30ywd`5mVBM#iJ?RYOQE^cF>83 zyW-%q1mi()nqx6=q8%wG)Dek<+jXqHBOZ42093}}!O$$7U})jirkT-TB%EyeKP-M- z!_0#BCP`yP?ER&@RIas+F4v!VebQg1l(-`?%moK&ZTi@IxA-U*_fA%)%kwHzBU8p` z$JF%lyWAw(&vLwel@6Gi|9U&^bNwa76Y#sRRn^)seEa{jICpt=ZY*y1Z*`5!w{feN zc=}r0@~l5Y8wT^HFLeR$zP#se)ZA?ESCQrY4A=7Q`(^8`(_n?$-|udCu*S>`c=-c0 f=6yR2!CDs_X`Br4p1)Mbvhm5?e=vhf( literal 0 HcmV?d00001 diff --git a/crc/binhex.c b/crc/binhex.c new file mode 100644 index 0000000..f73720d --- /dev/null +++ b/crc/binhex.c @@ -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); +} + diff --git a/crc/binhex.o b/crc/binhex.o new file mode 100644 index 0000000000000000000000000000000000000000..d883df34140343476dc8179ab659cff5161e8f02 GIT binary patch literal 2032 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5V@!FB*M9T<2ScodjG$ z_g)leTm*uqAJn=aiqol)Z zlfdIBv+iyG-#2H^-ql*my*H!RbMExIZFyJYzW52-8R-Se74XgfzwiCs`+v?$@3&eX zIlrR6W8%ujQyX6|B8nk*J;)SiyHZU0*C_s{Mdvv;qawY$_SB+5KXtm-4z1*y$ildSaq z^1scw>w9+9-tM(8=AP_Tt6|SciE;H=WYetkK;|Hi{Cm6qvFB^<&tAW4|IPj%^TqSb z>O%cW;wI~Dvb)IlL5{)Q+1W}#!`&}bQ^8!%SkC~Qwip;hpfqDu5Cda{0HZVyJI4fI z!UT!SK;;~uG(HNHmRT4+{>P?<8EZ;sU|8Q73`5T+oI5<+sn15|}PkQPL8C)~uO%)E@$3cX~832s41hk-W;lpjTX(3o=))xTFX|XTVrR zsX2*yC8-r940 z;?s%}b5o(#QcNiTO#r0{^bmCbih+Owm_!ihWuY`s3X}>Q5K6!-324%gfQm!X1p_=r zVd82)d61dtDXami51m4{Uk9iF6sNfK!{Zxj5IWxwC=N0cCGLRy1|S9lGzkT$FpRPU zGC=xa`4lGJ0M#c16M)h%_rqu>pg4?;taK8Zy)Zd+wc$|x=*nk61<>7v?*Aa5er)k) zfF=GwdSUuu@dt7by4^q_h7(Xh1*n6$fnuOEfUchtD25()Kp}<~P(eKq2MM72AC&L0 Q>Gy!TKM_eUh>5Nr03q6It^fc4 literal 0 HcmV?d00001 diff --git a/crc/ccitt.c b/crc/ccitt.c new file mode 100644 index 0000000..cedd2ff --- /dev/null +++ b/crc/ccitt.c @@ -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); +} + diff --git a/crc/ccitt.o b/crc/ccitt.o new file mode 100644 index 0000000000000000000000000000000000000000..1cd58c9d2809754fbf1f80c289fb0255116e58a1 GIT binary patch literal 2064 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J;D!FB*M9T<2ScoU5YEJZ8n7y&*;M$Al9=`u*C?vpCY!sxlHE4>{_o8b_mXjr# zt2ak2-g|k@;s2lSJx)?_Hc?<<6nU0%ykv<>Ye?2o@2wiGoKxRDJ^yvh(cY`UW<_d( zVg_v2%f6*e4cp=ty}fF=1J@gp8jBib^SS2%DaN-$|CTbw!h_GaJ9 z^*=p2GiP$G)ZY0u>WbI)s%cq;QUP4XRzg~TZ{In+|M$Gtm9rzdt#?bUUY65d^Tg+9 zjFJwsO#+Xj%(}Pzf8U%vdsk~M_uhSHL&_|GxKk@BcY3 zz29nmflz8p0Kld#^m3NZ*8_c zEOWX3aop#POcR7YD_t@&brK0GPYNq~we|GU6;nG~^S=5&)w#-h^pVM7l?5V=ENLa~ zDJmhXF1MHe+CH;=$MpE;b>C%=+g!h__Q`A_+Xk`lw6Zc$HZm(md=O z6MzX9BrXG$bAZzLC{S8wVfctO6*6PZ2@DL(K!^=615H8)oIn9a23CYH6N1T%ERGNc zn$C{ILok^cI1n5p7Bd4I5)Z-@08&Co?stHykOk6$NbZN5n4FwhQlgj4kX)2pl9|ZmstWaNC;{k$U7k0|NMsl1tf7KuQD*`6<6kh4Av_yDT2@$Fji4& zPNH5(YDEcyUP@v~B7lIsnB$zyVAm2=ua28Yl%y1r7)$V3q|mX-GiDxqviCFD(3F z;%ZQF^c2h+C1_Lw+1*kBLvIH_f z`eFGLCcXfw50-9V;xPMRv=dZ6OddvWLbDep4$}wYhXWZPF?8iSpaSUbLJ!X%pk8e8 z7l0-HKzd>NVeyB}ZlE%T7f|~Zpbq8+ih>24)&0xff)^*cp++]; + } + + return(crc); +} + diff --git a/crc/ccitt32.o b/crc/ccitt32.o new file mode 100644 index 0000000000000000000000000000000000000000..0ae5b117d1dd1097dffa947e6a180ff5ae3b73fa GIT binary patch literal 3608 zcmbu>e_YeW9|!Qy1aS%^n2TWynElhKX-iYKHHA& zi40%GU{G{nP@&Xvi;hy%@VezX-(2NW&Xf~%{ETe7a+fJmx!ZvuC_67uI-^ric1oa~ zV3wT`9P48Uv}ZR3gqzm4_Xq+vY6WHb$Q^wJV{@m;@Y9sZQp}h9A8&86wD#!E3NBp> zzw{0>&oo+Se=*t_8NHXllTnIG;p&)(%VEbf(;Kdz?Y|NZ4VC*r$$*dplT}XF!_O4D zZE#&f<&ChrJNgEgGvXQv-|y24;N|1hdtl3A>`m}xwcA1HsTquir)p|Nu%JQ|3qRm_ z+zpR%hO=O^vnmO?y2RZDH}Y9U@VSIhIXqHap96KNi846e?)3!R-#YO$tW-8W0(Vr2 zABQ*g_*B4(F~h?!*4R`Ee=sB~;DLC~JMfqA$+sa--0~*8U!L|le8AUF4FmmWTHvI+ z`gxe(nArfUqydA_CudF%{}O4&;LXC^FJYu7?|o==SU3%@WVd|`9}g+`5N;_6`W4pK z8RubmXNM7tC z>iV7Fn%3IGP}45D7p7Oa<-)I(g9UJ8tU3c`_QYnxHw>rUE$RZAFY`<3H>Vs#e<)`4bfzVH& zV#qWAk10Anhu5i!K84fWL8CCP!8i=)Vu% zsV>ilQySqtP~>bM4Zn5i6~Y^Mig5TaCt?>YFQ)E3tmq>6 zXM?K?jOx~JgpaAJJ)oB&mIW^o`JIDr31@zXVyXH({30jw0zAX!Ou&?oNdxTiY?*?N z4r#x@_D-KKAfwsv85}NY`Wj}}C4U9))_J`L$Mh3D(0;yA2Vb8O_rv>?q1~{*%Jdd= zY42)-FSN=v@L6NfE6~kgdUpv+fuKRoT9dmKJlRh|I3O5q)Fp_O?%SR)QQ3ZuiRJa|4{TL>2&6>0Dm_lQhb?QbuESNZm)z@LOFSC}Y@bAu1&cx;0H z(&5YC^&$1EU@1G%0meJ99O2KNqwC?V&DGnXp))oR?yPeSg(ph%K~Sl$y$S~DL~Quo zl$$TSeSUB&Eb?yYg&zl}Y2hU-&PT9;n*0DZ#i)nihN#Rla3I6)8+dQw%m~yDG=2vQ zhr~a^S7*H@;il<{8OZ8xnuRYlB>x8U6+VB!_f&>OxOTCl48Aj7q=a|%1(iVki17jV zc}3S#@KBBX8Q7@_t%go&Q!RYWMe{0jaL#Ro-*5t&VH$7lStw0y>w;eu7j!_o1l}94 zjlb|3q$0w?g4kOk_U_xt-p&o=`kRB~d($H0NG!!T?85MLTEnbjEXB!@!_cFNc}SRXgkWa+qA*{83>QS*qGmR>@Yq zc9i+(Sw+ZsAgv8n>!yn}yzHe$Qnpl@l12KmvSle;av*&3Ws;-}G5~2QX$MpDBvSJ;OHcLx$R^1+ z8@6|rPhu$a{ak7-jiu|*le};m_~d0>_~uW4^88tXXks3EALzKZC2o7tN=O`q9>3K3 z&o;iKFvd3j1f5_b)?i(>kp^P_+B?#2ATM*VSpeG-rrAL%$fuuII^JN(qt6W;r{|~L zWyz=eX;0eBOULOvy1k!N5VKu>hb7;3UAC8vCAll@-+>kO54m(cy?-msO@>itEd$w> r1>^Gpm$c1aOJcTrM?w_SGC%gmy4e2z_|jS_KgW_Uu}&s++x)))BO!B! literal 0 HcmV?d00001 diff --git a/crc/kermit.c b/crc/kermit.c new file mode 100644 index 0000000..088a204 --- /dev/null +++ b/crc/kermit.c @@ -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); +} + diff --git a/crc/kermit.o b/crc/kermit.o new file mode 100644 index 0000000000000000000000000000000000000000..9b2f06a83f1826e1977b728e25ca1118de6b2f35 GIT binary patch literal 2032 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5V@!FB*M9T<2Sco7#{PSU;qQhYQFrrgXNO`uAird<7v()`1 z9z6%=My+PAGz{NBcw<^HefoWjsLd%MuGwU<;5@Be7_;Gl#D=Vj|C zt*3E0{@-isa=4Z@Z;@!5I9>1Y@=rDgwqA77JZ%xcbyGSm|9xGF&)?YYtxQX1P7`Qf z|5@$P-U}uN4_kU^T$GC7eqNuK_cf-*m*-gPb-Ab0zi2cpoM^Rp^ClOsv(aIh_bU>3 zUdk5f|F-MB#&UfASFtB6Cnz-T-fXn!Xq1ol^~$)6hcX$wpY5yk_@1|alQ}Z=s@B5A z8!VbOPIk*aUlrnUH!?~0wM_xvPx=1uY|rLi5jnbgqtb$%lMI@VSNmmMjfnAlY@4O? zQLciY!QI)}N(T+dj~0GcdBpfqDu5Cda{0HZVyJI4fI!UT!SK;=xKG(HNH zmRT4+{>P?<8EZ;sU| z8Q73`5T+oI5<+r6EG*=K;(|!-gqxV1T9lhvqL<8&T$Egrn8X0#$CnnQ00m$?ATu*B zvjl85#2%1$K(_z+4*?1gVFr*ml2;iR^olEULFVcemlQ$h3>d2@H78N8B(i;8>H!miZgELsayC!_NLy+~d|FXrZYtDTiYW!4 z37|BA9-6kUG>R1rMBaqta+;vh3o;tt4f0AeselTd&P!zfE21Ee38PhsK> zP<=u$0VoY~Ka6$)io@8*N++S&3zI`v8xGZvu6zbm0Nq{a;SmJXk1hTTu*4roFHAoy z{y^?Qw;L$LZ~`i*0Cg}oPz;m?(Dicy#n9spD8%prDyRqIAOUp$gYrE#{T@*FCnD(u IG12t{0AV#{-v9sr literal 0 HcmV?d00001 diff --git a/crc/libcrc.a b/crc/libcrc.a new file mode 100644 index 0000000000000000000000000000000000000000..3188f6441761c14e7e42f0accd84c5e5ba3ca2be GIT binary patch literal 15994 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 literal 0 HcmV?d00001 diff --git a/crc/makecrc b/crc/makecrc new file mode 100755 index 0000000000000000000000000000000000000000..2600cbf88ee6fe95e879a7d606af86d921b9f986 GIT binary patch literal 14216 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 literal 0 HcmV?d00001 diff --git a/crc/makecrc.c b/crc/makecrc.c new file mode 100755 index 0000000..9112096 --- /dev/null +++ b/crc/makecrc.c @@ -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 + +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); +} + diff --git a/crc/makecrc.o b/crc/makecrc.o new file mode 100644 index 0000000000000000000000000000000000000000..40d1462dab940970b8d3a50fc97be9aa358c3ca1 GIT binary patch literal 9048 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[(crc&0xff)^*cp++]; + } + + return(crc); +} + diff --git a/crc/zip.o b/crc/zip.o new file mode 100644 index 0000000000000000000000000000000000000000..9164027e3da137e6f4a78ce6d90dbeed1d6c4350 GIT binary patch literal 3592 zcmbuBdt95<8OKiugg^+;TJeHtHWhV9M61-wu+VCW40Y5C8=@tI5C{nrNJnLCUKox} z%Tz?!rdWq4y2*eL2)AG<>tq*!5H8^sMAT9*Sc+P-8sF!ayc#n;?vEWl$?u%=p69)s z?>7k#+?=x8M<8H)6R;cEwe3xMsIAq~mqP)-6XA2S-x2AKO27>L|DTDB~8O;gsL=_H>MY z03E(k8N8XYJ2fDj^1MO4lk)d#+D|F3YgBzm*-)FkM0ris%vY2znrAS;0&c*C;Eg^6(8~umV;yC5c<4513{A-L|M0o?7521W8b#e=3m~te7 z(zMpTPI>X5@ngzA)ONp58PeFdNLg?8IZY|9@;gb{W)C_+dC9WmZOY%47y46fO34kT z{7Z!LY|8lPoC_!)Pn-o;QPB)I_sXo``lHZsa6VYs3NJ1)bU0B}9GE*PA9q*{0p9j}Kc&*-w@g&;!(Pu5cN!8J>%1Lvt2HMri!vcUPn zS`obXWupL|99a{?i?qQIcyi3%0ioa`EijSxW1a`1J0qL5^#M)76i_hnsVWVv9b`J z1lV%m#q&!_coMum53Y4Xc5wb--3Yk0H%)@`Iq^n#@sP9~p2TJJ!Hd^)-S9+KVFu?8 zV?VeDEq1_zKU!Pi#rC9eaQ<7V72MB`oT0~O6=AdRVzWdA&cBJv2KO7adVJoS(zWnH zG8_!f&p89Y{jz2T4_fQ};l)igA>eFn5QBT}ssJ8*H6Vf)_oiim^S?A|a4(A0!Grfi z`S9Ww;Wltyh#CX;^s;Gq@bBa~cv0x+0_XJ=3%KvHbi#x2>K1r$ykP>Ie_b;Q?t=qU z@L99_u-=eryl za9^n|fCu+m^5Df|MkP3(Uy%duhpmP1Aa*eqUeuNbfwM440`6U5KJehGNI!UCiR%XE z%O!o_{$zSPJn+>T;l<0&NpQY;cm&)Zt+&I2h~{~C(K3(?u92%MaDKKy3$B4RdU{;; ziYNeH?1&A9CzTq1cyU%5gC`Fs_k-(}GBY?gN40|M_2C`h{HJOwypUSP;YsJpEWG%E zV+NkstYhH1bI}IQr;T&qT2L_!&i@Isz>9k#yWq)Nr7iHHG^rDwyqhit*L~U$aQDqX$=14bb@D+c4-!8xYJ2(B+Rw1cx>>8fYk|G&w&J~f($_!x0-@{;@YbV_-Nq1ctVe6LuoQ_2nM z0|q9~RvMH{o>fx9?mO(b@nP=Y9WXcfI$0d7pL>(W-B)) ^ *cp++]; +#else + crc = (crc>>B) ^ crctab[(crc & ((1< +main() +{ + initcrctab(); +} + +initcrctab() +{ + register int b, i; + WTYPE v; + + + for( b = 0; b <= (1<= 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< +#include + +#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 +**************************************************************************** + diff --git a/doc/README.hexbin b/doc/README.hexbin new file mode 100755 index 0000000..885fa17 --- /dev/null +++ b/doc/README.hexbin @@ -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. + */ + diff --git a/doc/README.macget b/doc/README.macget new file mode 100755 index 0000000..c3038d3 --- /dev/null +++ b/doc/README.macget @@ -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) + */ diff --git a/doc/README.macput b/doc/README.macput new file mode 100755 index 0000000..4d5acb2 --- /dev/null +++ b/doc/README.macput @@ -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 + * +*/ diff --git a/doc/README.scan b/doc/README.scan new file mode 100755 index 0000000..e730c4b --- /dev/null +++ b/doc/README.scan @@ -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 + * + * The format of 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 ; + diff --git a/fileio/all b/fileio/all new file mode 100644 index 0000000..e69de29 diff --git a/fileio/appledouble.h b/fileio/appledouble.h new file mode 100755 index 0000000..c377a00 --- /dev/null +++ b/fileio/appledouble.h @@ -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; + diff --git a/fileio/aufs.h b/fileio/aufs.h new file mode 100755 index 0000000..f642deb --- /dev/null +++ b/fileio/aufs.h @@ -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; + diff --git a/fileio/fileglob.c b/fileio/fileglob.c new file mode 100755 index 0000000..979a488 --- /dev/null +++ b/fileio/fileglob.c @@ -0,0 +1,2 @@ +int bytes_read, bytes_written; + diff --git a/fileio/fileglob.h b/fileio/fileglob.h new file mode 100755 index 0000000..1ecb3ca --- /dev/null +++ b/fileio/fileglob.h @@ -0,0 +1,2 @@ +extern int bytes_read, bytes_written; + diff --git a/fileio/fileglob.o b/fileio/fileglob.o new file mode 100644 index 0000000000000000000000000000000000000000..9d886938d829e3ce7a8a9369fa00c1f1ecec9e48 GIT binary patch literal 992 zcmbVL%}T>S5S}#k54_Zq=%qb~3c3_T1P>A@wU^>SD0q`ix@xgWAX(6!d=($d*U%TJ zGs#XHHk(Tqvfs=%^X+6Olds|UzU6tq%Y!>ud&~lSSID5C1K5LIfYD%Z+dUgSOwPME z;!5<_5~oGSwBdK@3i{5<06w%_>B##H{8j_suJQZGbl`8v5yqni9$sd1^*T>O5ka`n zDu4dSW?HMnc$tz@0Ff_ZEki_|mH5V%R-YQgRB8z#%ySS?8pkR@E=jc#*vQLV%jmuK zrkfGRD5IWlTk^p2*{yu$g6iQ;oZac5h}Jh-e~KwMB^&E6P)ldpa}^**>!5_y&h;6u zF~asL36009Q?cz_@?F#SWHdhpcM$2JyV5!=0soQu-6_;Jg-%Q!gI&La0lW8 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 + diff --git a/fileio/makefile b/fileio/makefile new file mode 100755 index 0000000..b46a7a3 --- /dev/null +++ b/fileio/makefile @@ -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 + diff --git a/fileio/rdfile.c b/fileio/rdfile.c new file mode 100755 index 0000000..f24e1cb --- /dev/null +++ b/fileio/rdfile.c @@ -0,0 +1,1010 @@ +#include +#ifdef TYPES_H +#include +#endif /* TYPES_H */ +#include +#include "machdr.h" +#include "rdfile.h" +#include "rdfileopt.h" +#ifndef DIRENT_H +#include +#define dirstruct direct +#else /* DIRENT_H */ +#include +#define dirstruct dirent +#endif /* DIRENT_H */ +#include "../util/curtime.h" +#include "../util/masks.h" +#include "../util/util.h" + +#ifdef AUFSPLUS +#define AUFS +#endif /* AUFSPLUS */ +#ifdef AUFS +#define APPLESHARE +#endif /* AUFS */ +#ifdef APPLEDOUBLE +#define APPLESHARE +#endif /* APPLEDOUBLE */ + +#define NOTFOUND 0 +#define ISFILE 1 +#define INFOFILE 2 +#define INFOEXT 3 +#define SKIPFILE 4 +#define MACBINARY 5 +#define DIRECTORY 6 +#ifdef APPLESHARE +#define SHAREFILE 7 +#endif /* APPLESHARE */ + +#define DATA_FORMAT 1 +#define RSRC_FORMAT 2 +#define UNIX_FORMAT 3 + +extern char *malloc(); +extern char *realloc(); +extern char *strcpy(); +extern char *strncpy(); +extern char *strcat(); +extern void exit(); + +static void check_files(); +static void read_file(); +static void enter_dir(); +static void exit_dir(); +static int get_stdin_file(); + +char file_info[INFOBYTES]; +char *data_fork, *rsrc_fork; +int data_size, rsrc_size; +static int max_data_size, max_rsrc_size; + +typedef struct filelist { + int nfiles; + char **files; + int *kind; + struct filelist *previous; + int current; +#ifdef APPLESHARE + int shared_dir; +#endif /* APPLESHARE */ +} filelist; + +static int data_only; +static int no_recurse; +static int read_stdin; +static filelist global_files; +static filelist *current_files; +static char f_auth[5]; +static char f_type[5]; +static char f_name[] = ".foldername"; +#ifdef APPLESHARE +#ifdef AUFS +#include "aufs.h" +static char infodir[] = ".finderinfo"; +static char rsrcdir[] = ".resource"; +static void read_aufs_info(); +#endif /* AUFS */ +#ifdef APPLEDOUBLE +#include "appledouble.h" +static char infodir[] = ".AppleDouble"; +static void read_appledouble_info(); +#endif /* APPLEDOUBLE */ +#endif /* APPLESHARE */ +static char filename[255]; +static int filekind; + +void setup(argc, argv) +int argc; +char **argv; +{ + if(argc == 0) { + read_stdin = 1; + } else { + read_stdin = 0; + global_files.previous = NULL; + global_files.nfiles = argc; + global_files.files = argv; + global_files.current = 0; + current_files = &global_files; + check_files(1); + } +} + +static void check_files(initial) +int initial; +{ + struct stat stbuf; + int i, j, n; + char filename[255], filename1[255]; + + /* Check the method to read the file */ + current_files->current = 0; + /* Set initially to NOTFOUND or DIRECTORY */ + n = current_files->nfiles; + current_files->kind = (int *)malloc((unsigned)n * sizeof(int)); + if(current_files->kind == NULL) { + (void)fprintf(stderr, "Insufficient memory\n"); + exit(1); + } + for(i = 0; i < n; i++) { + current_files->kind[i] = NOTFOUND; + if(stat(current_files->files[i], &stbuf) >= 0) { + if((stbuf.st_mode & S_IFMT) == S_IFDIR) { + /* We found a directory */ + current_files->kind[i] = DIRECTORY; + continue; + } + current_files->kind[i] = ISFILE; + } + } + /* That is enough for data_only mode */ + if(data_only) { + return; + } +#ifdef APPLESHARE + /* First check whether we are in a folder on a shared volume */ + i = 1; +#ifdef AUFS + if(stat(rsrcdir,&stbuf) < 0) { + i = 0; + } else { + if((stbuf.st_mode & S_IFMT) != S_IFDIR) { + i = 0; + } + } + if(stat(infodir,&stbuf) < 0) { + i = 0; + } else { + if((stbuf.st_mode & S_IFMT) != S_IFDIR) { + i = 0; + } + } +#endif /* AUFS */ +#ifdef APPLEDOUBLE + if(stat(infodir,&stbuf) < 0) { + i = 0; + } else { + if((stbuf.st_mode & S_IFMT) != S_IFDIR) { + i = 0; + } + } +#endif /* APPLEDOUBLE */ + current_files->shared_dir = i; +#endif /* APPLESHARE */ + for(i = 0; i < n; i++) { + if(current_files->kind[i] == NOTFOUND) { + j = 0; + } else if(current_files->kind[i] == ISFILE) { + /* Check whether the file is special */ +#ifdef APPLESHARE + if(!current_files->shared_dir && + !strcmp(current_files->files[i], f_name)) { + current_files->kind[i] = SKIPFILE; + continue; + } +#else /* APPLESHARE */ + if(!strcmp(current_files->files[i], f_name)) { + current_files->kind[i] = SKIPFILE; + continue; + } +#endif /* APPLESHARE */ + j = 1; + } else if(current_files->kind[i] == SKIPFILE) { + continue; + } else if(!initial) { /* DIRECTORY */ + /* Check whether the directory is special */ + if(!strcmp(current_files->files[i], ".") || + !strcmp(current_files->files[i], "..")) { + current_files->kind[i] = SKIPFILE; + } +#ifdef APPLESHARE +#ifdef AUFS + if(current_files->shared_dir && + (!strcmp(current_files->files[i], infodir) || + !strcmp(current_files->files[i], rsrcdir))) { + current_files->kind[i] = SKIPFILE; + } +#endif /* AUFS */ +#ifdef APPLEDOUBLE + if(current_files->shared_dir && + !strcmp(current_files->files[i], infodir)) { + current_files->kind[i] = SKIPFILE; + } +#endif /* APPLEDOUBLE */ +#endif /* APPLESHARE */ + continue; + } else { /* Take all directories from command line! */ + continue; + } +#ifdef APPLESHARE + /* Check whether file is in shared format */ + if(j & current_files->shared_dir) { + j = 0; + filename[0] = 0; + (void)strcat(filename, infodir); + (void)strcat(filename, "/"); + (void)strcat(filename, current_files->files[i]); + /* There ought to be an associated file in the info direcory */ + if(stat(filename, &stbuf) >= 0) { + current_files->kind[i] = SHAREFILE; + continue; + } + } +#endif /* APPLESHARE */ + /* If file not found check for the same with .info extension */ + if(!j) { + filename[0] = 0; + (void)strcat(filename, current_files->files[i]); + (void)strcat(filename, ".info"); + /* Found a .info file, else no such file found */ + if(stat(filename, &stbuf) >= 0) { + current_files->kind[i] = INFOEXT; + } + continue; + } + /* Now we found the file. Check first whether the name ends with + .info */ + j = strlen(current_files->files[i]) - 5; + if(!strncmp(current_files->files[i] + j, ".info", 5)) { + /* This is a .info file. Set as INFOFILE */ + current_files->kind[i] = INFOFILE; + /* Now remove from list of files the same with .data or .rsrc + extension */ + filename[0] = 0; + (void)strcat(filename, current_files->files[i]); + filename[j] = 0; + (void)strcpy(filename1, filename); + (void)strcat(filename, ".data"); + (void)strcat(filename1, ".rsrc"); + for(j = i + 1; j < n; j++) { + if(!strcmp(filename, current_files->files[j])) { + /* Associated .data file */ + current_files->kind[j] = SKIPFILE; + continue; + } + if(!strcmp(filename1, current_files->files[j])) { + /* Associated .rsrc file */ + current_files->kind[j] = SKIPFILE; + } + } + continue; + } + if(!strncmp(current_files->files[i] + j, ".data", 5) || + !strncmp(current_files->files[i] + j, ".rsrc", 5)) { + /* .data or .rsrc file found. Check whether there is an + associated .info file in the filelist */ + filename[0] = 0; + (void)strcat(filename, current_files->files[i]); + filename[j] = 0; + (void)strcat(filename, ".info"); + for(j = i + 1; j < n; j++) { + if(!strcmp(filename, current_files->files[j])) { + /* Found an associated .info file! */ + current_files->kind[i] = SKIPFILE; + break; + } + } + if(j < n) { + continue; + } + } + /* Finally nothing special */ + current_files->kind[i] = MACBINARY; + } +} + +int nextfile() +{ + int i; + + if(read_stdin) { + return get_stdin_file(); + } + i = current_files->current; +again: + if(i == current_files->nfiles) { + if(current_files->previous == NULL) { + return ISATEND; + } else { + exit_dir(); + current_files->current++; + return ENDDIR; + } + } + filename[0] = 0; + (void)strcat(filename, current_files->files[i]); + filekind = current_files->kind[i]; + switch(filekind) { + case DIRECTORY: + if(no_recurse) { + (void)fprintf(stderr, "Directory %s skipped.\n", filename); + i++; + current_files->current = i; + goto again; + } + enter_dir(); + return ISDIR; + case SKIPFILE: + i++; + current_files->current = i; + goto again; + case NOTFOUND: + (void)fprintf(stderr, "File %s not found.\n", filename); + exit(1); + default: + read_file(); + current_files->current = i + 1; + return ISFILE; + } +} + +static void read_file() +{ + FILE *fd; + int c, j, lname, skip; + struct stat stbuf; +#ifdef APPLESHARE + char filename1[255]; +#endif /* APPLESHARE */ + + switch(filekind) { + case ISFILE: + if(stat(filename, &stbuf) < 0) { + (void)fprintf(stderr, "Cannot stat file %s\n", filename); + exit(1); + } + for(j = 0; j < INFOBYTES; j++) { + file_info[j] = 0; + } + (void)strcpy(file_info + I_NAMEOFF + 1, filename); + file_info[I_NAMEOFF] = strlen(filename); + put4(file_info + I_CTIMOFF, (unsigned long)stbuf.st_ctime + TIMEDIFF); + put4(file_info + I_MTIMOFF, (unsigned long)stbuf.st_mtime + TIMEDIFF); + if(data_only == RSRC_FORMAT) { + rsrc_size = stbuf.st_size; + data_size = 0; + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if(f_type[0] == 0) { + (void)strncpy(file_info + I_TYPEOFF, "RSRC", 4); + } else { + (void)strncpy(file_info + I_TYPEOFF, f_type, 4); + } + if(f_auth[0] == 0) { + (void)strncpy(file_info + I_AUTHOFF, "RSED", 4); + } else { + (void)strncpy(file_info + I_AUTHOFF, f_auth, 4); + } + put4(file_info + I_RLENOFF, (unsigned long)rsrc_size); + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(rsrc_fork, 1, rsrc_size, fd) != rsrc_size) { + (void)fprintf(stderr, "Short file %s\n", filename); + exit(1); + } + (void)fclose(fd); + } else { + data_size = stbuf.st_size; + rsrc_size = 0; + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if(f_type[0] == 0) { + (void)strncpy(file_info + I_TYPEOFF, "TEXT", 4); + } else { + (void)strncpy(file_info + I_TYPEOFF, f_type, 4); + } + if(f_auth[0] == 0) { + (void)strncpy(file_info + I_AUTHOFF, "MACA", 4); + } else { + (void)strncpy(file_info + I_AUTHOFF, f_auth, 4); + } + put4(file_info + I_DLENOFF, (unsigned long)data_size); + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(data_fork, 1, data_size, fd) != data_size) { + (void)fprintf(stderr, "Short file %s\n", filename); + exit(1); + } + (void)fclose(fd); + if(data_only == UNIX_FORMAT) { + for(j = 0; j < data_size; j++) { + c = data_fork[j]; + if(c == '\012' || c == '\015') { + data_fork[j] = '\027' -c; + } + } + } + } + break; + case INFOEXT: + (void)strcat(filename, ".info"); + case INFOFILE: + lname = strlen(filename) - 5; + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(file_info, 1, INFOBYTES, fd) != INFOBYTES) { + (void)fprintf(stderr, "Cannot read info header %s\n", filename); + } + (void)fclose(fd); + data_size = get4(file_info + I_DLENOFF); + rsrc_size = get4(file_info + I_RLENOFF); + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if(data_size != 0) { + filename[lname] = 0; + (void)strcat(filename, ".data"); + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open data fork %s\n", filename); + exit(1); + } + if(fread(data_fork, 1, data_size, fd) != data_size) { + (void)fprintf(stderr, "Premature EOF on %s\n", filename); + } + (void)fclose(fd); + } + if(rsrc_size != 0) { + filename[lname] = 0; + (void)strcat(filename, ".rsrc"); + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open rsrc fork %s\n", filename); + exit(1); + } + if(fread(rsrc_fork, 1, rsrc_size, fd) != rsrc_size) { + (void)fprintf(stderr, "Premature EOF on %s\n", filename); + } + (void)fclose(fd); + } + break; + case MACBINARY: + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(file_info, 1, INFOBYTES, fd) != INFOBYTES) { + (void)fprintf(stderr, "Short file %s\n", filename); + exit(1); + } + if(file_info[0] != 0) { + (void)fprintf(stderr, "File is not MacBinary: %s\n", filename); + exit(1); + } + data_size = get4(file_info + I_DLENOFF); + rsrc_size = get4(file_info + I_RLENOFF); + if(file_info[I_LOCKOFF] & 1) { + file_info[I_FLAGOFF + 1] = PROTCT_MASK; + file_info[I_LOCKOFF] &= ~1; + } + if(data_size != 0) { + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if(fread(data_fork, 1, data_size, fd) != data_size) { + (void)fprintf(stderr, "Short file %s\n", filename); + exit(1); + } + skip = (((data_size + 127) >> 7) << 7) - data_size; + for(j = 0; j < skip; j++) { + (void)fgetc(fd); + } + } + if(rsrc_size != 0) { + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if(fread(rsrc_fork, 1, rsrc_size, fd) != rsrc_size) { + (void)fprintf(stderr, "Short file %s\n", filename); + exit(1); + } + } + break; +#ifdef APPLESHARE + case SHAREFILE: +#ifdef AUFS + (void)strcpy(filename1, infodir); + (void)strcat(filename1, "/"); + (void)strcat(filename1, filename); + if((fd = fopen(filename1, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename1); + } + read_aufs_info(fd); + (void)fclose(fd); + (void)strcpy(filename1, rsrcdir); + (void)strcat(filename1, "/"); + (void)strcat(filename1, filename); + if(stat(filename1, &stbuf) >= 0) { + rsrc_size = stbuf.st_size; + put4(file_info + I_RLENOFF, (unsigned long)rsrc_size); + if(rsrc_size > 0) { + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if((fd = fopen(filename1, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename1); + exit(1); + } + if(fread(rsrc_fork, 1, rsrc_size, fd) != rsrc_size) { + (void)fprintf(stderr, "Short file %s\n", filename1); + exit(1); + } + (void)fclose(fd); + } + } + if(stat(filename, &stbuf) >= 0) { + data_size = stbuf.st_size; + put4(file_info + I_DLENOFF, (unsigned long)data_size); + if(data_size > 0) { + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(data_fork, 1, data_size, fd) != data_size) { + (void)fprintf(stderr, "Short file %s\n", filename1); + exit(1); + } + (void)fclose(fd); + } + } +#endif /* AUFS */ +#ifdef APPLEDOUBLE + (void)strcpy(filename1, infodir); + (void)strcat(filename1, "/"); + (void)strcat(filename1, filename); + if((fd = fopen(filename1, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename1); + } + read_appledouble_info(fd); + rsrc_size = get4(file_info + I_RLENOFF); + if(rsrc_size > 0) { + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if(fread(rsrc_fork, 1, rsrc_size, fd) != rsrc_size) { + (void)fprintf(stderr, "Short file %s\n", filename1); + exit(1); + } + } + (void)fclose(fd); + if(stat(filename, &stbuf) >= 0) { + data_size = stbuf.st_size; + put4(file_info + I_DLENOFF, (unsigned long)data_size); + if(data_size > 0) { + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if((fd = fopen(filename, "r")) == NULL) { + (void)fprintf(stderr, "Cannot open file %s\n", filename); + exit(1); + } + if(fread(data_fork, 1, data_size, fd) != data_size) { + (void)fprintf(stderr, "Short file %s\n", filename1); + exit(1); + } + (void)fclose(fd); + } + } +#endif /* APPLEDOUBLE */ + break; +#endif /* APPLESHARE */ + } +} + +static void enter_dir() +{ + DIR *directory; + struct dirstruct *curentry; + FILE *fd; + int n, j, namlen; + int listsize, cursize; + char *filetable; + filelist *new_files; +#ifdef APPLESHARE + char filename1[255]; +#endif /* APPLESHARE */ + + for(j = 0; j < INFOBYTES; j++) { + file_info[j] = 0; + } + (void)strcpy(file_info + I_NAMEOFF + 1, filename); + file_info[I_NAMEOFF] = strlen(filename); + directory = opendir(filename); + if(directory == NULL) { + (void)fprintf(stderr, "Cannot read directory %s\n", filename); + exit(1); + } + listsize = 1024; + filetable = malloc((unsigned)listsize); + cursize = 0; + n = 0; + while((curentry = readdir(directory)) != NULL) { + namlen = strlen(curentry->d_name); + if(namlen + 1 > listsize - cursize) { + listsize += 1024; + filetable = realloc(filetable, (unsigned)listsize); + } + (void)strcpy(filetable + cursize, curentry->d_name); + cursize += (namlen + 1); + n++; + } + filetable = realloc(filetable, (unsigned)cursize); + (void)closedir(directory); + new_files = (filelist *)malloc(sizeof(filelist)); + new_files->nfiles = n; + new_files->files = (char **)malloc((unsigned)n * sizeof(char **)); + new_files->kind = (int *)malloc((unsigned)n * sizeof(int)); + new_files->previous = current_files; + new_files->current = 0; + cursize = 0; + for(j = 0; j < n; j++) { + new_files->files[j] = filetable + cursize; + cursize += (strlen(filetable + cursize) + 1); + } + (void)chdir(filename); +#ifdef APPLESHARE + if((fd = fopen(f_name, "r")) != NULL) { + if(fread(file_info, 1, INFOBYTES, fd) != INFOBYTES) { + (void)fprintf(stderr, "File error on %s\n", f_name); + exit(1); + } + file_info[I_NAMEOFF] |= 0x80; + (void)fclose(fd); + } else { +#ifdef AUFS + (void)strcpy(filename1, "../"); + (void)strcat(filename1, infodir); + (void)strcat(filename1, "/"); + (void)strcat(filename1, filename); + if((fd = fopen(filename1, "r")) != NULL) { + read_aufs_info(fd); + (void)fclose(fd); + } +#endif /* AUFS */ +#ifdef APPLEDOUBLE + (void)strcpy(filename1, infodir); + (void)strcat(filename1, "/.Parent"); + if((fd = fopen(filename1, "r")) != NULL) { + read_appledouble_info(fd); + (void)fclose(fd); + } +#endif /* APPLEDOUBLE */ + file_info[I_NAMEOFF] |= 0x80; + } +#else /* APPLESHARE */ + if((fd = fopen(f_name, "r")) != NULL) { + if(fread(file_info, 1, INFOBYTES, fd) != INFOBYTES) { + (void)fprintf(stderr, "File error on %s\n", f_name); + exit(1); + } + file_info[I_NAMEOFF] |= 0x80; + (void)fclose(fd); + } +#endif /* APPLESHARE */ + current_files = new_files; + check_files(0); +} + +static void exit_dir() +{ + filelist *old_files; + int i; + + for(i = 0; i < INFOBYTES; i++) { + file_info[i] = 0; + } + file_info[I_NAMEOFF] = 0x80; + old_files = current_files; + /* Do some garbage collection here! */ + current_files = current_files->previous; + (void)free(old_files->files[0]); + (void)free((char *)old_files->files); + (void)free((char *)old_files->kind); + (void)free((char *)old_files); + (void)chdir(".."); +} + +#ifdef APPLESHARE +#ifdef AUFS +static void read_aufs_info(fd) +FILE *fd; +{ + FileInfo theinfo; + int i, n; + struct stat stbuf; + + for(i = 0; i < INFOBYTES; i++) { + file_info[i] = 0; + } + bzero((char *) &theinfo, sizeof(theinfo)); + if(fread((char *)&theinfo, 1, sizeof(theinfo), fd) != sizeof(theinfo)) { + (void)fprintf(stderr, "Short AUFS info header for %s\n", filename); + exit(1); + } + if(theinfo.fi_magic1 & BYTEMASK != FI_MAGIC1 || + theinfo.fi_version & BYTEMASK != FI_VERSION || + theinfo.fi_magic & BYTEMASK != FI_MAGIC) { + (void)fprintf(stderr, "Magic number mismatch on %s\n", filename); + exit(1); + } + bcopy(theinfo.fi_fndr, file_info + I_TYPEOFF, 4); + bcopy(theinfo.fi_fndr + 4, file_info + I_AUTHOFF, 4); + bcopy(theinfo.fi_fndr + 8, file_info + I_FLAGOFF, 2); + if(theinfo.fi_bitmap & FI_BM_MACINTOSHFILENAME) { + n = strlen(theinfo.fi_macfilename); + (void)strncpy(file_info + I_NAMEOFF + 1, (char *)theinfo.fi_macfilename, + n); + } else if(theinfo.fi_bitmap & FI_BM_SHORTFILENAME) { + n = strlen(theinfo.fi_shortfilename); + (void)strncpy(file_info + I_NAMEOFF + 1, + (char *)theinfo.fi_shortfilename, n); + } else { + n = strlen(filename); + (void)strncpy(file_info + I_NAMEOFF + 1, filename, n); + } + file_info[I_NAMEOFF] = n; +#ifdef AUFSPLUS + if(theinfo.fi_datemagic == FI_MAGIC && + (theinfo.fi_datevalid & (FI_CDATE | FI_MDATE)) == + (FI_CDATE | FI_MDATE)) { + put4(file_info + I_CTIMOFF, get4(theinfo.fi_ctime) + TIMEDIFF); + put4(file_info + I_MTIMOFF, get4(theinfo.fi_mtime) + TIMEDIFF); + } else { + if(fstat(fileno(fd), &stbuf) >= 0) { + put4(file_info + I_CTIMOFF, + (unsigned long)stbuf.st_ctime + TIMEDIFF); + put4(file_info + I_MTIMOFF, + (unsigned long)stbuf.st_mtime + TIMEDIFF); + } + } +#else /* AUFSPLUS */ + if(fstat(fileno(fd), &stbuf) >= 0) { + put4(file_info + I_CTIMOFF, (unsigned long)stbuf.st_ctime + TIMEDIFF); + put4(file_info + I_MTIMOFF, (unsigned long)stbuf.st_mtime + TIMEDIFF); + } +#endif /* AUFSPLUS */ +} +#endif /* AUFS */ + +#ifdef APPLEDOUBLE +/* This version assumes that the AppleDouble info header is always the same + size and format. I have not yet seen something that will lead me to + believe different. +*/ +static void read_appledouble_info(fd) +FILE *fd; +{ + FileInfo theinfo; + int i, n; + + for(i = 0; i < INFOBYTES; i++) { + file_info[i] = 0; + } + bzero((char *) &theinfo, sizeof(theinfo)); + if(fread((char *)&theinfo, 1, sizeof(theinfo), fd) != sizeof(theinfo)) { + (void)fprintf(stderr, "Short AppleDouble info header for %s\n", + filename); + exit(1); + } + if(get4(theinfo.fi_magic) != FI_MAGIC || + get2(theinfo.fi_version) != FI_VERSION) { + (void)fprintf(stderr, "Magic number mismatch on %s\n", filename); + exit(1); + } + bcopy(theinfo.fi_type, file_info + I_TYPEOFF, 4); + bcopy(theinfo.fi_auth, file_info + I_AUTHOFF, 4); + bcopy(theinfo.fi_finfo, file_info + I_FLAGOFF, 2); + n = get4(theinfo.fi_namlen); + (void)strncpy(file_info + I_NAMEOFF + 1, theinfo.fi_name, n); + file_info[I_NAMEOFF] = n; + put4(file_info + I_CTIMOFF, get4(theinfo.fi_ctime) + TIMEDIFF); + put4(file_info + I_MTIMOFF, get4(theinfo.fi_mtime) + TIMEDIFF); + rsrc_size = get4(theinfo.fi_rsrc); + put4(file_info + I_RLENOFF, (unsigned long)rsrc_size); +} +#endif /* APPLEDOUBLE */ +#endif /* APPLESHARE */ + +static int get_stdin_file() +{ + int i, skip; + + i = fgetc(stdin); + if(i == EOF) { + return ISATEND; + } + (void)ungetc(i, stdin); + if(fread(file_info, 1, INFOBYTES, stdin) != INFOBYTES) { + (void)fprintf(stderr, "Short input\n"); + exit(1); + } + if(file_info[0] != 0) { + (void)fprintf(stderr, "File is not MacBinary: %s\n", filename); + exit(1); + } + data_size = get4(file_info + I_DLENOFF); + rsrc_size = get4(file_info + I_RLENOFF); + if(file_info[I_LOCKOFF] & 1) { + file_info[I_FLAGOFF + 1] = PROTCT_MASK; + file_info[I_LOCKOFF] &= ~1; + } + if(data_size != 0) { + if(data_size > max_data_size) { + if(data_fork == NULL) { + data_fork = malloc((unsigned)data_size); + } else { + data_fork = realloc(data_fork, (unsigned)data_size); + } + max_data_size = data_size; + } + if(fread(data_fork, 1, data_size, stdin) != data_size) { + (void)fprintf(stderr, "Short input\n"); + exit(1); + } + skip = (((data_size + 127) >> 7) << 7) - data_size; + for(i = 0; i < skip; i++) { + (void)fgetc(stdin); + } + } + if(rsrc_size != 0) { + if(rsrc_size > max_rsrc_size) { + if(rsrc_fork == NULL) { + rsrc_fork = malloc((unsigned)rsrc_size); + } else { + rsrc_fork = realloc(rsrc_fork, (unsigned)rsrc_size); + } + max_rsrc_size = rsrc_size; + } + if(fread(rsrc_fork, 1, rsrc_size, stdin) != rsrc_size) { + (void)fprintf(stderr, "Short input\n"); + exit(1); + } + skip = (((rsrc_size + 127) >> 7) << 7) - rsrc_size; + for(i = 0; i < skip; i++) { + (void)fgetc(stdin); + } + } + if(file_info[I_NAMEOFF] & 0x80) { + if((file_info[I_NAMEOFF] & 0xff) == 0x80) { + return ENDDIR; + } + return ISDIR; + } + return ISFILE; +} + +int rdfileopt(c) +char c; +{ +extern char *optarg; +char name[32]; + + switch(c) { + case 'd': + data_only = DATA_FORMAT; + break; + case 'u': + case 'U': + data_only = UNIX_FORMAT; + break; + case 'r': + data_only = RSRC_FORMAT; + break; + case 'c': + backtrans(name, optarg); + (void)strncpy(f_auth, name, 4); + break; + case 't': + backtrans(name, optarg); + (void)strncpy(f_type, name, 4); + break; + default: + return 0; + } + return 1; +} + +void give_rdfileopt() +{ + (void)fprintf(stderr, "File input options:\n"); + (void)fprintf(stderr, "-r:\tread as resource files\n"); + (void)fprintf(stderr, "-d:\tread as data files\n"); + (void)fprintf(stderr, + "-u:\tread as data files with Unix -> Mac text file translation\n"); + (void)fprintf(stderr, "-U:\ta synonym for -u\n"); + (void)fprintf(stderr, + "-c cr:\tcreator if one of the above options is used\n"); + (void)fprintf(stderr, + "-t ty:\tfiletype if one of the above options is used\n"); +} + +void set_norecurse() +{ + no_recurse = 1; +} + +char *get_rdfileopt() +{ + static char options[] = "rduUc:t:"; + + return options; +} + +char *get_minb() +{ +#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 */ +} + diff --git a/fileio/rdfile.h b/fileio/rdfile.h new file mode 100755 index 0000000..05e65a4 --- /dev/null +++ b/fileio/rdfile.h @@ -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(); + diff --git a/fileio/rdfile.o b/fileio/rdfile.o new file mode 100644 index 0000000000000000000000000000000000000000..8b095672fe4edf712e980048f0c87b21d288c167 GIT binary patch literal 28608 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 +#endif /* TYPES_H */ +#include +#include +#include +#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 */ +} + diff --git a/fileio/wrfile.h b/fileio/wrfile.h new file mode 100755 index 0000000..d069d14 --- /dev/null +++ b/fileio/wrfile.h @@ -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(); + diff --git a/fileio/wrfile.o b/fileio/wrfile.o new file mode 100644 index 0000000000000000000000000000000000000000..6d6b7e0ea61c224fe4464152a84baef1ce36dfae GIT binary patch literal 20488 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 literal 0 HcmV?d00001 diff --git a/fileio/wrfileopt.h b/fileio/wrfileopt.h new file mode 100755 index 0000000..da3083a --- /dev/null +++ b/fileio/wrfileopt.h @@ -0,0 +1,6 @@ +extern int wrfileopt(); +extern void give_wrfileopt(); +extern void set_wrfileopt(); +extern void set_s_wrfileopt(); +extern char *get_wrfileopt(); + diff --git a/hexbin/buffer.c b/hexbin/buffer.c new file mode 100755 index 0000000..501b4e8 --- /dev/null +++ b/hexbin/buffer.c @@ -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(); +} + diff --git a/hexbin/buffer.h b/hexbin/buffer.h new file mode 100755 index 0000000..1bd2dfa --- /dev/null +++ b/hexbin/buffer.h @@ -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(); + diff --git a/hexbin/crc.c b/hexbin/crc.c new file mode 100755 index 0000000..e5e59c0 --- /dev/null +++ b/hexbin/crc.c @@ -0,0 +1,44 @@ +/* crc.c; do crc calculation. */ + +#include +#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); + } +} + diff --git a/hexbin/crc.h b/hexbin/crc.h new file mode 100755 index 0000000..67e49fb --- /dev/null +++ b/hexbin/crc.h @@ -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(); + diff --git a/hexbin/dl.c b/hexbin/dl.c new file mode 100755 index 0000000..700c1cb --- /dev/null +++ b/hexbin/dl.c @@ -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 */ + diff --git a/hexbin/globals.c b/hexbin/globals.c new file mode 100755 index 0000000..91b3961 --- /dev/null +++ b/hexbin/globals.c @@ -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 */ + diff --git a/hexbin/globals.h b/hexbin/globals.h new file mode 100755 index 0000000..d22e9d5 --- /dev/null +++ b/hexbin/globals.h @@ -0,0 +1,39 @@ +#include +#include +#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(); + diff --git a/hexbin/hecx.c b/hexbin/hecx.c new file mode 100755 index 0000000..5d19d8e --- /dev/null +++ b/hexbin/hecx.c @@ -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 */ + diff --git a/hexbin/hexbin.c b/hexbin/hexbin.c new file mode 100755 index 0000000..a730858 --- /dev/null +++ b/hexbin/hexbin.c @@ -0,0 +1,362 @@ +#ifdef TYPES_H +#include +#endif /* TYPES_H */ +#include +#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"); +} + diff --git a/hexbin/hexbin.h b/hexbin/hexbin.h new file mode 100755 index 0000000..3df0af0 --- /dev/null +++ b/hexbin/hexbin.h @@ -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) + diff --git a/hexbin/hqx.c b/hexbin/hqx.c new file mode 100755 index 0000000..e998626 --- /dev/null +++ b/hexbin/hqx.c @@ -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 */ + diff --git a/hexbin/hqx.diff b/hexbin/hqx.diff new file mode 100755 index 0000000..0f15aec --- /dev/null +++ b/hexbin/hqx.diff @@ -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)) { diff --git a/hexbin/makefile b/hexbin/makefile new file mode 100755 index 0000000..898df05 --- /dev/null +++ b/hexbin/makefile @@ -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 + diff --git a/hexbin/mu.c b/hexbin/mu.c new file mode 100755 index 0000000..8b43c48 --- /dev/null +++ b/hexbin/mu.c @@ -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 */ + diff --git a/hexbin/printhdr.c b/hexbin/printhdr.c new file mode 100755 index 0000000..aa3f22f --- /dev/null +++ b/hexbin/printhdr.c @@ -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); + } +} + diff --git a/hexbin/printhdr.h b/hexbin/printhdr.h new file mode 100755 index 0000000..2cda600 --- /dev/null +++ b/hexbin/printhdr.h @@ -0,0 +1,4 @@ +extern void print_header0(); +extern void print_header1(); +extern void print_header2(); + diff --git a/hexbin/readline.c b/hexbin/readline.c new file mode 100755 index 0000000..9ebe6f1 --- /dev/null +++ b/hexbin/readline.c @@ -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; +} + diff --git a/hexbin/readline.h b/hexbin/readline.h new file mode 100755 index 0000000..af379fa --- /dev/null +++ b/hexbin/readline.h @@ -0,0 +1,2 @@ +extern char line[]; + diff --git a/macunpack/arc.h b/macunpack/arc.h new file mode 100755 index 0000000..59c7f8e --- /dev/null +++ b/macunpack/arc.h @@ -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 + diff --git a/macunpack/bin.c b/macunpack/bin.c new file mode 100755 index 0000000..86fb1f0 --- /dev/null +++ b/macunpack/bin.c @@ -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 */ + diff --git a/macunpack/bin.o b/macunpack/bin.o new file mode 100644 index 0000000000000000000000000000000000000000..bb7246a5f481ec22610ab561ccb2432b4347301f GIT binary patch literal 4128 zcmbuBTTC2P7=X{Rw58bYVreT{(Xmp6v`(OuYK%4P(uE;e#kvrPS|`KqY-}B z8Vdm$Hn?i~Qq!l#M58e##>8t3qS)9MeW*SdAL@fO+Sr&j#-!eY|37nn_Au=Dp#Sci z%Xj|Exy+n%P9&0@6`>F#39$!RsYaBsvs+5#cDLBhB5W&*^~HMoQp)s|mjEh-KMTLb z3SVcGg~~mRE|_hYhrDG;SvZ7NKVdRo*$`d4t}L{zlIXkJ8)h#=XX6lBDcXq-Dxpa! zx+cHA8a=%fJ@rY``RL-()E|vwRdY+x*)KuCbNT+N7iD29mOqprS;Rqb4{p#P<(tbY zyN<$cs-$;-3RBWXZt1!A`egQs#5W~=Y}n&vRuxTa2(Fsq{Cnmo)luc>2YlS|h7 z_qLslj8E&T-Hlv-_bTxUJKb!3e|B+we*}qhTo=EDd9Osi2P)fy`E=J1SQ9)oq9QNL z0sL?P?+)Op0RBh-e=LA&0X!GL%>eEM@aX{ld;mWcz|REmmjn1~0sPGX{&oO=FMu=H zd*n2elO4^Nv|@4qlNL<&W738?%rLW~Ozlec#A8Xdr?WGa=v8}T@nk|}$8=|qjhT?8 zSthRgOrJ0uHaZ3+Rka;0J*1{{LuytthS^>i9|~?g_znF9J2?t{U-;$M3fw({q3+j@ z14BW5-0R5ClL$djAHQLg2U$lm82XA2IGXf<9g`NdKb1ZxQ$p0>{0I^sfjU z&kf?gbB^P!7dRaN*#Fz$x$Z6R%4R$uK#<=K5Aj-oV}FR(3mp4TJSlK-9glGCU&jGK zUtC8+;JC-rxJ<#1IG1Rg`d`br|9!3(_-;Y}puq1Gcrt*e1l}O%OHf9^X0GDanQTvvINBiO zj^*V!Dp~rlCOi6s!{iKXQA{4RZ6;fJte|>}44b4_y^qQ1{KyFIellFBbQx|>_qZDs z=%F(`r)Di}ME64fpHu>4oO=I_pdAE`nm1y&$Cb6` M{U0Yqp8M_p0qVETb^rhX literal 0 HcmV?d00001 diff --git a/macunpack/bits_be.c b/macunpack/bits_be.c new file mode 100755 index 0000000..e4ce810 --- /dev/null +++ b/macunpack/bits_be.c @@ -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); +} + diff --git a/macunpack/bits_be.h b/macunpack/bits_be.h new file mode 100755 index 0000000..3f8e549 --- /dev/null +++ b/macunpack/bits_be.h @@ -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(); + diff --git a/macunpack/cpt.c b/macunpack/cpt.c new file mode 100755 index 0000000..5514302 --- /dev/null +++ b/macunpack/cpt.c @@ -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 < 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 */ + diff --git a/macunpack/cpt.h b/macunpack/cpt.h new file mode 100755 index 0000000..43700b8 --- /dev/null +++ b/macunpack/cpt.h @@ -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 + diff --git a/macunpack/cpt.o b/macunpack/cpt.o new file mode 100644 index 0000000000000000000000000000000000000000..4268419f96d1586df2901cc4057409a534bd1085 GIT binary patch literal 20616 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 n;85#hv0@?+ki(ZGkd7i%1`NEwf_GBKL_9{ literal 0 HcmV?d00001 diff --git a/macunpack/crc.c b/macunpack/crc.c new file mode 100755 index 0000000..0e0baf3 --- /dev/null +++ b/macunpack/crc.c @@ -0,0 +1,4 @@ +unsigned long crcinit; + +unsigned long (*updcrc)(); + diff --git a/macunpack/crc.h b/macunpack/crc.h new file mode 100755 index 0000000..b339d36 --- /dev/null +++ b/macunpack/crc.h @@ -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)(); + diff --git a/macunpack/dd.c b/macunpack/dd.c new file mode 100755 index 0000000..28f417d --- /dev/null +++ b/macunpack/dd.c @@ -0,0 +1,1042 @@ +#include "macunpack.h" +#ifdef DD +#include "globals.h" +#include "dd.h" +#include "crc.h" +#include "../fileio/machdr.h" +#include "../fileio/wrfile.h" +#include "../fileio/fileglob.h" +#include "../util/masks.h" +#include "../util/util.h" + +extern char *malloc(); +extern char *realloc(); +extern char *strcpy(); +extern char *strncpy(); +extern void cpt_wrfile1(); +extern void core_compress(); +extern void de_compress(); + +static void dd_name(); +static int dd_filehdr(); +static void dd_cfilehdr(); +static int dd_valid(); +static int dd_valid1(); +static char *dd_methname(); +static unsigned long dd_checksum(); +static void dd_chksum(); +static unsigned long dd_checkor(); +static void dd_do_delta(); +static void dd_delta(); +static void dd_delta3(); +static void dd_copy(); +static void dd_copyfile(); +static void dd_expand(); +static void dd_expandfile(); +static void dd_nocomp(); +static void dd_lzc(); +#ifdef UNTESTED +static void dd_rle(); +#ifdef NOTIMPLEMENTED +static void dd_huffman(); +#endif /* NOTIMPLEMENTED */ +static void dd_lzss(); +static int dd_getbits(); +#endif /* UNTESTED */ +static void dd_cpt_compat(); + +typedef struct methodinfo { + char *name; + int number; +}; + +static struct methodinfo methods[] = { + {"NoComp", nocomp}, + {"LZC", lzc}, + {"???", method2}, + {"RLE", rle}, + {"Huffman", huffman}, + {"???", method5}, + {"???", method6}, + {"LZSS", lzss}, + {"RLE/LZH", cpt_compat}, + {"???", method9}, +}; +static unsigned char *dd_archive; +static unsigned char *dd_data_ptr; +static int dd_archive_size; +static int dd_max_archive_size; +static unsigned char *dd_dirst; +static int dd_dirstptr; +static int dd_dirstmax; +static int dd_xor; +static long dd_bitbuf; +static int dd_bitcount; +static unsigned char *dd_bitptr; +static char dd_LZbuff[2048]; + +void dd_file(bin_hdr) +unsigned char *bin_hdr; +{ + unsigned long data_size; + int i; + struct fileCHdr cf; + char ftype[5], fauth[5]; + + updcrc = binhex_updcrc; + crcinit = binhex_crcinit; + dd_name(bin_hdr); + for(i = 0; i < INFOBYTES; i++) { + info[i] = bin_hdr[i]; + } + transname(info + I_NAMEOFF + 1, text, (int)info[I_NAMEOFF] & BYTEMASK); + data_size = get4(info + I_DLENOFF); + if(data_size > dd_max_archive_size) { + if(dd_max_archive_size == 0) { + dd_archive = (unsigned char *)malloc((unsigned)data_size); + } else { + dd_archive = (unsigned char *)realloc((char *)dd_archive, + (unsigned)data_size); + } + dd_max_archive_size = data_size; + if(dd_archive == NULL) { + (void)fprintf(stderr, "Insufficient memory.\n"); + exit(1); + } + } + dd_archive_size = data_size; + if(fread((char *)dd_archive, 1, (int)data_size, infp) != data_size) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("Premature EOF"); +#endif /* SCAN */ + exit(1); + } + dd_data_ptr = dd_archive; + dd_cfilehdr(&cf); + write_it = 1; + if(list) { + 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", + text, ftype, fauth, + (long)get4(info + I_DLENOFF), (long)get4(info + I_RLENOFF)); + if(info_only) { + write_it = 0; + } + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + } + if(!dd_valid((int)cf.datamethod, (int)cf.rsrcmethod)) { + (void)fprintf(stderr, "\tUnimplemented method found: %d %d\n", + cf.datamethod, cf.rsrcmethod); +#ifdef SCAN + do_error("macunpack: Unimplemented method found"); +#endif /* SCAN */ + return; + } + + if(write_it) { + define_name(text); + } + if(write_it || list) { + dd_expand(cf, dd_data_ptr); + } +} + +void dd_arch(bin_hdr) +unsigned char *bin_hdr; +{ + unsigned long data_size; + unsigned long crc, filecrc; + struct fileHdr f; + struct fileCHdr cf; + char locname[64]; + int i, nlength; + + updcrc = binhex_updcrc; + crcinit = binhex_crcinit; + data_size = get4((char *)bin_hdr + I_DLENOFF); + if(data_size > dd_max_archive_size) { + if(dd_max_archive_size == 0) { + dd_archive = (unsigned char *)malloc((unsigned)data_size); + } else { + dd_archive = (unsigned char *)realloc((char *)dd_archive, + (unsigned)data_size); + } + dd_max_archive_size = data_size; + } + dd_archive_size = data_size; + if(fread((char *)dd_archive, 1, (int)data_size, infp) != data_size) { + (void)fprintf(stderr, "Insufficient memory.\n"); + exit(1); + } + dd_name(bin_hdr); + nlength = bin_hdr[I_NAMEOFF]; + for(i = 0; i < INFOBYTES; i++) { + info[i] = 0; + } + info[I_NAMEOFF] = nlength; + for(i = 1; i <= nlength; i++) { + info[I_NAMEOFF + i] = bin_hdr[I_NAMEOFF + i]; + } + transname(info + I_NAMEOFF + 1, text, nlength); + (void)strcpy(locname, text); + if(list) { + do_indent(indent); + (void)fprintf(stderr, "folder=\"%s\"", text); + if(query) { + if(!do_query()) { + return; + } + } else { + (void)fputc('\n', stderr); + } + indent++; + } + if(!info_only) { + do_mkdir(text, info); + } + + if(strncmp((char *)dd_archive, "DDAR", 4)) { + (void)fprintf(stderr, "Magic archive header error\n"); +#ifdef SCAN + do_error("macunpack: Magic archive header error"); +#endif /* SCAN */ + exit(1); + } + crc = (*updcrc)(crcinit, dd_archive, ARCHHDRSIZE - 2); + filecrc = get2((char *)dd_archive + ARCHHDRCRC); + if(crc != filecrc) { + (void)fprintf(stderr, "Header CRC mismatch: got 0x%02x, need 0x%02x\n", + (int)crc, (int)filecrc); +#ifdef SCAN + do_error("macunpack: Header CRC mismatch"); +#endif /* SCAN */ + exit(1); + } + dd_data_ptr = dd_archive + ARCHHDRSIZE; + while(dd_data_ptr < dd_archive + data_size) { + switch(dd_filehdr(&f, &cf, dir_skip)) { + case DD_FILE: + dd_chksum(f, dd_data_ptr); + dd_expand(cf, dd_data_ptr); + case DD_IVAL: + dd_data_ptr += f.dataLength - CFILEHDRSIZE; + break; + case DD_COPY: + dd_copy(f, dd_data_ptr); + dd_data_ptr += f.dataLength + f.rsrcLength; + break; + case DD_SDIR: + if(write_it || info_only) { + if(write_it) { + do_mkdir(text, info); + } + if(dd_dirstptr == dd_dirstmax) { + if(dd_dirstmax == 0) { + dd_dirst = (unsigned char *)malloc(64); + } else { + dd_dirst = (unsigned char *)realloc((char *)dd_dirst, + (unsigned)dd_dirstmax + 64); + } + dd_dirstmax += 64; + } + for(i = 0; i < 64; i++) { + dd_dirst[dd_dirstptr + i] = text[i]; + } + dd_dirst += 64; + indent++; + } else { + dir_skip++; + } + break; + case DD_EDIR: + if(dir_skip) { + dir_skip--; + } else { + dd_dirst -= 64; + indent--; + if(list) { + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", + dd_dirst + dd_dirstptr); + } + if(!info_only) { + enddir(); + } + } + } + } + if(!info_only) { + enddir(); + } + if(list) { + indent--; + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", locname); + } +} + +static void dd_name(bin_hdr) +unsigned char *bin_hdr; +{ + int nlength; + unsigned char *extptr; + + nlength = bin_hdr[I_NAMEOFF] & BYTEMASK; + extptr = bin_hdr + I_NAMEOFF + nlength - 3; + if(!strncmp((char *)extptr, ".sea", 4) || + !strncmp((char *)extptr, ".Sea", 4) || + !strncmp((char *)extptr, ".SEA", 4)) { + nlength -= 4; + extptr[0] = 0; + extptr[1] = 0; + extptr[2] = 0; + extptr[3] = 0; + bin_hdr[I_NAMEOFF] = nlength; + return; + } + extptr++; + if(!strncmp((char *)extptr, ".dd", 3)) { + nlength -=3; + extptr[0] = 0; + extptr[1] = 0; + extptr[2] = 0; + bin_hdr[I_NAMEOFF] = nlength; + return; + } + if(nlength < 31) { + nlength++; + } + bin_hdr[I_NAMEOFF + nlength] = 0xA5; + bin_hdr[I_NAMEOFF] = nlength; +} + +static int dd_filehdr(f, cf, skip) +struct fileHdr *f; +struct fileCHdr *cf; +int skip; +{ + register int i; + unsigned long crc; + int n, to_uncompress; + unsigned char *hdr; + char ftype[5], fauth[5]; + unsigned long datalength, rsrclength; + + to_uncompress = DD_COPY; + hdr = dd_data_ptr; + dd_data_ptr += FILEHDRSIZE; + for(i = 0; i < INFOBYTES; i++) { + info[i] = '\0'; + } + crc = INIT_CRC; + crc = (*updcrc)(crc, hdr, FILEHDRSIZE - 2); + + f->hdrcrc = get2((char *)hdr + D_HDRCRC); + if(f->hdrcrc != crc) { + (void)fprintf(stderr, "Header CRC mismatch: got 0x%04x, need 0x%04x\n", + f->hdrcrc & WORDMASK, (int)crc); +#ifdef SCAN + do_error("macunpack: Header CRC mismatch"); +#endif /* SCAN */ + exit(1); + } + + n = hdr[D_FNAME] & BYTEMASK; + if(n > F_NAMELEN) { + n = F_NAMELEN; + } + info[I_NAMEOFF] = n; + copy(info + I_NAMEOFF + 1, (char *)hdr + D_FNAME + 1, n); + transname((char *)hdr + D_FNAME + 1, text, n); + + if(!hdr[D_ISDIR]) { + f->datacrc = get2((char *)hdr + D_DATACRC); + f->rsrccrc = get2((char *)hdr + D_RSRCCRC); + f->dataLength = get4((char *)hdr + D_DATALENGTH); + f->rsrcLength = get4((char *)hdr + D_RSRCLENGTH); + copy(info + I_DLENOFF, (char *)hdr + D_DATALENGTH, 4); + copy(info + I_RLENOFF, (char *)hdr + D_RSRCLENGTH, 4); + copy(info + I_CTIMOFF, (char *)hdr + D_CTIME, 4); + copy(info + I_MTIMOFF, (char *)hdr + D_MTIME, 4); + copy(info + I_TYPEOFF, (char *)hdr + D_FTYPE, 4); + copy(info + I_AUTHOFF, (char *)hdr + D_CREATOR, 4); + copy(info + I_FLAGOFF, (char *)hdr + D_FNDRFLAGS, 2); + } + + if(hdr[D_ISDIR]) { + to_uncompress = DD_SDIR; + } else if(hdr[D_ENDDIR]) { + to_uncompress = DD_EDIR; + } else if(!no_dd && ((hdr[D_FNDRFLAGS] & 0x80) == 0)) { + dd_cfilehdr(cf); + to_uncompress = DD_FILE; + datalength = cf->dataLength; + rsrclength = cf->rsrcLength; + } else { + datalength = f->dataLength; + rsrclength = f->rsrcLength; + } + hdr[D_FNDRFLAGS] &= 0x7f; + write_it = !skip; + if(list && !skip) { + if(to_uncompress != DD_EDIR) { + do_indent(indent); + } + if(to_uncompress == DD_SDIR) { + (void)fprintf(stderr, "folder=\"%s\"", text); + } else if(to_uncompress != DD_EDIR) { + 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", + text, ftype, fauth, (long)datalength, (long)rsrclength); + } + if(info_only) { + write_it = 0; + } + if(to_uncompress != DD_EDIR) { + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + } + if(to_uncompress == DD_FILE) { + if(!dd_valid((int)cf->datamethod, (int)cf->rsrcmethod)) { + (void)fprintf(stderr, "\tUnimplemented method found: %d %d\n", + cf->datamethod, cf->rsrcmethod); +#ifdef SCAN + do_error("macunpack: Unimplemented method found"); +#endif /* SCAN */ + return DD_IVAL; + } + } + } + + if(write_it) { + define_name(text); + } + return to_uncompress; +} + +static void dd_cfilehdr(f) +struct fileCHdr *f; +{ + unsigned long crc; + unsigned char *hdr; + + hdr = dd_data_ptr; + dd_data_ptr += CFILEHDRSIZE; + crc = INIT_CRC; + crc = (*updcrc)(crc, hdr, CFILEHDRSIZE - 2); + + f->hdrcrc = get2((char *)hdr + C_HDRCRC); + if(f->hdrcrc != crc) { + (void)fprintf(stderr, "Header CRC mismatch: got 0x%04x, need 0x%04x\n", + f->hdrcrc & WORDMASK, (int)crc); +#ifdef SCAN + do_error("macunpack: Header CRC mismatch"); +#endif /* SCAN */ + exit(1); + } + + f->dataLength = get4((char *)hdr + C_DATALENGTH); + f->dataCLength = get4((char *)hdr + C_DATACLENGTH); + f->rsrcLength = get4((char *)hdr + C_RSRCLENGTH); + f->rsrcCLength = get4((char *)hdr + C_RSRCCLENGTH); + f->datamethod = hdr[C_DATAMETHOD]; + f->rsrcmethod = hdr[C_RSRCMETHOD]; + f->datacrc = get2((char *)hdr + C_DATACRC); + f->rsrccrc = get2((char *)hdr + C_RSRCCRC); + f->datainfo = get2((char *)hdr + C_DATAINFO); + f->rsrcinfo = get2((char *)hdr + C_RSRCINFO); + f->datacrc2 = get2((char *)hdr + C_DATACRC2); + f->rsrccrc2 = get2((char *)hdr + C_RSRCCRC2); + f->info1 = hdr[C_INFO1]; + f->info2 = hdr[C_INFO2]; + copy(info + I_DLENOFF, (char *)hdr + C_DATALENGTH, 4); + copy(info + I_RLENOFF, (char *)hdr + C_RSRCLENGTH, 4); + copy(info + I_CTIMOFF, (char *)hdr + C_CTIME, 4); + copy(info + I_MTIMOFF, (char *)hdr + C_MTIME, 4); + copy(info + I_TYPEOFF, (char *)hdr + C_FTYPE, 4); + copy(info + I_AUTHOFF, (char *)hdr + C_CREATOR, 4); + copy(info + I_FLAGOFF, (char *)hdr + C_FNDRFLAGS, 2); + if(f->info1 >= 0x2a && (f->info2 & 0x80) == 0) { + dd_xor = 0x5a; + } else { + dd_xor = 0; + } +} + +static int dd_valid(dmethod, rmethod) +int dmethod, rmethod; +{ + return dd_valid1(dmethod) | dd_valid1(rmethod); +} + +static int dd_valid1(method) +int method; +{ + switch(method) { + case nocomp: + case lzc: +#ifdef UNTESTED + case rle: +#ifdef NOTIMPLEMENTED + case huffman: +#endif /* NOTIMPLEMENTED */ + case lzss: +#endif /* UNTESTED */ + case cpt_compat: + return 1; + } + return 0; +} + +static char *dd_methname(n) +int n; +{ +int i, nmeths; + nmeths = sizeof(methods) / sizeof(struct methodinfo); + for(i = 0; i < nmeths; i++) { + if(methods[i].number == n) { + return methods[i].name; + } + } + return NULL; +} + +static unsigned long dd_checksum(init, buffer, length) +unsigned long init; +char *buffer; +unsigned long length; +{ + int i; + unsigned long cks; + + cks = init; + for(i = 0; i < length; i++) { + cks += *buffer++ & BYTEMASK; + } + return cks & WORDMASK; +} + +static void dd_chksum(hdr, data) +struct fileHdr hdr; +unsigned char *data; +{ + unsigned long cks; + + if(write_it) { + cks = dd_checksum(INIT_CRC, (char *)data - CFILEHDRSIZE, + hdr.dataLength); + if(hdr.datacrc != cks) { + (void)fprintf(stderr, + "Checksum error on compressed file: need 0x%04x, got 0x%04x\n", + hdr.datacrc, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on compressed file"); +#endif /* SCAN */ + exit(1); + } + } +} + +static unsigned long dd_checkor(init, buffer, length) +unsigned long init; +char *buffer; +unsigned long length; +{ + int i; + unsigned long cks; + + cks = init; + for(i = 0; i < length; i++) { + cks ^= *buffer++ & BYTEMASK; + } + return cks & WORDMASK; +} + +static void dd_do_delta(out_ptr, nbytes, kind) +char *out_ptr; +unsigned long nbytes; +int kind; +{ + switch(kind) { + case 0: + break; + case 1: + dd_delta(out_ptr, nbytes); + break; + case 2: + dd_delta3(out_ptr, nbytes); + break; + default: + (void)fprintf(stderr, "Illegal kind value found: %d\n", kind); +#ifdef SCAN + do_error("Illegal kind value found"); +#endif /* SCAN */ + exit(1); + } +} + +static void dd_delta(out_ptr, nbytes) +char *out_ptr; +unsigned long nbytes; +{ + int i, sum = 0; + + for(i = 0; i < nbytes; i++) { + sum = (sum + *out_ptr) & BYTEMASK; + *out_ptr++ = sum; + } +} + +static void dd_delta3(out_ptr, nbytes) +char *out_ptr; +unsigned long nbytes; +{ + int i, sum1 = 0, sum2 = 0, sum3 = 0; + + for(i = 0; i < nbytes; i += 3) { + sum1 = (sum1 + *out_ptr) & BYTEMASK; + *out_ptr++ = sum1; + if(i < nbytes - 1) { + sum2 = (sum2 + *out_ptr) & BYTEMASK; + *out_ptr++ = sum2; + if(i < nbytes) { + sum3 = (sum3 + *out_ptr) & BYTEMASK; + *out_ptr++ = sum3; + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/* Archive only, no compression */ +/*---------------------------------------------------------------------------*/ +static void dd_copy(hdr, data) +struct fileHdr hdr; +unsigned char *data; +{ + unsigned long cks; + + if(write_it) { + start_info(info, hdr.rsrcLength, hdr.dataLength); + } + if(verbose) { + (void)fprintf(stderr, "\tNo compression"); + } + if(write_it) { + start_data(); + } + dd_copyfile(hdr.dataLength, data); + data += hdr.dataLength; + if(write_it) { + cks = dd_checksum(INIT_CRC, out_buffer, hdr.dataLength); + if(hdr.datacrc != cks) { + (void)fprintf(stderr, + "Checksum error on data fork: need 0x%04x, got 0x%04x\n", + hdr.datacrc, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on data fork"); +#endif /* SCAN */ + exit(1); + } + } + if(write_it) { + start_rsrc(); + } + dd_copyfile(hdr.rsrcLength, data); + data += hdr.rsrcLength; + if(write_it) { + cks = dd_checksum(INIT_CRC, out_buffer, hdr.rsrcLength); + if(hdr.rsrccrc != cks) { + (void)fprintf(stderr, + "Checksum error on resource fork: need 0x%04x, got 0x%04x\n", + hdr.rsrccrc, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on resource fork"); +#endif /* SCAN */ + exit(1); + } + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } +} + +static void dd_copyfile(obytes, data) +unsigned long obytes; +unsigned char *data; +{ + if(obytes == 0) { + return; + } + if(write_it) { + copy(out_ptr, (char *)data, (int)obytes); + } +} + +/*---------------------------------------------------------------------------*/ +/* Possible compression, and perhaps in an archive */ +/*---------------------------------------------------------------------------*/ +static void dd_expand(hdr, data) +struct fileCHdr hdr; +unsigned char *data; +{ + unsigned long cks; + char *out_buf; + + if(write_it) { + start_info(info, hdr.rsrcLength, hdr.dataLength); + } + if(verbose) { + (void)fprintf(stderr, "\tData: "); + } + if(write_it) { + start_data(); + } + out_buf = out_buffer; + dd_expandfile(hdr.dataLength, hdr.dataCLength, (int)hdr.datamethod, + (int)hdr.datainfo, data, (unsigned long)hdr.datacrc); + data += hdr.dataCLength; + if(write_it) { + if((hdr.info2 & 0x40) && (hdr.dataLength != 0)) { + cks = arc_updcrc(INIT_CRC, (unsigned char *)out_buf, + (int)hdr.dataLength); + if(cks != hdr.datacrc2) { + (void)fprintf(stderr, + "Checksum error on data fork: need 0x%04x, got 0x%04x\n", + (int)hdr.datacrc2, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on data fork"); +#endif /* SCAN */ + exit(1); + } + } + } + if(verbose) { + (void)fprintf(stderr, ", Rsrc: "); + } + if(write_it) { + start_rsrc(); + } + out_buf = out_buffer; + dd_expandfile(hdr.rsrcLength, hdr.rsrcCLength, (int)hdr.rsrcmethod, + (int)hdr.rsrcinfo, data, (unsigned long)hdr.rsrccrc); + data += hdr.rsrcCLength; + if(write_it) { + if((hdr.info2 & 0x40) && (hdr.rsrcLength != 0)) { + cks = arc_updcrc(INIT_CRC, (unsigned char *)out_buf, + (int)hdr.rsrcLength); + if(cks != hdr.rsrccrc2) { + (void)fprintf(stderr, + "Checksum error on resource fork: need 0x%04x, got 0x%04x\n", + (int)hdr.rsrccrc2, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on resource fork"); +#endif /* SCAN */ + exit(1); + } + } + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } +} + +static void dd_expandfile(obytes, ibytes, method, kind, data, chksum) +unsigned long obytes, ibytes, chksum; +int method, kind; +unsigned char *data; +{ + int sub_method, m1, m2; + char *optr = out_ptr; + unsigned long cksinit; + + if(obytes == 0) { + if(verbose) { + (void)fprintf(stderr, "empty"); + } + return; + } + switch(method & 0x7f) { + case nocomp: + if(verbose) { + (void)fprintf(stderr, "No compression"); + } + if(write_it) { + dd_nocomp(obytes, data); + } + break; + case lzc: + m1 = (*data++ & BYTEMASK) ^ dd_xor; + m2 = (*data++ & BYTEMASK) ^ dd_xor; + sub_method = (*data++ & BYTEMASK) ^ dd_xor; + cksinit = m1 + m2 + sub_method; + sub_method = sub_method & 0x1f; + if(verbose) { + (void)fprintf(stderr, "LZC(%d) compressed (%4.1f%%)", + sub_method, 100.0 * ibytes / obytes); + } + if(write_it) { + dd_lzc(ibytes - 3, obytes, data, sub_method, chksum, cksinit); + } + break; +#ifdef UNTESTED + case rle: + if(verbose) { + (void)fprintf(stderr, "RLE compressed (%4.1f%%)", + 100.0 * ibytes / obytes); + } + if(write_it) { + dd_rle(ibytes, data); + } + break; +#ifdef NOTIMPLEMENTED + case huffman: + if(verbose) { + (void)fprintf(stderr, "Huffman compressed (%4.1f%%)", + 100.0 * ibytes / obytes); + } + if(write_it) { + dd_huffman(ibytes, data); + } + break; +#endif /* NOTIMPLEMENTED */ + case lzss: + if(verbose) { + (void)fprintf(stderr, "LZSS compressed (%4.1f%%)", + 100.0 * ibytes / obytes); + } + if(write_it) { + dd_lzss(data, chksum); + } + break; +#endif /* UNTESTED */ + case cpt_compat: + sub_method = get2((char *)data); + data += 16; + if(sub_method != 0) { + sub_method = 0; + } else { + sub_method = 1; + } + if(verbose) { + if(!sub_method) { + (void)fprintf(stderr, "RLE compressed (%4.1f%%)", + 100.0 * ibytes / obytes); + } else { + (void)fprintf(stderr, "RLE/LZH compressed (%4.1f%%)", + 100.0 * ibytes / obytes); + } + } + if(write_it) { + dd_cpt_compat(ibytes, obytes, data, sub_method, chksum); + } + break; + default: + break; + } + if(write_it) { + dd_do_delta(optr, obytes, kind); + } +} + +/*---------------------------------------------------------------------------*/ +/* Method 0: no compression */ +/*---------------------------------------------------------------------------*/ +static void dd_nocomp(obytes, data) +unsigned char *data; +unsigned long obytes; +{ + copy(out_ptr, (char *)data, (int)obytes); +} + +/*---------------------------------------------------------------------------*/ +/* Method 1: LZC compressed */ +/*---------------------------------------------------------------------------*/ +static void dd_lzc(ibytes, obytes, data, mb, chksum, ckinit) +unsigned char *data; +unsigned long ibytes, obytes, chksum, ckinit; +int mb; +{ + int i; + char *out_buf; + unsigned long cks; + + out_buf = out_buffer; + core_compress((char *)data); + de_compress(ibytes, mb); + out_buffer = out_buf; + if(dd_xor != 0) { + for(i = 0; i < obytes; i++) { + *out_buf++ ^= dd_xor; + } + } + cks = dd_checksum(ckinit, out_buffer, obytes); + if(chksum != cks) { + (void)fprintf(stderr, + "Checksum error on fork: need 0x%04x, got 0x%04x\n", + (int)chksum, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on fork"); +#endif /* SCAN */ + exit(1); + } +} + +#ifdef UNTESTED +/*---------------------------------------------------------------------------*/ +/* Method 3: Run length encoding */ +/*---------------------------------------------------------------------------*/ +static void dd_rle(ibytes, data) +unsigned char *data; +unsigned long ibytes; +{ + int ch, lastch, n, i; + + while(ibytes != 0) { + ch = *data++; + ibytes--; + if(ch == ESC) { + n = *data++ - 1; + ibytes--; + if(n < 0) { + *out_ptr++ = ESC; + lastch = ESC; + } else { + for(i = 0; i < n; i++) { + *out_ptr++ = lastch; + } + } + } else { + *out_ptr++ = ch; + lastch = ch; + } + } +} + +#ifdef NOTIMPLEMENTED +/*---------------------------------------------------------------------------*/ +/* Method 4: Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void dd_huffman(ibytes, data) +unsigned char *data; +unsigned long ibytes; +{ +} +#endif /* NOTIMPLEMENTED */ + +/*---------------------------------------------------------------------------*/ +/* Method 7: Slightly improved LZSS */ +/*---------------------------------------------------------------------------*/ +static void dd_lzss(data, chksum) +unsigned char *data; +unsigned long chksum; +{ + int i, LZptr, LZbptr, LZlength; + char *optr = out_ptr; + unsigned char cks; + + data += get4((char *)data + 6); + LZptr = 0; + while(1) { + if(dd_getbits(1) == 0) { + *out_ptr++ = dd_LZbuff[LZptr++] = dd_getbits(8); + LZptr &= 0x7ff; + } else { + if(dd_getbits(1) == 0) { + LZbptr = dd_getbits(11); + } else { + LZbptr = dd_getbits(7); + } + if(LZbptr == 0) { + break; + } + LZbptr = (LZptr - LZbptr) & 0x7ff; + LZlength = dd_getbits(2); + if(LZlength == 3) { + LZlength += dd_getbits(2); + if(LZlength == 6) { + do { + i = dd_getbits(4); + LZlength += i; + } while(i == 15); + } + } + LZlength += 2; + for(i = 0; i < LZlength; i++) { + *out_ptr++ = dd_LZbuff[LZptr++] = dd_LZbuff[LZbptr++]; + LZptr &= 0x7ff; + LZbptr &= 0x7ff; + } + } + } + cks = dd_checkor(INIT_CRC, optr, (unsigned long)(out_ptr - optr)); + if(chksum != cks) { + (void)fprintf(stderr, + "Checksum error on fork: need 0x%04x, got 0x%04x\n", + (int)chksum, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on fork"); +#endif /* SCAN */ + exit(1); + } +} + +static int dd_getbits(n) +int n; +{ + int r; + + while(dd_bitcount < n) { + dd_bitbuf = (dd_bitbuf << 8) | (~(*dd_bitptr++) & BYTEMASK); + dd_bitcount += 8; + } + dd_bitcount -= n; + r = (dd_bitbuf >> dd_bitcount); + dd_bitbuf ^= (r << dd_bitcount); + return r; +} + +#endif /* UNTESTED */ + +/*---------------------------------------------------------------------------*/ +/* Method 8: Compactor compatible compression */ +/*---------------------------------------------------------------------------*/ +static void dd_cpt_compat(ibytes, obytes, data, sub_method, chksum) +unsigned char *data; +unsigned long ibytes, obytes, chksum; +int sub_method; +{ + unsigned long cks; + char *optr = out_buffer; + + cpt_wrfile1(data, ibytes, obytes, sub_method, (unsigned long)0x0fff0); + cks = arc_updcrc(INIT_CRC, (unsigned char *)optr, (int)obytes); + if(chksum != cks) { + (void)fprintf(stderr, + "Checksum error on fork: need 0x%04x, got 0x%04x\n", + (int)chksum, (int)cks); +#ifdef SCAN + do_error("macunpack: Checksum error on fork"); +#endif /* SCAN */ + exit(1); + } +} +#else /* DD */ +int dd; /* keep lint and some compilers happy */ +#endif /* DD */ + diff --git a/macunpack/dd.h b/macunpack/dd.h new file mode 100755 index 0000000..1fc0453 --- /dev/null +++ b/macunpack/dd.h @@ -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 */ + diff --git a/macunpack/de_compress.c b/macunpack/de_compress.c new file mode 100755 index 0000000..a393a5a --- /dev/null +++ b/macunpack/de_compress.c @@ -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<= 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 */ + diff --git a/macunpack/de_huffman.c b/macunpack/de_huffman.c new file mode 100755 index 0000000..860d2fc --- /dev/null +++ b/macunpack/de_huffman.c @@ -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 */ + diff --git a/macunpack/de_lzah.c b/macunpack/de_lzah.c new file mode 100755 index 0000000..bfa28e7 --- /dev/null +++ b/macunpack/de_lzah.c @@ -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 */ + diff --git a/macunpack/de_lzh.c b/macunpack/de_lzh.c new file mode 100755 index 0000000..9d16177 --- /dev/null +++ b/macunpack/de_lzh.c @@ -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 */ + diff --git a/macunpack/dia.c b/macunpack/dia.c new file mode 100755 index 0000000..984eff3 --- /dev/null +++ b/macunpack/dia.c @@ -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 */ + diff --git a/macunpack/dia.h b/macunpack/dia.h new file mode 100755 index 0000000..10c73e2 --- /dev/null +++ b/macunpack/dia.h @@ -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 + diff --git a/macunpack/dia.o b/macunpack/dia.o new file mode 100644 index 0000000000000000000000000000000000000000..43618dbbc08f674f2cddbda583846f6dc31639ab GIT binary patch literal 15248 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 literal 0 HcmV?d00001 diff --git a/macunpack/dir.c b/macunpack/dir.c new file mode 100755 index 0000000..494b395 --- /dev/null +++ b/macunpack/dir.c @@ -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++; +} + diff --git a/macunpack/dir.o b/macunpack/dir.o new file mode 100644 index 0000000000000000000000000000000000000000..1a00d4ad4fa8c516443e45f534bbf4161e9687c2 GIT binary patch literal 3952 zcmbuBU1(fI6vtYKhu5rl+1)dwlIbUpvMbF#;qy&!m&J9FkY zXU?2CbMNd-4~`7AghGlXq@Goc7E`67?F~Jq)tKr~?P_dhIyBQc`w5}=+_m{l=&CJs z);h?E*IFpW<{krnMwgZSwZA%R*Qvc2qv9)i)C!9DoE}`&Wh`Fp15}-}S5RIU3srxg zj;FMXc-X5J-fC$KXZsqQabxx+3d8dlI&zVttL!n6P1fi1EXKUD-6-x*buT85t^HJ8 z33+j?EjH$gr|v*^JnU5qUO4mGSHo)U3!$H@E*VFw<$Aqd{UH|j+nWTe{(YlfkI#2t zhOcj@;#=%Td_jBHnOX$U+6EW@DKK8;?nZprvSpgrtb18+0;XC0UPq%>xY)+?u6_ub z(jmpeUN!ey!`Q_s&(43uoGh28)k}2lWwiDU;V0mYoI#?)IGMQ{DYZu%|-p&`D zsW#JZ3l;ra zyQ(cMpS5jm?Y~9S<^|Svle$uG)*Ej61t=A!Uo#1lr)CmXI*tG8+Cr_6@WUfJHRl#$ z^JJUht)|U2nqdWR8zroymDj&RR~zHmWw?Hmg{wyl-y;~SVYQjn^?IJPZjm>=7sR6U zbgf%8l&1ptXaIjPfFBLub^vz*crk!a1@M^welmc+6Tm+R;2#C>GXeb50RDLZ|1yB9 zbk?y_C=(^u(RDsKsq3|!0kj&dEmo2+0TgVg>#X@dMrHhGdAx+1CD!X((I4V_VDi zP>$_6$Q*aFuC46Jtcx*kRBUI8Y%4B>T1@08V5^1SH5>)duhSU>xzFoX;P{G}KNP_A z`A>bY$G6D#L&hGgTkz)$XM6sB$9(*n7f$_%kMqe=5?sc4TyXei|24zWzKtG^6W=2Q z@!;&_c~1e7fa9BIej1Pj{7!n9p93TTm-*CZz2UIudA}na!hV=9dsuTB&n3ZSJiiK# zJa9aJ2rlEnEdhc&;LPNCuL6=F9+^)*_`zj9H{*|i1RVb#><9N52>4y}FyCf4eB3Sg z1A^ZpxF!6^`1=Hx@eB(;J;KkS0Q*-2mvK%Aj;kEUUlRWDKg#@s;M)bC5q{*pzb))# z{@)Y!GXJLpm+Spla9n{no-=~Wb)7fdpZ^QO9^XE{KNp4l{lfpx!d|{_zX*=~x@x}P z6~SdZe+vH*;s1uPmwDKP7mCFH9(Eg!b?u;s^AI5&f^K7?+sZ0W<=x~ls$Ivc$60gi zT+(vwNmp6vq?=UMv2s~iP7w{5_gZwAr;7PJ&S9%ibZv`nUVF`XuSeVCiHw8u`~OOW z93U0`8$^s4gzpVr%d=%&_fvtK#Ly6O$vC`>P7+*IF%RE_ut$(x^nhazq`WHfExB>G zjvgfqKKw;e_V`(>L33PJin4< literal 0 HcmV?d00001 diff --git a/macunpack/globals.c b/macunpack/globals.c new file mode 100755 index 0000000..d878a7b --- /dev/null +++ b/macunpack/globals.c @@ -0,0 +1,22 @@ +#include "globals.h" +#include "../fileio/machdr.h" +#include "../fileio/wrfile.h" +#include "../fileio/kind.h" + +char info[INFOBYTES]; +char text[F_NAMELEN+1]; + +int list, verbose, info_only, query, write_it, indent, dir_skip, no_dd; +FILE *infp; +int in_data_size = -1; +int in_rsrc_size = -1; +int in_ds, in_rs, ds_skip, rs_skip; + +#ifdef SCAN +void do_error(string) +char *string; +{ + do_idf(string, ERROR); +} +#endif /* SCAN */ + diff --git a/macunpack/globals.h b/macunpack/globals.h new file mode 100755 index 0000000..e431048 --- /dev/null +++ b/macunpack/globals.h @@ -0,0 +1,14 @@ +#include + +extern void exit(); +extern void transname(); +extern void do_error(); + +extern char info[]; +extern char text[]; + +extern int list, verbose, info_only, query, write_it, indent, dir_skip, no_dd; +extern FILE *infp; + +extern int in_data_size, in_rsrc_size, in_ds, in_rs, ds_skip, rs_skip; + diff --git a/macunpack/globals.o b/macunpack/globals.o new file mode 100644 index 0000000000000000000000000000000000000000..ca6886100d46acb0d864e22f6ed551f5ee9d5dc7 GIT binary patch literal 1464 zcmb_cO-md>5Pj>!M9E2W3FNY#R4`2-2>}l>B5Dre&5H=*>`t2u?#`I*_G1G<$t4$m zME+v(2iC5!idov}n*}?s-m7|DJwx~2?jG#T^?H!#VGAu26}U;-JZ;hxi&(&v1N%EW zoBg%@!=v^77xhtnXxlq8n(+evrd`FPa|b|zxvqAv&ung{Bfp3l4Xc@WW$BKk>0*Ae|ZqF+YzUlIK` z>wS+DY4ZgBc%=90GrwcRw^2RFM^+7CY-Z2P3lxlHl^F~FESjgWW|-OXr*5R& 0) { + olength = getb(infp) & BYTEMASK; + olength = (olength << 8) | (getb(infp) & BYTEMASK); + ilength = getb(infp) & BYTEMASK; + ilength = (ilength << 8) | (getb(infp) & BYTEMASK); + if(write_it) { + jdw_block(olength); + } else { + for(i = 0; i < ilength; i++) { + (void)getb(infp); + } + } + comprlength += ilength + 4; + length -= olength; + } + if(verbose) { + (void)fprintf(stderr, "(%4.1f%%)", 100.0 * comprlength / origlength); + } +} + +static void jdw_block(olength) +int olength; +{ + bytesread = 0; + read_tree(); + /* Put reading back at a word boundary! */ + while(bytesread & 3) { + (void)getb(infp); + bytesread++; + } + clrhuff(); + de_huffman((unsigned long)olength); +} +#else /* JDW */ +int jdw; /* keep lint and some compilers happy */ +#endif /* JDW */ + diff --git a/macunpack/jdw.h b/macunpack/jdw.h new file mode 100755 index 0000000..545c365 --- /dev/null +++ b/macunpack/jdw.h @@ -0,0 +1,23 @@ +#define J_MAGIC 0 +#define J_TYPE 6 +#define J_AUTH 10 +#define J_FINFO 14 +#define J_DATALENGTH 22 +#define J_RSRCLENGTH 26 +#define J_CTIME 30 +#define J_MTIME 34 +#define J_FLENGTH 38 + +typedef struct fileHdr { + char magic[6]; + unsigned long type; + unsigned long auth; + char finfo[8]; + unsigned long dataLength; + unsigned long rsrcLength; + unsigned long ctime; + unsigned long mtime; + char flength; + char fname[32]; /* actually flength */ +}; + diff --git a/macunpack/jdw.o b/macunpack/jdw.o new file mode 100644 index 0000000000000000000000000000000000000000..4d04e71151f3baf62162897e6c53c7e805f1dcdf GIT binary patch literal 7256 zcmb_ge{5UD9Y4n@NlLL(V9>4Wa6=O?AdqSsWSzy9-S*x z(#K2n=$WAFtRB4_Ty@Di@)86%1ii0MW~Pr_C@yz9 z-qEW0`T5Z^-UCUvJLp>aq${xDdg|g-2e{MxF`0Md+>QD9w$aN&&2jIQ@tL4^^~8*K zCx7O)(b=KRfWC+5pJ%+gkLlTUI0jN0r-YB*)XN|e%1r8~C$;n^u297!7t_6~$7j4d z#;1QB%3S5Xi{QJ;CBb(JeD6)awqWjSWBOQWO)WN(2~;m@7=H&Fq^Dh} zPea)nqy@7tR(~Jvq0IR|05v`C(l`7i^_iYs0U)5CIHLErYI=GCXlGLwLYWIr|E5+w zeH{GL;LqN#mIknR&Slpuh=bt?Jv}EalTX>(B~i_f~s^_lCo3PbJ)X+Jl*? zw#?_D%r!l`pkXKZM5TB(YjI&mk;`iI73h*a#+S=Gi=oU@IPbjz>m^^=ht$lK+(XU$ zn|Ka@Cr^8U)6V5+?^D`AO3Uqruy$hln%qkAjvmI)^od%s2^NMh!xLnxlkXY14Yv&V zj$L$W2QUg@Q&AF7UNqq0g#kNBKuOVn05JGK8GQrRFw;}i6BGc^cDY0Z(&D$6`+-AeyHZ z7{G*x7Eif$Gur{--9qbj%;+!E>U2L_;_22r1HGQkk|Qcvp;-KeT`pzU=8JjVMc?3z zx#6#vxk0IzxfxHe1ujgm5~9z?PB7dIH+rYJ8AdtH%_^KAAZ~{1ZlT@EtBV{h+$r#d zY&o~ic2^4i*K7gz@Vc}A_X&Qrji1Y}MXb(-^L+!xEq7n&bTeFS3vDA*D;Gk%rYZ34 z3VgQ$$Gj}2Zz}LX1-@5-k0|ix6*%sA#rktdfgc9^R>(J*XMBAD_A3Sd0|k!TU$J)a zAX*H6SAm~Y;D1%%A1m-F1wO05|Ea*|6nG_U5XGLWOo88`!0%AtD;4-^1;a z4G)^}gt>?LLz^1#QjeDh@UjLkYw@xUFAw5nJxf|K!!%iVOK5A077B0Oyt%!#Biy02 zgj&NaK4|t>2J0HOjHGEqVhk@~%QOtu(;pvTPa0Mii}sq`@IqoSBaC-=F)_$O4IYPrnhyw-t0OVp?HnCLxOWdSaFt z=}&ThECJ4#(Qjc_65&LD?=UozvZ4$;Pp1rXSj6GWj2Zp0aJ;A2VBs(bNB4xI-Fw3E zNKY?JFxXdfH`sd_f2Vx`FI=?M1iu-|691;aac94S-~oZ#b+!?F3E_WR;C7t^;o~0s zd9FM2-zEHIP?r5k+xXW7KTB|YM#+Ck;Mgwi)e?VI;Mjj`SK>cc;J+6*>MSRGT;FJj z<2gX;;Ce+vecGQ%j^_BZKmQWAoi9JB?fu7fhGysADR4XgUIo8F!GDPGS3o=RxgH}p zeXdT0jz#$203A7BKO#6DIi>zD3GN~I5rX4cO!AKk9G~|tg8Oh_zz|;v|B_!PaQnDD zNcePKS_r?2=ycj}aB+Kz;BE&zf>F%(M|iaT;TR`@GJO@3Vxe{zg@xKMfg?Fr#Z22blY(FEaSG9;I#ky6#54h z{GTfLzaV_09ETqeKA!z0{$s+Y&-E(7y@dZWg42EPH$}MeR?kXEy3#v|0vO+`hO(&Qo=t?bg2G$ zf;SNUC89(1=LnA9zOw%%;u96ehw3jO_ydIRgEAV<7ye5V$I3h|zpt1-IoxMOy5Me^ zxqG)PnMQBK&yT@=e$@4MC6ml=Ca{9^20t9=X|*w5jV3Lqz|TQ_cpmomCoIDczt!B& zkGjA@WurSBH}PQo|1ckj;1NR%OJ1^BlqziwaU99>@T`bq+?+>pg~R-JHpUvoPZW4o z#@KSf!!s}1J@AjX*lrQx_K2-riQC)9JpeWT*Lch^)Wlq%CfjeMAe3eM^4=^kd;EUU ze|x-qei@JNIV@xDQX3cXk}rL-F7Ho(1LJWmQadH$?YgpEdB-f0Wg7qCe>wioh4G@pinG-&f`Z5n0zkGA50|~FY^ccZf_ePc1ZlBbqdA7FdcE 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + } + } + } else { + if(fread(subheader, 1, 3, infp) != 3) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + if(strncmp(subheader, MAGIC2, 2)) { + (void)fprintf(stderr, "Magic subheader mismatch\n"); +#ifdef SCAN + do_error("macunpack: Magic subheader mismatch"); +#endif /* SCAN */ + exit(1); + } + nbits = subheader[2] & 0x7f; + if(verbose) { + (void)fprintf(stderr, "LZC(%d) compressed (%4.1f%%)", + nbits, 100.0 * ibytes / obytes); + } + if(write_it) { + de_compress(ibytes - 3, nbits); + } else { + n = ibytes - 3; + while(n-- > 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + } + } + } +} + +static void lzc_zivu(ohdr) +char *ohdr; +{ + (void)fprintf(stderr, + "\tMacCompress(Unix) not yet implemented, copied as MacBinary\n"); + mcb(ohdr, (unsigned long)in_rsrc_size, (unsigned long)in_data_size, + in_ds + in_rs); +} +#else /* LZC */ +int lzc; /* keep lint and some compilers happy */ +#endif /* LZC */ + diff --git a/macunpack/lzc.h b/macunpack/lzc.h new file mode 100755 index 0000000..daa6d86 --- /dev/null +++ b/macunpack/lzc.h @@ -0,0 +1,29 @@ +#define HEADERBYTES 48 +#define MAGIC1 "\253\315\000\060" +#define MAGIC2 "\037\235" + +#define C_DLENOFF 4 +#define C_DLENOFFC 8 +#define C_RLENOFF 12 +#define C_RLENOFFC 16 +#define C_MTIMOFF 24 +#define C_CTIMOFF 28 +#define C_TYPEOFF 32 +#define C_AUTHOFF 36 +#define C_FLAGOFF 40 + +typedef struct fileHdr { + unsigned long magic1; + unsigned long dataLength; + unsigned long dataCLength; + unsigned long rsrcLength; + unsigned long rsrcCLength; + unsigned long unknown1; + unsigned long mtime; + unsigned long ctime; + unsigned long filetype; + unsigned long fileauth; + unsigned long flag1; + unsigned long flag2; +}; + diff --git a/macunpack/lzc.o b/macunpack/lzc.o new file mode 100644 index 0000000000000000000000000000000000000000..10f3aae12f88691e1d6d549ac74c60e55027084d GIT binary patch literal 8880 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 literal 0 HcmV?d00001 diff --git a/macunpack/lzh.c b/macunpack/lzh.c new file mode 100755 index 0000000..136f8d1 --- /dev/null +++ b/macunpack/lzh.c @@ -0,0 +1,776 @@ +#include "macunpack.h" +#ifdef LZH +#include "globals.h" +#include "lzh.h" +#include "crc.h" +#include "../fileio/wrfile.h" +#include "../fileio/machdr.h" +#include "../util/masks.h" +#include "../util/util.h" +#include "bits_be.h" + +#define LZ5LOOKAHEAD 18 /* look ahead buffer size for LArc */ +#define LZ5BUFFSIZE 8192 +#define LZ5MASK 8191 +#define LZSLOOKAHEAD 17 +#define LZSBUFFSIZE 4096 +#define LZSMASK 4095 +#define LZBUFFSIZE 8192 /* Max of above buffsizes */ + +extern char *malloc(); +extern char *realloc(); +extern void de_lzah(); +extern unsigned char (*lzah_getbyte)(); +extern void de_lzh(); + +typedef struct methodinfo { + char *name; + int number; +}; + +static struct methodinfo methods[] = { + {"-lh0-", lh0}, + {"-lh1-", lh1}, + {"-lh2-", lh2}, + {"-lh3-", lh3}, + {"-lh4-", lh4}, + {"-lh5-", lh5}, + {"-lz4-", lz4}, + {"-lz5-", lz5}, + {"-lzs-", lzs} +}; +static char *lzh_archive; +static char *lzh_pointer; +static char *lzh_data; +static char *lzh_finfo; +static int lzh_fsize; +static int lzh_kind; +static int oldsize; +static char *lzh_file; +static int lzh_filesize; +static char *lzh_current; +static char *tmp_out_ptr; +static char lzh_lzbuf[LZBUFFSIZE]; + +static int lzh_filehdr(); +static int lzh_checkm(); +static char *lzh_methname(); +static void lzh_wrfile(); +static void lzh_skip(); +static void lzh_nocomp(); +#ifdef UNTESTED +static void lzh_lzss1(); +static void lzh_lzss2(); +#endif /* UNTESTED */ +static void lzh_lzah(); +static unsigned char lzh_getbyte(); +#ifdef UNDEF +static void lzh_lh2(); +static void lzh_lh3(); +#endif /* UNDEF */ +#ifdef UNTESTED +static void lzh_lzh12(); +#endif /* UNTESTED */ +static void lzh_lzh13(); + +void lzh(kind) +int kind; +{ + struct fileHdr filehdr; + int m, i, j; + char loc_name[64]; + char dirinfo[INFOBYTES]; + + updcrc = arc_updcrc; + crcinit = arc_crcinit; + write_it = 1; + lzh_fsize = 0; + lzh_kind = kind; + if(lzh_archive == NULL) { + lzh_archive = malloc((unsigned)in_data_size); + oldsize = in_data_size; + } else if(in_data_size > oldsize) { + lzh_archive = realloc(lzh_archive, (unsigned)in_data_size); + oldsize = in_data_size; + } + if(lzh_archive == NULL) { + (void)fprintf(stderr, "Insufficient memory for archive.\n"); + exit(1); + } + if(fread(lzh_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); + } + lzh_pointer = lzh_archive; + while(1) { + if(in_data_size == 0) { + break; + } + if(lzh_filehdr(&filehdr) == 0) { + break; + } + m = lzh_checkm(&filehdr); + if(m < 0) { + (void)fprintf(stderr, + "Skipping file: \"%s\"; unknown method: %.5s.\n", + text, filehdr.method); + lzh_skip(&filehdr); + continue; + } + if(!write_it) { + /* We are skipping a folder. Skip the file if lzh_finfo is a + prefix of or identical to the folder info in the file. */ + if(lzh_fsize <= filehdr.extendsize && + !strncmp(lzh_finfo, filehdr.extend, lzh_fsize)) { + /* It was true, so we skip. */ + lzh_skip(&filehdr); + continue; + } + /* We have left the folder we were skipping. */ + } + /* Now we must leave folders until lzh_finfo is a proper prefix or + identical to the folder info in the file. */ + while(lzh_fsize > filehdr.extendsize || + strncmp(lzh_finfo, filehdr.extend, lzh_fsize)) { + /* Not a proper prefix, leave folder. First determine which! */ + i = lzh_fsize - 1; + while(--i >= 0 && lzh_finfo[i] != ':'); + i = i + 1; + transname(lzh_finfo + i, loc_name, lzh_fsize - i - 1); + lzh_fsize = i; + if(write_it) { + indent--; + if(!info_only) { + enddir(); + } + if(list) { + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name); + } + } + write_it = 1; + } + write_it = 1; + /* lzh_finfo is a proper prefix or identical, just show so. */ + lzh_finfo = filehdr.extend; + /* Now enter directories while lzh_finfo is smaller than extend. */ + while(lzh_fsize < filehdr.extendsize) { + i = lzh_fsize; + while(lzh_finfo[++i] != ':'); + transname(lzh_finfo + lzh_fsize, loc_name, i - lzh_fsize); + for(j = 0; j < INFOBYTES; j++) { + dirinfo[j] = 0; + } + dirinfo[I_NAMEOFF] = i - lzh_fsize; + copy(dirinfo + I_NAMEOFF + 1, lzh_finfo + lzh_fsize, i - lzh_fsize); + lzh_fsize = i + 1; + if(list) { + do_indent(indent); + (void)fprintf(stderr, "folder=\"%s\"", loc_name); + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + if(write_it) { + indent++; + } + } + if(write_it && !info_only) { + do_mkdir(loc_name, dirinfo); + } + if(!write_it) { + break; + } + } + if(!write_it) { + lzh_skip(&filehdr); + } else { + lzh_wrfile(&filehdr, m); + } + } + /* Leaving some more directories! */ + while(lzh_fsize != 0) { + i = lzh_fsize - 1; + while(--i >= 0 && lzh_finfo[i] != ':'); + i = i + 1; + transname(lzh_finfo + i, loc_name, lzh_fsize - i - 1); + lzh_fsize = i; + if(write_it) { + } + if(write_it) { + indent--; + if(!info_only) { + enddir(); + } + if(list) { + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name); + } + } + } +} + +static int lzh_filehdr(f) +struct fileHdr *f; +{ + register int i; + char *hdr; + int c; + int ext_ptr; + int chk_sum = 0; + char *ptr; + + if(in_data_size <= 0) { + return 0; + } + for(i = 0; i < INFOBYTES; i++) { + info[i] = '\0'; + } + hdr = lzh_pointer; + in_data_size -= 2; + lzh_pointer += 2; + if(in_data_size < 0) { + in_data_size++; + } + f->hsize = (unsigned char)hdr[L_HSIZE]; + if(f->hsize == 0) { + return 0; + } + f->hcrc = (unsigned char)hdr[L_HCRC]; + ptr = hdr + L_METHOD; + in_data_size -= f->hsize; + lzh_pointer += f->hsize; + copy(&(f->method[0]), hdr + L_METHOD, 5); + f->psize = get4i(hdr + L_PSIZE); + f->upsize = get4i(hdr + L_UPSIZE); + f->lastmod = get4i(hdr + L_LASTMOD); + f->attribute = hdr[L_ATTRIBUTE + 1]; + if(f->attribute < 2) { + for(i = 0; i < f->hsize; i++) { + chk_sum += *ptr++; + } + chk_sum &= BYTEMASK; + if(chk_sum != f->hcrc) { + (void)fprintf(stderr, + "Header checksum error; got %.2x, must be %.2x.\n", + chk_sum, f->hcrc); +#ifdef SCAN + do_error("macunpack: Header checksum error"); +#endif /* SCAN */ + exit(1); + } + f->nlength = (unsigned char)hdr[L_NLENGTH]; + info[I_NAMEOFF] = f->nlength; + copy(info + I_NAMEOFF + 1, hdr + L_NAME, (int)f->nlength); + transname(hdr + L_NAME, text, (int)f->nlength); + ext_ptr = L_NLENGTH + f->nlength + 1; + f->crc = get2i(hdr + ext_ptr + L_CRC); + if(f->attribute == 1) { + f->etype = hdr[ext_ptr + L_ETYPE]; + f->extendsize = hdr[ext_ptr + L_EXTENDSZ]; + f->extend = hdr + ext_ptr + L_EXTEND; + } else { + f->extend = NULL; + f->extendsize = 0; + } + } else if(f->attribute == 2) { + in_data_size += 2; + lzh_pointer -= 2; + f->nlength = hdr[L_2EXTENDSZ] - 3; + info[I_NAMEOFF] = f->nlength; + copy(info + I_NAMEOFF + 1, hdr + L_2EXTEND + 2, (int)f->nlength); + transname(hdr + L_2EXTEND + 2, text, (int)f->nlength); + ext_ptr = + f->crc = get2i(hdr + L_2CRC); + f->etype = hdr[L_2ETYPE]; + ext_ptr = L_2EXTEND + 2 + f->nlength; + f->extendsize = hdr[ext_ptr + L_EEXTENDSZ]; + f->extend = hdr + ext_ptr + L_EEXTEND; + } else { + (void)fprintf(stderr, "Unknown file header format (%d).\n", + (int)f->attribute); +#ifdef SCAN + do_error("macunpack: Unknown file header format"); +#endif /* SCAN */ + exit(1); + } + if(f->extend != NULL) { + if(f->extendsize > 5) { + f->extend += 2; + hdr = f->extend; + f->extendsize -= 3; + for(i = 0; i < f->extendsize; i++) { + c = *hdr++; + if((c & BYTEMASK) == BYTEMASK) { + hdr[-1] = ':'; + c = ':'; + } + } + c = *hdr++; + if(c == 5) { + hdr += 5; + } + } else { + if(f->extendsize == 5) { + hdr = f->extend; + f->extend = NULL; + f->extendsize = 0; + hdr += 5; + } else { + hdr = f->extend; + f->extend = NULL; + f->extendsize = 0; + } + } + } else { + hdr = hdr + ext_ptr; + } + lzh_data = hdr; + if(f->attribute != 0) { + lzh_data++; + } + return 1; +} + +static int lzh_checkm(f) +struct fileHdr *f; +{ + int i, nummeth; + char *meth; + + meth = f->method; + nummeth = sizeof(methods) / sizeof(struct methodinfo); + for(i = 0; i < nummeth; i++) { + if(!strncmp(methods[i].name, meth, 5)) { + return methods[i].number; + } + } + return -1; +} + +static char *lzh_methname(n) +int n; +{ + if(n > sizeof(methods) / sizeof(struct methodinfo)) { + return NULL; + } + return methods[n].name; +} + +static void lzh_wrfile(filehdr, method) +struct fileHdr *filehdr; +int method; +{ + char ftype[5], fauth[5]; + int rsrcLength, dataLength; + int doit; + char *mname; + unsigned long crc; + + if(filehdr->upsize > lzh_filesize) { + if(lzh_filesize == 0) { + lzh_file = malloc((unsigned)filehdr->upsize); + } else { + lzh_file = realloc(lzh_file, (unsigned)filehdr->upsize); + } + if(lzh_file == NULL) { + (void)fprintf(stderr, "Insufficient memory to unpack file.\n"); + exit(1); + } + } + switch(method) { + case lz4: + lzh_nocomp((unsigned long)128); + break; +#ifdef UNTESTED + case lz5: + lzh_lzss1((unsigned long)128); + break; + case lzs: + lzh_lzss2((unsigned long)128); + break; +#endif /* UNTESTED */ + case lh0: + lzh_nocomp((unsigned long)128); + break; + case lh1: + lzh_lzah((unsigned long)128); + break; +#ifdef UNDEF + case lh2: + lzh_lh2((unsigned long)128); + break; + case lh3: + lzh_lh3((unsigned long)128); + break; +#endif /* UNDEF */ +#ifdef UNTESTED + case lh4: + lzh_lzh12((unsigned long)128); + break; +#endif /* UNTESTED */ + case lh5: + lzh_lzh13((unsigned long)128); + break; + default: + mname = lzh_methname(method); + if(mname != NULL) { + do_indent(indent); + (void)fprintf(stderr, + "\tSorry, packing method not yet implemented.\n"); + do_indent(indent); + (void)fprintf(stderr, "File = \"%s\"; ", text); + (void)fprintf(stderr, "method = %s, skipping file.\n", mname); + lzh_skip(filehdr); + return; + } + (void)fprintf(stderr, + "There is something very wrong with this program!\n"); +#ifdef SCAN + do_error("macunpack: program error"); +#endif /* SCAN */ + exit(1); + } + /* Checks whether everything is packed as MacBinary. */ + if(*lzh_file != 0 /* More checks possible here. */) { + do_indent(indent); + (void)fprintf(stderr, "File = \"%s\" ", text); + (void)fprintf(stderr, "not packed in MacBinary, skipping file.\n"); +#ifdef SCAN + do_error("macunpack: not MacBinary"); +#endif /* SCAN */ + lzh_skip(filehdr); + return; + } + copy(info, lzh_file, 128); + rsrcLength = get4(info + I_RLENOFF); + dataLength = get4(info + I_DLENOFF); + transname(info + I_TYPEOFF, ftype, 4); + transname(info + I_AUTHOFF, fauth, 4); + if(list) { + do_indent(indent); + (void)fprintf(stderr, + "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld", + text, ftype, fauth, (long)dataLength, (long)rsrcLength); + } + if(info_only) { + doit = 0; + } else { + doit = 1; + } + if(query) { + doit = do_query(); + } else if(list) { + (void)fputc('\n', stderr); + } + if(doit) { + define_name(text); + start_info(info, (unsigned long)rsrcLength, (unsigned long)dataLength); + } + switch(method) { + case lz4: + if(verbose) { + (void)fprintf(stderr, "\tNo Compression (%.5s)", filehdr->method); + } + if(doit) { + lzh_nocomp(filehdr->upsize); + } + break; +#ifdef UNTESTED + case lz5: + if(verbose) { + (void)fprintf(stderr, "\tLZSS (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzss1(filehdr->upsize); + } + break; + case lzs: + if(verbose) { + (void)fprintf(stderr, "\tLZSS (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzss2(filehdr->upsize); + } + break; +#endif /* UNTESTED */ + case lh0: + if(verbose) { + (void)fprintf(stderr, "\tNo Compression (%.5s)", filehdr->method); + } + if(doit) { + lzh_nocomp(filehdr->upsize); + } + break; + case lh1: + if(verbose) { + (void)fprintf(stderr, "\tLZAH (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzah(filehdr->upsize); + } + break; +#ifdef UNDEF + case lh2: + if(verbose) { + (void)fprintf(stderr, "\tLZAH (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lh2(filehdr->upsize); + } + break; + case lh3: + if(verbose) { + (void)fprintf(stderr, "\tLZH (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzh3(filehdr->upsize); + } + break; +#endif /* UNDEF */ +#ifdef UNTESTED + case lh4: + if(verbose) { + (void)fprintf(stderr, "\tLZH (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzh12(filehdr->upsize); + } + break; +#endif /* UNTESTED */ + case lh5: + if(verbose) { + (void)fprintf(stderr, "\tLZH (%.5s) compressed (%4.1f%%)", + filehdr->method, 100.0 * filehdr->psize / filehdr->upsize); + } + if(doit) { + lzh_lzh13(filehdr->upsize); + } + } + if(doit) { + crc = (*updcrc)(INIT_CRC, lzh_file, filehdr->upsize); + if(filehdr->crc != crc) { + (void)fprintf(stderr, + "CRC error on file: need 0x%04x, got 0x%04x\n", + filehdr->crc, (int)crc); +#ifdef SCAN + do_error("macunpack: CRC error on file"); +#endif /* SCAN */ + exit(1); + } + start_data(); + copy(out_ptr, lzh_file + 128, (int)(filehdr->upsize - 128)); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } + if(doit) { + end_file(); + } + lzh_skip(filehdr); +} + +static void lzh_skip(filehdr) +struct fileHdr *filehdr; +{ + lzh_pointer += filehdr->psize; + in_data_size -= filehdr->psize; +} + +/*---------------------------------------------------------------------------*/ +/* -lz4- and -lh0: No compression */ +/*---------------------------------------------------------------------------*/ +static void lzh_nocomp(obytes) +unsigned long obytes; +{ + copy(lzh_file, lzh_data, (int)obytes); +} + +#ifdef UNTESTED +/*---------------------------------------------------------------------------*/ +/* -lz5-: LZSS compression, variant 1 */ +/*---------------------------------------------------------------------------*/ +static void lzh_lzss1(obytes) +unsigned long obytes; +{ + int mask, ch, lzcnt, lzptr, ptr, count; + char *p = lzh_lzbuf; + int i, j; + + for(i = 0; i < 256; i++) { + for(j = 0; j < 13; j++) { + *p++ = i; + } + } + for(i = 0; i < 256; i++) { + *p++ = i; + } + for(i = 0; i < 256; i++) { + *p++ = 255 - i; + } + for(i = 0; i < 128; i++) { + *p++ = 0; + } + for(i = 0; i < 128; i++) { + *p++ = ' '; + } + + tmp_out_ptr = out_ptr; + out_ptr = lzh_file; + ptr = LZ5BUFFSIZE - LZ5LOOKAHEAD; + count = 0; + lzh_current = lzh_data; + while(obytes != 0) { + if(count == 0) { + mask = *lzh_current++ & BYTEMASK; + count = 8; + } + count--; + ch = *lzh_current++ & BYTEMASK; + if ((mask & 1) != 0) { + *out_ptr++ = ch; + lzh_lzbuf[ptr++] = ch; + ptr &= LZ5MASK; + obytes--; + } else { + lzcnt = *lzh_current++; + lzptr = (ch & 0x00ff) | ((lzcnt << 4) & 0x0f00); + lzcnt = (lzcnt & 0x000f) + 3; + obytes -= lzcnt; + do { + ch = lzh_lzbuf[lzptr++]; + lzh_lzbuf[ptr++] = ch; + *out_ptr++ = ch; + lzptr &= LZ5MASK; + ptr &= LZ5MASK; + } while (--lzcnt != 0) ; + } + mask >>= 1; + } + out_ptr = tmp_out_ptr; +} + +/*---------------------------------------------------------------------------*/ +/* -lzs-: LZSS compression, variant 2 */ +/*---------------------------------------------------------------------------*/ +static void lzh_lzss2(obytes) +unsigned long obytes; +{ + int ch, lzcnt, lzptr, ptr, i; + + tmp_out_ptr = out_ptr; + out_ptr = lzh_file; + ptr = LZSBUFFSIZE - LZSLOOKAHEAD; + for(i = 0; i < ptr; i++) { + lzh_lzbuf[i] = ' '; + } + for(i = ptr; i < LZSBUFFSIZE; i++) { + lzh_lzbuf[i] = 0; + } + bit_be_init_getbits(); + bit_be_filestart = lzh_data; + bit_be_inbytes = -1; + while(obytes != 0) { + if(bit_be_getbits(1) == 0) { + ch = bit_be_getbits(8); + *out_ptr++ = ch; + lzh_lzbuf[ptr++] = ch; + ptr &= LZSMASK; + obytes--; + } else { + lzptr = bit_be_getbits(11); + lzcnt = bit_be_getbits(4) + 3; + obytes -= lzcnt; + do { + ch = lzh_lzbuf[lzptr++]; + lzh_lzbuf[ptr++] = ch; + *out_ptr++ = ch; + lzptr &= LZSMASK; + ptr &= LZSMASK; + } while (--lzcnt != 0) ; + } + } + out_ptr = tmp_out_ptr; +} +#endif /* UNTESTED */ + +/*---------------------------------------------------------------------------*/ +/* -lh1-: LZ compression plus adaptive Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void lzh_lzah(obytes) +unsigned long obytes; +{ + lzh_current = lzh_data + 2; /* SKIPPING BLOCKSIZE! */ + tmp_out_ptr = out_ptr; + out_ptr = lzh_file; + lzah_getbyte = lzh_getbyte; + de_lzah(obytes); + out_ptr = tmp_out_ptr; +} + +static unsigned char lzh_getbyte() +{ + return *lzh_current++; +} + +#ifdef UNDEF +/*---------------------------------------------------------------------------*/ +/* -lh2-: LZ** compression */ +/*---------------------------------------------------------------------------*/ +static void lzh_lh2(obytes) +unsigned long obytes; +{ +} + +/*---------------------------------------------------------------------------*/ +/* -lh3-: LZ** compression */ +/*---------------------------------------------------------------------------*/ +static void lzh_lh3(obytes) +unsigned long obytes; +{ +} +#endif /* UNDEF */ + +#ifdef UNTESTED +/*---------------------------------------------------------------------------*/ +/* -lh4-: LZ(12) compression plus Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void lzh_lzh12(obytes) +unsigned long obytes; +{ + lzh_current = lzh_data; + tmp_out_ptr = out_ptr; + out_ptr = lzh_file; + /* Controlled by obytes only */ + de_lzh((long)(-1), (long)obytes, &lzh_current, 12); + out_ptr = tmp_out_ptr; +} +#endif /* UNTESTED */ + +/*---------------------------------------------------------------------------*/ +/* -lh5-: LZ(13) compression plus Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void lzh_lzh13(obytes) +unsigned long obytes; +{ + lzh_current = lzh_data; + tmp_out_ptr = out_ptr; + out_ptr = lzh_file; + /* Controlled by obytes only */ + de_lzh((long)(-1), (long)obytes, &lzh_current, 13); + out_ptr = tmp_out_ptr; +} +#else /* LZH */ +int lzh; /* keep lint and some compilers happy */ +#endif /* LZH */ + diff --git a/macunpack/lzh.h b/macunpack/lzh.h new file mode 100755 index 0000000..5ebf8e5 --- /dev/null +++ b/macunpack/lzh.h @@ -0,0 +1,67 @@ +#define FILEHDRSIZE 22 +#define TOTALSIZE 64 +#define L_HSIZE 0 +#define L_HCRC 1 +#define L_METHOD 2 +#define L_PSIZE 7 +#define L_UPSIZE 11 +#define L_LASTMOD 15 +#define L_ATTRIBUTE 19 + +/* Level 0 and level 1 headers */ +#define L_NLENGTH 21 +#define L_NAME 22 +/* Offset after name */ +#define L_CRC 0 +#define L_ETYPE 2 +#define L_EXTENDSZ 3 +#define L_EXTEND 4 + +/* Level 2 header */ +#define L_2CRC 21 +#define L_2ETYPE 23 +#define L_2EXTENDSZ 24 +#define L_2EXTEND 25 + +/* Extension definition, EXTEND defines the size of the extension. */ +#define L_KIND 0 /* After EXTEND */ +#define L_ENAME 2 /* Extension name, EXTEND-3 bytes long */ +/* Offset after name */ +#define L_EEXTENDSZ 0 +#define L_EEXTEND 1 + +typedef struct fileHdr { /* 58 bytes */ + unsigned char hsize; + unsigned char hcrc; + char method[5]; + unsigned long psize; + unsigned long upsize; + unsigned long lastmod; + unsigned short attribute; + unsigned char nlength; + char name[32]; + unsigned short crc; + unsigned char etype; + unsigned char extendsize; + char *extend; + char *data; +}; + +/* Currently known methods: */ +#define lh0 0 +#define lh1 1 +#define lh2 2 +#define lh3 3 +#define lh4 4 +#define lh5 5 +#define lz4 6 +#define lz5 7 +#define lzs 8 + +extern char *lzh_pointer; +extern char *lzh_data; +extern char *lzh_finfo; +extern int lzh_fsize; +extern int lzh_kind; +extern char *lzh_file; + diff --git a/macunpack/macbinary.c b/macunpack/macbinary.c new file mode 100755 index 0000000..cab1e36 --- /dev/null +++ b/macunpack/macbinary.c @@ -0,0 +1,555 @@ +#include "macunpack.h" +#include "globals.h" +#include "../fileio/machdr.h" +#include "../fileio/wrfile.h" +#include "../fileio/kind.h" +#include "zmahdr.h" +#include "../util/util.h" + +extern void dir(); +extern void mcb(); +#ifdef BIN +extern void bin(); +#endif /* BIN */ +#ifdef JDW +extern void jdw(); +#endif /* JDW */ +#ifdef STF +extern void stf(); +#endif /* STF */ +#ifdef LZC +extern void lzc(); +#endif /* LZC */ +#ifdef ASQ +extern void asq(); +#endif /* ASQ */ +#ifdef ARC +extern void arc(); +#endif /* ARC */ +#ifdef PIT +extern void pit(); +#endif /* PIT */ +#ifdef SIT +extern void sit(); +#endif /* SIT */ +#ifdef DIA +extern void dia(); +#endif /* DIA */ +#ifdef CPT +extern void cpt(); +#endif /* CPT */ +#ifdef ZMA +extern void zma(); +#endif /* ZMA */ +#ifdef LZH +extern void lzh(); +#endif /* LZH */ +#ifdef DD +extern void dd_file(); +extern void dd_arch(); +#endif /* DD */ + +static void skip_file(); +#ifdef SCAN +static void get_idf(); +#endif /* SCAN */ + +#define Z (ZMAHDRS2 + 1) + +static int info_given; + +void macbinary() +{ + char header[INFOBYTES]; + int c; + + while(1) { + if((c = fgetc(infp)) == EOF) { + break; + } + (void)ungetc(c, infp); + if(fread(header, 1, Z, infp) != Z) { + (void)fprintf(stderr, "Can't read MacBinary header.\n"); +#ifdef SCAN + do_error("macunpack: Can't read MacBinary header"); +#endif /* SCAN */ + exit(1); + } +#ifdef ZMA + if(!strncmp(header + 1, ZMAHDR, ZMAHDRS2)) { + /* Can distinguish zoom data forks only this way from macbinary */ + if(verbose) { + (void)fprintf(stderr, "This is a \"Zoom\" archive.\n"); + } + zma(header, (unsigned long)0); + exit(0); + } +#endif /* ZMA */ + if(fread(header + Z, 1, INFOBYTES - Z, infp) != INFOBYTES - Z) { + (void)fprintf(stderr, "Can't read MacBinary header.\n"); +#ifdef SCAN + do_error("macunpack: Can't read MacBinary header"); +#endif /* SCAN */ + exit(1); + } + if(verbose && !info_given) { + do_indent(indent); + (void)fprintf(stderr, "This is \"MacBinary\" input.\n"); + info_given = 1; + } + if(header[I_NAMEOFF] & 0x80) { + dir(header); + continue; + } + in_data_size = get4(header + I_DLENOFF); + in_rsrc_size = get4(header + I_RLENOFF); + in_ds = (((in_data_size + 127) >> 7) << 7); + in_rs = (((in_rsrc_size + 127) >> 7) << 7); + ds_skip = in_ds - in_data_size; + rs_skip = in_rs - in_rsrc_size; + if(dir_skip != 0) { + skip_file(in_ds + in_rs); + continue; + } +#ifdef SCAN + if(header[I_NAMEOFF] == 0) { + get_idf((int)header[I_NAMEOFF + 1]); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* SCAN */ + header[I_NAMEOFF + 1 + header[I_NAMEOFF]] = 0; +#ifdef BIN + if(!strncmp(header + I_TYPEOFF, "TEXT", 4) && + !strncmp(header + I_AUTHOFF, "BnHq", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"BinHex 5.0\" packed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + bin(header, in_data_size, 0); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "TEXT", 4) && + !strncmp(header + I_AUTHOFF, "GJBU", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"MacBinary 1.0\" packed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + bin(header, in_data_size, 0); + skip_file(ds_skip + in_rs); + continue; + } + /* Recognize only if creator is UMcp. UMCP uses ttxt as default. */ + if(!strncmp(header + I_TYPEOFF, "TEXT", 4) && + !strncmp(header + I_AUTHOFF, "UMcp", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"UMCP\" packed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + bin(header, in_data_size, 1); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* BIN */ +#ifdef JDW + if(!strncmp(header + I_TYPEOFF, "Smal", 4) && + !strncmp(header + I_AUTHOFF, "Jdw ", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"Compress It\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + jdw((unsigned long)in_data_size); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* JDW */ +#ifdef STF + if(!strncmp(header + I_TYPEOFF, "COMP", 4) && + !strncmp(header + I_AUTHOFF, "STF ", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"ShrinkToFit\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + stf((unsigned long)in_data_size); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* STF */ +#ifdef LZC + if(!strncmp(header + I_TYPEOFF, "ZIVM", 4) && + !strncmp(header + I_AUTHOFF, "LZIV", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"MacCompress(M)\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + lzc(header); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "ZIVU", 4) && + !strncmp(header + I_AUTHOFF, "LZIV", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"MacCompress(U)\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + lzc(header); + continue; + } +#endif /* LZC */ +#ifdef ASQ + if(!strncmp(header + I_TYPEOFF, "ArCv", 4) && + !strncmp(header + I_AUTHOFF, "TrAS", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"AutoSqueeze\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + lzh(0); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* ASQ */ +#ifdef ARC + if(!strncmp(header + I_TYPEOFF, "mArc", 4) && + !strncmp(header + I_AUTHOFF, "arc*", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"ArcMac\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + arc(); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "arc@", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"ArcMac\" self extracting archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + arc(); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* ARC */ +#ifdef PIT + if(!strncmp(header + I_TYPEOFF, "PIT ", 4) && + !strncmp(header + I_AUTHOFF, "PIT ", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"PackIt\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + pit(); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* PIT */ +#ifdef SIT + if(!strncmp(header + I_TYPEOFF, "SIT!", 4) && + !strncmp(header + I_AUTHOFF, "SIT!", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"StuffIt\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + sit(); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "SITD", 4) && + !strncmp(header + I_AUTHOFF, "SIT!", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"StuffIt Deluxe\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + sit(); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "aust", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"StuffIt\" self extracting archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + sit(); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* SIT */ +#ifdef DIA + if(!strncmp(header + I_TYPEOFF, "Pack", 4) && + !strncmp(header + I_AUTHOFF, "Pack", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"Diamond\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + dia((unsigned char *)header); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "Pack", 4) && + in_data_size != 0) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"Diamond\" self extracting archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + dia((unsigned char *)header); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* DIA */ +#ifdef CPT + if(!strncmp(header + I_TYPEOFF, "PACT", 4) && + !strncmp(header + I_AUTHOFF, "CPCT", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"Compactor\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + cpt(); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "EXTR", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"Compactor\" self extracting archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + cpt(); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* CPT */ +#ifdef ZMA + if(!strncmp(header + I_TYPEOFF, "zooM", 4) && + !strncmp(header + I_AUTHOFF, "zooM", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"Zoom\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + zma((char *)NULL, (unsigned long)in_data_size); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "Mooz", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"Zoom\" self extracting archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + zma((char *)NULL, (unsigned long)in_data_size); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* ZMA */ +#ifdef LZH + if(!strncmp(header + I_TYPEOFF, "LARC", 4) && + !strncmp(header + I_AUTHOFF, "LARC", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"MacLHa (LHARC)\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + lzh(0); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "LHA ", 4) && + !strncmp(header + I_AUTHOFF, "LARC", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"MacLHa (LHA)\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + lzh(1); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* LZH */ +#ifdef DD + if((!strncmp(header + I_TYPEOFF, "DD01", 4) || + !strncmp(header + I_TYPEOFF, "DDF?", 3) || + !strncmp(header + I_TYPEOFF, "DDf?", 3)) && + !strncmp(header + I_AUTHOFF, "DDAP", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, + "This is a \"DiskDoubler\" compressed file.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + dd_file((unsigned char *)header); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "DDAR", 4) && + !strncmp(header + I_AUTHOFF, "DDAP", 4)) { + if(verbose) { + do_indent(indent); + (void)fprintf(stderr, "This is a \"DiskDoubler\" archive.\n"); + } +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + dd_arch((unsigned char *)header); + skip_file(ds_skip + in_rs); + continue; + } + if(!strncmp(header + I_TYPEOFF, "APPL", 4) && + !strncmp(header + I_AUTHOFF, "DSEA", 4)) { + if(verbose) { + do_indent(indent); + } + c = getc(infp); + (void)ungetc(c, infp); + if(c == 'D') { + if(verbose) { + (void)fprintf(stderr, + "This is a \"DiskDoubler\" self extracting archive.\n"); +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, ARCH_NAME); +#endif /* SCAN */ + } + dd_arch((unsigned char *)header); + } else { + if(verbose) { + (void)fprintf(stderr, + "This is a \"DiskDoubler\" self decompressing file.\n"); +#ifdef SCAN + do_idf(header + I_NAMEOFF + 1, PACK_NAME); +#endif /* SCAN */ + } + dd_file((unsigned char *)header); + } + skip_file(ds_skip + in_rs); + continue; + } +#endif /* DD */ + if(header[0] == 0 /* MORE CHECKS HERE! */) { + mcb(header, (unsigned long)in_rsrc_size, + (unsigned long)in_data_size, in_ds + in_rs); + continue; + } else { + (void)fprintf(stderr, "Unrecognized archive type.\n"); + exit(1); + } + } +} + +static void skip_file(skip) +int skip; +{ + char buff[1024]; + int n; + + while(skip > 0) { + n = (skip < 1024 ? skip : 1024); + if(fread(buff, 1, n, infp) != n) { + (void)fprintf(stderr, "Incomplete file.\n"); +#ifdef SCAN + do_error("macunpack: Incomplete file"); +#endif /* SCAN */ + exit(1); + } + skip -= n; + } +} + +#ifdef SCAN +static void get_idf(kind) +int kind; +{ + char filename[255]; + + if(fread(filename, 1, in_data_size, infp) != in_data_size) { + (void)fprintf(stderr, "Incomplete file.\n"); +#ifdef SCAN + do_error("macunpack: Incomplete file"); +#endif /* SCAN */ + exit(1); + } + filename[in_data_size] = 0; + do_idf(filename, kind); +} +#endif /* SCAN */ + diff --git a/macunpack/macbinary.o b/macunpack/macbinary.o new file mode 100644 index 0000000000000000000000000000000000000000..96680a400095c5ac02dbf25185bc91ba7b793e30 GIT binary patch literal 17816 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 F_NAMELEN) { + n = F_NAMELEN; + } + info[I_NAMEOFF] = n; + transname(hdr + I_NAMEOFF + 1, text, n); + if(hdr[I_LOCKOFF] & 1) { + hdr[I_FLAGOFF + 1] = PROTCT_MASK; + hdr[I_LOCKOFF] &= ~1; + } + + write_it = 1; + if(list) { + transname(hdr + I_TYPEOFF, ftype, 4); + transname(hdr + I_AUTHOFF, fauth, 4); + do_indent(indent); + (void)fprintf(stderr, + "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld", + text, ftype, fauth, (long)dataLength, (long)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(write_it) { + start_info(info, rsrcLength, dataLength); + } + if(verbose) { + (void)fprintf(stderr, "\tData: "); + } + if(write_it) { + start_data(); + } + mcb_wrfile(dataLength); + if(verbose) { + (void)fprintf(stderr, ", Rsrc: "); + } + if(write_it) { + start_rsrc(); + } + mcb_wrfile(rsrcLength); + if(write_it) { + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } +} + +static void mcb_wrfile(ibytes) +unsigned long ibytes; +{ + int n; + + if(ibytes == 0) { + if(verbose) { + (void)fprintf(stderr, "empty"); + } + return; + } + if(verbose) { + (void)fprintf(stderr, "No compression"); + } + if(write_it) { + n = fread(out_buffer, 1, (int)ibytes, infp); + if(n != ibytes) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + mcb_read -= n; + n = ((n + 127) / 128) * 128 - n; + if(n > mcb_read) { + n = mcb_read; + } + mcb_read -= n; + while(n-- > 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + } + } else { + n = ((ibytes + 127) / 128) * 128; + if(n > mcb_read) { + n = mcb_read; + } + mcb_read -= n; + while(n-- > 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + } + } +} + diff --git a/macunpack/mcb.o b/macunpack/mcb.o new file mode 100644 index 0000000000000000000000000000000000000000..24ec93121da5434510a29b51105992eb9083699f GIT binary patch literal 5808 zcmbuCdu&rx9LG;v9%Di~0bvU21vcDp)WJX=VX$s&Tufm+4H4newYRKpZO84cW10x0 zLRLmm;~#>WNTPoj6E*yU1QXth|40a6#9;!c5y%iBJ_7QXzu)OO^v7Kj5HO$S1u%+te-sFT-HAhM3$|Gvm5X|rE z57B;9QZu~r64IV?YWkKm4#-S<>d1!F&l|hYh0QqQS$L-WOqv%qpMC99wJYbJ>T#rQ z^d>LKM%>`gr;!8LDsS$AW<49#;3;8|)gTS2!4v9??qo~XBiN_%!Fh5L?8SfVY|hO0yl=U0+47}o>WTuBsiyy$ zpFSN@yZV)uK@ZjR+>+u+2h)5F)C^BNdxpC@hdb2NL5Ets5sZ?*dG;)Ir2d(+cMg<1 zjVC(!7}U(GPBk+X5Zj9ppF+=`y2T$m%)+nho~ucnzuQ^2_!wUqoMX9um12o=UZTdc z`FzgI^ZGb&x_lLgKhs*`hUR?x`e7-3HRtKim?guYs$Nw6ovX?&Pp%9zP_TSK`oe!G zLTXiZKO}={>Zr1EmG4F0D&OjR4`)HXuJpX0>qE~@lK)VSz?s)A!{-62^k|#e!4}4q zU_9Dp=!rxm9%G9PJsL2RhOX2%HWac!a|32zrot+eB?%)4886NxW3fO~uO3^P7+ay3 z9c_Ab=@jpjM1>Man$2-TmO|iLUD_I|Pz-R!9Aoq9>Siis^A;{ISEhNZyp>#yvEd?h zyt0Hj))zTO4IWtVChWgr;G;#|I^4uQcTvjOSm-YBJ+ugl(?#759BZw+XuGr4U7T^% zx|MDHeD1O>{eAAr)PT9}MJ}hqy~5{S)9PO2yjke3gi4=V0b_8gMKvL0lVH>R*!A9g z)vmlJFk>$G4Y*H37F-PXQQzQVgZjWx zob>IFA~=6|iC3xM)|Mx5Zl#PpBkW6v24<%SUSZ)g1m{n)rOw50mhKO;p;&Z3;-v-~ zzQBeDZTL$zJYmDv+we^`e2Wc#%Z9%Ld?@S)xj*>x0PKp5{d+cimks~KhJS9u_uKF< zZTMF<{97B|ZNtB};pc7muQvR;4Zm%}2f_i7Z@(4Ua25?Vd4m{h?M67#s`IR&2SUv2 zudBppGDedys={arMpH3*mc6VSP4R@z5@tv@45rQVH`e<6T4O`Q()wlEGGDE~USr{Q zBVy`|$6CZ>kyyBmY4aPkwYnK(`g%a|q^UI}!(rWEVcs_Mhnf0%lbJ>!mcT=vwMG&q z3+drVOxHLF#kEK*q{mDaZZje=GmOe{Egoy_U{JR%sT&sT!RsA^d|x2PJiJ?Z$eu%ZW-^9H zy5!k&2+wfFMi4H~6RSR+9~h92guiST&j}33QA_H-fDnR}>sib>zRRRNo*x)c<5Boa z-hmJT>d>aQl8 z>IaDq)sGTR^>+{*IzJx}{shdEoX=wxen&hPCkcO&*#9UvYAb~QN$hd|-w--?2_FMo zJ{JYJP!KSo`a=ar{juos`~NoK z`1LCL|1RNl-9IAwcos?f&xrka;Bwx+Ae_$gA;O;`_Q#2S8PPvY>`_Oy+il^p-HU|N zdH#cNI<7l{<2sfT{lVgji`8@=ju0H}@$8lT8BOeIyW<9!*yzrO(R3MK5*IjH4UY^C{9GCY|=1p`&%|H{RrjbpXWzNuB z173dX@bdeCw<(ceUL%eLG@s;!TM#WyXI}VZjp7x=8;hH|7d|H^^7{kWp_tyRg$=yC z{O_QE0v>q-EJ`(^JV?xstQNX7%qB4O#u=_@#fN z@UMiFhJ(T%zk_LzellGFl`>E5PFe>lDy_Cr;ZOHCnw}Bh@7kwB!K zqT_O0xc>MRF8$^DV}Gn|qr{s27&F!^`hj;0Ja?@AsA*k$K= '4' && ch <= '6') || ch == 'g') { + synced = 1; + } + } + } else if(ch == 'E') { + pithdr[2] = ch = getb(infp); + if(ch == 'n') { + pithdr[3] = ch = getb(infp); + if(ch == 'd') { + synced = 1; + } + } + } + if(!synced) { + (void)ungetc(ch, infp); + } + } + } + (void)fprintf(stderr, ", done.\n"); +#ifdef SCAN + do_idf("", PROTECTED); +#endif /* SCAN */ + continue; + default: + (void)fprintf(stderr, "File contains non PackIt info %.4s\n", + pithdr); +#ifdef SCAN + do_error("macunpack: File contains non PackIt info"); +#endif /* SCAN */ + exit(1); + } + bytes_read = 0; + if(pithdr[3] == '4') { + read_tree(); + decode = huffman; + } else { + decode = nocomp; + } + if(pit_filehdr(&filehdr, decode) == -1) { + (void)fprintf(stderr, "Can't read file header\n"); +#ifdef SCAN + do_error("macunpack: Can't read file header"); +#endif /* SCAN */ + exit(1); + } + bytes_written = filehdr.rlen + filehdr.dlen; + start_info(info, filehdr.rlen, filehdr.dlen); + start_data(); + pit_wrfile(filehdr.dlen, decode); + data_crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.dlen); + start_rsrc(); + pit_wrfile(filehdr.rlen, decode); + data_crc = (*updcrc)(data_crc, out_buffer, filehdr.rlen); + if(decode == nocomp) { + crc = getb(infp); + crc = (crc << 8) | getb(infp); + } else { + crc = (getihuffbyte() & BYTEMASK) | + ((getihuffbyte() & BYTEMASK) << 8); + } + if(crc != data_crc) { + (void)fprintf(stderr, + "CRC error in file: need 0x%04x, got 0x%04x\n", + (int)crc, (int)data_crc); +#ifdef SCAN + do_error("macunpack: CRC error in file"); +#endif /* SCAN */ + exit(1); + } + if(verbose) { + if(decode == nocomp) { + (void)fprintf(stderr, "\tNo compression"); + } else { + (void)fprintf(stderr, "\tHuffman compressed (%4.1f%%)", + 100.0 * bytes_read / bytes_written); + } + } + if(write_it) { + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } + } +} + +static int pit_filehdr(f, compr) +struct pit_header *f; +int compr; +{ + register int i; + unsigned long crc; + int n; + char hdr[HDRBYTES]; + char ftype[5], fauth[5]; + + for(i = 0; i < INFOBYTES; i++) + info[i] = '\0'; + + if(compr == huffman) { + for(i = 0; i < HDRBYTES; i++) { + hdr[i] = getihuffbyte(); + } + } else { + if(fread(hdr, 1, HDRBYTES, infp) != HDRBYTES) { + return -1; + } + } + crc = INIT_CRC; + crc = (*updcrc)(crc, hdr, HDRBYTES - 2); + + f->hdrCRC = get2(hdr + H_HDRCRC); + if(f->hdrCRC != crc) { + (void)fprintf(stderr, + "\tHeader CRC mismatch: got 0x%04x, need 0x%04x\n", + f->hdrCRC & WORDMASK, (int)crc); + return -1; + } + + n = hdr[H_NLENOFF] & BYTEMASK; + if(n > H_NAMELEN) { + n = H_NAMELEN; + } + info[I_NAMEOFF] = n; + copy(info + I_NAMEOFF + 1, hdr + H_NAMEOFF, n); + transname(hdr + H_NAMEOFF, text, n); + text[n] = '\0'; + + f->rlen = get4(hdr + H_RLENOFF); + f->dlen = get4(hdr + H_DLENOFF); + + write_it = 1; + if(list) { + transname(hdr + H_TYPEOFF, ftype, 4); + transname(hdr + H_AUTHOFF, fauth, 4); + do_indent(indent); + (void)fprintf(stderr, + "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld", + text, ftype, fauth, (long)f->dlen, (long)f->rlen); + if(info_only) { + write_it = 0; + } + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + } + + + if(write_it) { + define_name(text); + + copy(info + I_TYPEOFF, hdr + H_TYPEOFF, 4); + copy(info + I_AUTHOFF, hdr + H_AUTHOFF, 4); + copy(info + I_FLAGOFF, hdr + H_FLAGOFF, 2); + copy(info + I_LOCKOFF, hdr + H_LOCKOFF, 2); + copy(info + I_DLENOFF, hdr + H_DLENOFF, 4); + copy(info + I_RLENOFF, hdr + H_RLENOFF, 4); + copy(info + I_CTIMOFF, hdr + H_CTIMOFF, 4); + copy(info + I_MTIMOFF, hdr + H_MTIMOFF, 4); + } + return 1; +} + +static void pit_wrfile(bytes, type) +unsigned long bytes; +int type; +{ + if(bytes == 0) { + return; + } + switch(type) { + case nocomp: + pit_nocomp(bytes); + break; + case huffman: + pit_huffman(bytes); + } +} + +/*---------------------------------------------------------------------------*/ +/* No compression */ +/*---------------------------------------------------------------------------*/ +static void pit_nocomp(ibytes) +unsigned long ibytes; +{ + int n; + + n = fread(out_buffer, 1, (int)ibytes, infp); + if(n != ibytes) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } +} + +/*---------------------------------------------------------------------------*/ +/* Huffman compression */ +/*---------------------------------------------------------------------------*/ +static void pit_huffman(obytes) +unsigned long obytes; +{ + de_huffman(obytes); +} +#else /* PIT */ +int pit; /* keep lint and some compilers happy */ +#endif /* PIT */ + diff --git a/macunpack/pit.h b/macunpack/pit.h new file mode 100755 index 0000000..f47caeb --- /dev/null +++ b/macunpack/pit.h @@ -0,0 +1,32 @@ +#define H_NAMELEN 63 + +#define H_NLENOFF 0 +#define H_NAMEOFF 1 +#define H_TYPEOFF 64 +#define H_AUTHOFF 68 +#define H_FLAGOFF 72 +#define H_LOCKOFF 74 +#define H_DLENOFF 76 +#define H_RLENOFF 80 +#define H_CTIMOFF 84 +#define H_MTIMOFF 88 +#define H_HDRCRC 92 +#define HDRBYTES 94 + +struct pit_header { /* Packit file header (92 bytes) */ + unsigned char nlen; /* number of characters in packed file name */ + char name[63]; /* name of packed file */ + char type[4]; /* file type */ + char auth[4]; /* file creator */ + unsigned short flags; /* file flags (?) */ + unsigned short lock; /* unknown */ + unsigned long dlen; /* number of bytes in data fork */ + unsigned long rlen; /* number of bytes in resource fork */ + unsigned long ctim; /* file creation time */ + unsigned long mtim; /* file modified time */ + unsigned short hdrCRC; /* CRC */ +}; + +#define nocomp 0 +#define huffman 1 + diff --git a/macunpack/pit.o b/macunpack/pit.o new file mode 100644 index 0000000000000000000000000000000000000000..032b63d8ea5df5c9674a16b67f5c95ed641c3690 GIT binary patch literal 9584 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 literal 0 HcmV?d00001 diff --git a/macunpack/sit.c b/macunpack/sit.c new file mode 100755 index 0000000..88d61cd --- /dev/null +++ b/macunpack/sit.c @@ -0,0 +1,847 @@ +#include "macunpack.h" +#ifdef SIT +#include "globals.h" +#include "sit.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" + +extern void de_compress(); +extern void core_compress(); +extern void de_huffman(); +extern void de_huffman_end(); +extern void read_tree(); +extern void set_huffman(); +extern void de_lzah(); +extern unsigned char (*lzah_getbyte)(); + +typedef struct methodinfo { + char *name; + int number; +}; + +static struct methodinfo methods[] = { + {"NoComp", nocomp}, + {"RLE", rle}, + {"LZC", lzc}, + {"Huffman", huffman}, + {"LZAH", lzah}, + {"FixHuf", fixhuf}, + {"MW", mw}, +}; +static int sit_nodeptr; + +static int readsithdr(); +static int sit_filehdr(); +static int sit_valid(); +static int sit_checkm(); +static char *sit_methname(); +static void sit_folder(); +static void sit_unstuff(); +static void sit_wrfile(); +static void sit_skip(); +static void sit_nocomp(); +static void sit_rle(); +static void sit_lzc(); +static void sit_huffman(); +static void sit_lzah(); +static unsigned char sit_getbyte(); +static void sit_fixhuf(); +static void sit_dosplit(); +static void sit_mw(); +static void sit_mw_out(); +static int sit_mw_in(); + +static short code6[258] = { + 1024, 512, 256, 256, 256, 256, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 8, 8, 16, 16, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 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, 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, 1, 1, + 1, 1}; +static char sit_buffer[32768]; +static short sit_dict[16385]; +static unsigned long sit_avail; +static int sit_bits_avail; + +void sit() +{ + struct sitHdr sithdr; + struct fileHdr filehdr; + int i; + + set_huffman(HUFF_BE); + core_compress((char *)NULL); + updcrc = arc_updcrc; + crcinit = arc_crcinit; + if(readsithdr(&sithdr) == 0) { + (void)fprintf(stderr, "Can't read file header\n"); +#ifdef SCAN + do_error("macunpack: Can't read file header"); +#endif /* SCAN */ + exit(1); + } + + for(i = 0; i < sithdr.numFiles; i++) { + if(sit_filehdr(&filehdr, 0) == -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(!sit_valid(filehdr)) { + continue; + } + if(filehdr.compRMethod == sfolder) { + sit_folder(text); + } else { + sit_unstuff(filehdr); + } + } +} + +static int readsithdr(s) +struct sitHdr *s; +{ + char temp[SITHDRSIZE]; + + if(fread(temp, 1, SITHDRSIZE, infp) != SITHDRSIZE) { + return 0; + } + + if(strncmp(temp + S_SIGNATURE, "SIT!", 4) != 0 || + strncmp(temp + S_SIGNATURE2, "rLau", 4) != 0) { + (void)fprintf(stderr, "Not a StuffIt file\n"); + return 0; + } + + s->numFiles = get2(temp + S_NUMFILES); + s->arcLength = get4(temp + S_ARCLENGTH); + + return 1; +} + +static int sit_filehdr(f, skip) +struct fileHdr *f; +int skip; +{ + register int i; + unsigned long crc; + int n; + char hdr[FILEHDRSIZE]; + char ftype[5], fauth[5]; + + for(i = 0; i < INFOBYTES; i++) { + info[i] = '\0'; + } + if(fread(hdr, 1, FILEHDRSIZE, infp) != FILEHDRSIZE) { + (void)fprintf(stderr, "Can't read file header\n"); + return -1; + } + crc = INIT_CRC; + crc = (*updcrc)(crc, hdr, FILEHDRSIZE - 2); + + f->hdrCRC = get2(hdr + F_HDRCRC); + if(f->hdrCRC != crc) { + (void)fprintf(stderr, "Header CRC mismatch: got 0x%04x, need 0x%04x\n", + f->hdrCRC & WORDMASK, (int)crc); + return -1; + } + + 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->compRMethod = hdr[F_COMPRMETHOD]; + f->compDMethod = hdr[F_COMPDMETHOD]; + 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->rsrcCRC = get2(hdr + F_RSRCCRC); + f->dataCRC = get2(hdr + F_DATACRC); + + write_it = !skip; + if(list && !skip) { + if(f->compRMethod != efolder) { + do_indent(indent); + } + if(f->compRMethod == sfolder) { + (void)fprintf(stderr, "folder=\"%s\"", text); + } else if(f->compRMethod != efolder) { + 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(f->compRMethod != efolder) { + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + } + } + + if(write_it) { + define_name(text); + + if(f->compRMethod != sfolder) { + 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 int sit_valid(f) +struct fileHdr f; +{ + int fr = f.compRMethod, fd = f.compDMethod; + + if(fr == sfolder || fr == efolder) { + return 1; + } + if((fr & prot) || (fd & prot)) { + (void)fprintf(stderr, "\tFile is password protected"); +#ifdef SCAN + do_idf("", PROTECTED); +#endif /* SCAN */ + } else if(fr >= prot || fd >= prot) { + (void)fprintf(stderr, "\tUnknown stuffit flags: %x %x", fr, fd); +#ifdef SCAN + do_idf("", UNKNOWN); +#endif /* SCAN */ + } else if(((1 << fr) & sknown) && ((1 << fd) & sknown)) { + if(sit_checkm(fr) && sit_checkm(fd)) { + return 1; + } + if(!sit_checkm(fr)) { + (void)fprintf(stderr, "\tMethod \"%s\" not implemented", + sit_methname(fr)); + } else { + (void)fprintf(stderr, "\tMethod \"%s\" not implemented", + sit_methname(fd)); + } +#ifdef SCAN + do_idf("", UNKNOWN); +#endif /* SCAN */ + } else { + (void)fprintf(stderr, "\tUnknown compression methods: %x %x", fr, fd); +#ifdef SCAN + do_idf("", UNKNOWN); +#endif /* SCAN */ + } + (void)fprintf(stderr, ", skipping file.\n"); + sit_skip(f.compRLength); + sit_skip(f.compDLength); + return 0; +} + +static int sit_checkm(f) +int f; +{ + switch(f) { + case nocomp: + return 1; + case rle: + return 1; + case lzc: + return 1; + case huffman: + return 1; + case lzah: + return 1; + case fixhuf: + return 1; + case mw: + return 1; + default: + return 0; + } + /* NOTREACHED */ +} + +static char *sit_methname(n) +int n; +{ +int i, nmeths; + nmeths = sizeof(methods) / sizeof(struct methodinfo); + for(i = 0; i < nmeths; i++) { + if(methods[i].number == n) { + return methods[i].name; + } + } + return NULL; +} + +static void sit_folder(name) +char *name; +{ + int i, recurse; + char loc_name[64]; + struct fileHdr filehdr; + + for(i = 0; i < 64; i++) { + loc_name[i] = name[i]; + } + if(write_it || info_only) { + if(write_it) { + do_mkdir(text, info); + } + indent++; + while(1) { + if(sit_filehdr(&filehdr, 0) == -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(!sit_valid(filehdr)) { + continue; + } + if(filehdr.compRMethod == sfolder) { + sit_folder(text); + } else if(filehdr.compRMethod == efolder) { + break; + } else { + sit_unstuff(filehdr); + } + } + if(write_it) { + enddir(); + } + indent--; + if(list) { + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name); + } + } else { + recurse = 0; + while(1) { + if(sit_filehdr(&filehdr, 1) == -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.compRMethod == sfolder) { + recurse++; + } else if(filehdr.compRMethod == efolder) { + recurse--; + if(recurse < 0) { + break; + } + } else { + sit_skip(filehdr.compRLength); + sit_skip(filehdr.compDLength); + } + } + } +} + +static void sit_unstuff(filehdr) +struct fileHdr filehdr; +{ + unsigned long crc; + + if(write_it) { + start_info(info, filehdr.rsrcLength, filehdr.dataLength); + } + if(verbose) { + (void)fprintf(stderr, "\tRsrc: "); + } + if(write_it) { + start_rsrc(); + } + sit_wrfile(filehdr.compRLength, filehdr.rsrcLength, filehdr.compRMethod); + if(write_it) { + crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.rsrcLength); + if(filehdr.rsrcCRC != crc) { + (void)fprintf(stderr, + "CRC error on resource fork: need 0x%04x, got 0x%04x\n", + filehdr.rsrcCRC, (int)crc); +#ifdef SCAN + do_error("macunpack: CRC error on resource fork"); +#endif /* SCAN */ + exit(1); + } + } + if(verbose) { + (void)fprintf(stderr, ", Data: "); + } + if(write_it) { + start_data(); + } + sit_wrfile(filehdr.compDLength, filehdr.dataLength, filehdr.compDMethod); + if(write_it) { + crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.dataLength); + if(filehdr.dataCRC != crc) { + (void)fprintf(stderr, + "CRC error on data fork: need 0x%04x, got 0x%04x\n", + filehdr.dataCRC, (int)crc); +#ifdef SCAN + do_error("macunpack: CRC error on data fork"); +#endif /* SCAN */ + exit(1); + } + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } +} + +static void sit_wrfile(ibytes, obytes, type) +unsigned long ibytes, obytes; +unsigned char type; +{ + if(ibytes == 0) { + if(verbose) { + (void)fprintf(stderr, "empty"); + } + return; + } + switch(type) { + case nocomp: /* no compression */ + if(verbose) { + (void)fprintf(stderr, "No compression"); + } + if(write_it) { + sit_nocomp(ibytes); + } else { + sit_skip(ibytes); + } + break; + case rle: /* run length encoding */ + if(verbose) { + (void)fprintf(stderr, + "RLE compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_rle(ibytes); + } else { + sit_skip(ibytes); + } + break; + case lzc: /* LZC compression */ + if(verbose) { + (void)fprintf(stderr, + "LZC compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_lzc(ibytes); + } else { + sit_skip(ibytes); + } + break; + case huffman: /* Huffman compression */ + if(verbose) { + (void)fprintf(stderr, + "Huffman compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_huffman(obytes); + } else { + sit_skip(ibytes); + } + break; + case lzah: /* LZAH compression */ + if(verbose) { + (void)fprintf(stderr, + "LZAH compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_lzah(obytes); + } else { + sit_skip(ibytes); + } + break; + case fixhuf: /* FixHuf compression */ + if(verbose) { + (void)fprintf(stderr, + "FixHuf compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_fixhuf(ibytes); + } else { + sit_skip(ibytes); + } + break; + case mw: /* MW compression */ + if(verbose) { + (void)fprintf(stderr, + "MW compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + sit_mw(ibytes); + } else { + sit_skip(ibytes); + } + break; + default: + (void)fprintf(stderr, "Unknown compression method %2x\n", type); +#ifdef SCAN + do_idf("", UNKNOWN); +#endif /* SCAN */ + exit(1); + } +} + +/* skip stuffit file */ +static void sit_skip(ibytes) +unsigned long ibytes; +{ + while(ibytes != 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } + ibytes--; + } +} + +/*---------------------------------------------------------------------------*/ +/* Method 0: No compression */ +/*---------------------------------------------------------------------------*/ +static void sit_nocomp(ibytes) +unsigned long ibytes; +{ + int n; + + n = fread(out_buffer, 1, (int)ibytes, infp); + if(n != ibytes) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("macunpack: Premature EOF"); +#endif /* SCAN */ + exit(1); + } +} + +/*---------------------------------------------------------------------------*/ +/* Method 1: Run length encoding */ +/*---------------------------------------------------------------------------*/ +static void sit_rle(ibytes) +unsigned long ibytes; +{ + int ch, lastch, n, i; + + while(ibytes != 0) { + ch = getb(infp) & BYTEMASK; + ibytes--; + if(ch == ESC) { + n = (getb(infp) & BYTEMASK) - 1; + ibytes--; + if(n < 0) { + *out_ptr++ = ESC; + lastch = ESC; + n = 1; + } else { + for(i = 0; i < n; i++) { + *out_ptr++ = lastch; + } + } + } else { + *out_ptr++ = ch; + lastch = ch; + } + } +} + +/*---------------------------------------------------------------------------*/ +/* Method 2: LZC compressed */ +/*---------------------------------------------------------------------------*/ +static void sit_lzc(ibytes) +unsigned long ibytes; +{ + de_compress(ibytes, 14); +} + +/*---------------------------------------------------------------------------*/ +/* Method 3: Huffman compressed */ +/*---------------------------------------------------------------------------*/ +static void sit_huffman(obytes) +unsigned long obytes; +{ + read_tree(); + de_huffman(obytes); +} + +/*---------------------------------------------------------------------------*/ +/* Method 5: LZ compression plus adaptive Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void sit_lzah(obytes) +unsigned long obytes; +{ + lzah_getbyte = sit_getbyte; + de_lzah(obytes); +} + +static unsigned char sit_getbyte() +{ + return getb(infp); +} + +/*---------------------------------------------------------------------------*/ +/* Method 6: Compression with a fixed Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void sit_fixhuf(ibytes) +unsigned long ibytes; +{ + int i, sum, codes, sym, num; + char byte_int[4], byte_short[2]; + long size; + int sign; + char *tmp_ptr, *ptr, *end_ptr; + + sum = 0; + for(i = 0; i < 258; i++) { + sum += code6[i]; + nodelist[i + 1].flag = 1; + } + sit_nodeptr = 258; + sit_dosplit(0, sum, 1, 258); + while(ibytes > 0) { + if(fread(byte_int, 1, 4, infp) != 4) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("Premature EOF"); +#endif /* SCAN */ + exit(1); + } + ibytes -= 4; + size = (long)get4(byte_int); + sign = 0; + if(size < 0) { + size = - size; + sign = 1; + } + size -= 4; + if(sign) { + ibytes -= size; + if(fread(sit_buffer, 1, (int)size, infp) != size) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("Premature EOF"); +#endif /* SCAN */ + exit(1); + } + } else { + ibytes -= size; + if(fread(byte_int, 1, 4, infp) != 4) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("Premature EOF"); +#endif /* SCAN */ + exit(1); + } + size -= 4; + if(fread(byte_short, 1, 2, infp) != 2) { + (void)fprintf(stderr, "Premature EOF\n"); +#ifdef SCAN + do_error("Premature EOF"); +#endif /* SCAN */ + exit(1); + } + size -= 2; + codes = get2(byte_short); + for(i = 1; i <= codes; i++) { + nodelist[i].byte = getb(infp); + } + size -= codes; + clrhuff(); + nodelist[257].byte = 0x100; + nodelist[258].byte = 0x100; + tmp_ptr = out_ptr; + out_ptr = &(sit_buffer[0]); + bytesread = 0; + de_huffman_end(0x100); + while(bytesread < size) { + (void)getb(infp); + bytesread++; + } + size = get4(byte_int); + out_ptr = tmp_ptr; + } + ptr = sit_buffer; + end_ptr = ptr + size; + while(ptr < end_ptr) { + num = *ptr++ & BYTEMASK; + if(num < 0x80) { + while(num-- >= 0) { + *out_ptr++ = *ptr++; + } + } else if(num != 0x80) { + sym = *ptr++; + while(num++ <= 0x100) { + *out_ptr++ = sym; + } + } + } + } +} + +static void sit_dosplit(ptr, sum, low, upp) +int ptr, sum, low, upp; +{ + int i, locsum; + + sum = sum / 2; + locsum = 0; + i = low; + while(locsum < sum) { + locsum += code6[i++ - 1]; + } + if(low == i - 1) { + nodelist[ptr].zero = nodelist + low; + } else { + nodelist[ptr].zero = nodelist + ++sit_nodeptr; + sit_dosplit(sit_nodeptr, sum, low, i - 1); + } + if(upp == i) { + nodelist[ptr].one = nodelist + upp; + } else { + nodelist[ptr].one = nodelist + ++sit_nodeptr; + sit_dosplit(sit_nodeptr, sum, i, upp); + } +} + +/*---------------------------------------------------------------------------*/ +/* Method 8: Compression with a MW encoding */ +/*---------------------------------------------------------------------------*/ +static void sit_mw(ibytes) +unsigned long ibytes; +{ + int ptr; + int max, max1, bits; + char *out_buf; + + out_buf = out_buffer; + sit_bits_avail = 0; + sit_avail = 0; +start_over: + max = 256; + max1 = max + max; + bits = 9; + ptr = sit_mw_in(bits, &ibytes); + if(ptr == max) { + goto start_over; + } + if(ptr > max || ptr < 0) { + out_buffer = out_buf; + return; + } + sit_dict[255] = ptr; + sit_mw_out(ptr); + while(1) { + ptr = sit_mw_in(bits, &ibytes); + if(ptr == max) { + goto start_over; + } + if(ptr > max || ptr < 0) { + out_buffer = out_buf; + return; + } + sit_dict[max++] = ptr; + if(max == max1) { + max1 <<= 1; + bits++; + } + sit_mw_out(ptr); + } +} + +static void sit_mw_out(ptr) +int ptr; +{ + int stack_ptr; + int stack[16384]; + + stack_ptr = 1; + stack[0] = ptr; + while(stack_ptr) { + ptr = stack[--stack_ptr]; + while(ptr >= 256) { + stack[stack_ptr++] = sit_dict[ptr]; + ptr = sit_dict[ptr - 1]; + } + *out_buffer++ = ptr; + } +} + +static int sit_mw_in(bits, ibytes) +int bits; +unsigned long *ibytes; +{ + int res, res1; + + while(bits > sit_bits_avail) { + if(*ibytes == 0) { + return -1; + } + (*ibytes)--; + sit_avail += (getb(infp) & BYTEMASK) << sit_bits_avail; + sit_bits_avail += 8; + } + res1 = sit_avail >> bits; + res = sit_avail ^ (res1 << bits); + sit_avail = res1; + sit_bits_avail -= bits; + return res; +} + +#else /* SIT */ +int sit; /* keep lint and some compilers happy */ +#endif /* SIT */ diff --git a/macunpack/sit.h b/macunpack/sit.h new file mode 100755 index 0000000..383417b --- /dev/null +++ b/macunpack/sit.h @@ -0,0 +1,95 @@ +#define S_SIGNATURE 0 +#define S_NUMFILES 4 +#define S_ARCLENGTH 6 +#define S_SIGNATURE2 10 +#define S_VERSION 14 +#define SITHDRSIZE 22 + +#define F_COMPRMETHOD 0 +#define F_COMPDMETHOD 1 +#define F_FNAME 2 +#define F_FTYPE 66 +#define F_CREATOR 70 +#define F_FNDRFLAGS 74 +#define F_CREATIONDATE 76 +#define F_MODDATE 80 +#define F_RSRCLENGTH 84 +#define F_DATALENGTH 88 +#define F_COMPRLENGTH 92 +#define F_COMPDLENGTH 96 +#define F_RSRCCRC 100 +#define F_DATACRC 102 +#define F_HDRCRC 110 +#define FILEHDRSIZE 112 + +typedef long OSType; + +typedef struct sitHdr { /* 22 bytes */ + OSType signature; /* = 'SIT!' -- for verification */ + unsigned short numFiles; /* number of files in archive */ + unsigned long arcLength; /* length of entire archive incl. + hdr. -- for verification */ + OSType signature2; /* = 'rLau' -- for verification */ + unsigned char version; /* version number */ + char reserved[7]; +}; + +typedef struct fileHdr { /* 112 bytes */ + unsigned char compRMethod; /* rsrc fork compression method */ + unsigned char compDMethod; /* data fork compression method */ + unsigned char fName[64]; /* a STR63 */ + OSType fType; /* file type */ + OSType fCreator; /* er... */ + unsigned short FndrFlags; /* copy of Finder flags. For our + purposes, we can clear: + busy,onDesk */ + unsigned long creationDate; + unsigned long modDate; /* !restored-compat w/backup prgms */ + unsigned long rsrcLength; /* decompressed lengths */ + unsigned long dataLength; + unsigned long compRLength; /* compressed lengths */ + unsigned long compDLength; + unsigned short rsrcCRC; /* crc of rsrc fork */ + unsigned short dataCRC; /* crc of data fork */ + char reserved[6]; + unsigned short hdrCRC; /* crc of file header */ +}; + + +/* file format is: + sitArchiveHdr + file1Hdr + file1RsrcFork + file1DataFork + file2Hdr + file2RsrcFork + file2DataFork + . + . + . + fileNHdr + fileNRsrcFork + fileNDataFork +*/ + + + +/* compression methods */ +#define nocomp 0 /* just read each byte and write it to archive */ +#define rle 1 /* RLE compression */ +#define lzc 2 /* LZC compression */ +#define huffman 3 /* Huffman compression */ +#define lzah 5 /* LZ with adaptive Huffman */ +#define fixhuf 6 /* Fixed Huffman table */ +#define mw 8 /* Miller-Wegman encoding */ +/* this bit says whether the file is protected or not */ +#define prot 16 /* password protected bit */ +/* rsrc & data compress are identical here: */ +#define sfolder 32 /* start of folder */ +#define efolder 33 /* end of folder */ +#define sknown 0x16f /* known compression methods */ + +/* all other numbers are reserved */ + +#define ESC 0x90 /* repeat packing escape */ + diff --git a/macunpack/sit.o b/macunpack/sit.o new file mode 100644 index 0000000000000000000000000000000000000000..eba74cbd6a20d581b1bd921feb3fe36f76d9049f GIT binary patch literal 23664 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

cykkQ5yC zOoU77xr4}0B3zy=pgiscr2H152m6fVdo1{S7QDxT%lCn~zD}`)H}i3Vqq-@?9yj4r zfy0+|EX*ey^i2Rv^Zz7!Pe~ReAJ-YPg8$^Bv;qMdq znS`H;hCsj@ZLfNqep$oZ25E`lHJ?X5Hdr+cBJ#X zDmdz&50}(`E|I7Gb`0TX6L}ZWL+6u9!qN9q|8$~<+OvSjFCg-Zi9FgW^&|w7Per|t4M;pY+gt%TEd*+ulzb~&p6GD9%;li`F@J6(dKomayp z?S$X!uz>s;!mEiMYX41ypHJjh5l-z-5dGBt{Y0Mn`4Hh#K);-q(u7}2${iw(;?aIT z;pYpE{-O4}2_H`6ClOBVpGEXj`+rO1sr?TVPVIk^aGVd9!G&Qv;kYjw#;BrvKseTI ztk@@>GlUCZy^vS5@aOS_)B4UQd<2NfcE5&jAK}*vj=E`mAGDBvf^a&2ZY6r?{JD#8 zI)5G@dgwgxF_E7@>>P3;JU}q}p@?uFq|5q_Ae`D+A~@D}8j&AMIJNUKqKE3ANjTL% zkLa03^!o{?`fG?Ds{cm9ss3d|&orWcHQ`kM?L-fqKku^OuUhcGS@1kN7y$v>g|_1< zf}@{lJ6=TiWJr_krCI2?lE_m%i!J0=TFBo+coix4F`@^@qqL`ka9Xcth#vZ$>L&a; zqUTGZhmH3lNQ98D@;mws`AETs5>DIeR15APyc+b#b^d6<(f@HxWK7t%kknK&e|aH9A! z3fl$cPsIp?G7~?YW5q|f6PWZvi0}&tuO*z0_a%a3nbV2<<3yg;Ylj6dISDdDK(jA| zOWJc0;k4Y#1UHvEnQ%IvOedV~`&x*8+Ac}LX*;eboXT$}oYr?2;gzIbuM+Mh{1D-^ z+|LN7<(_#mWQKr#qx?d`sXgU{Q+vh}PVJd1IQlsNmu#0Si9EG)DdBD+A0v8#gd0Sj z>iHSrwB7F`d?eBH0MS2<@IMlH>YolGA0qNE68TYtzeYH<=N+Pl_WvV<(|-6F;Wb46 zU|eiLz;-NwOZvHxa9ZxEf@8bTa-D?Jaxb*dQ$hHDka9gl5A~;y$kX<^l5lG0V!}&_ z{zeP^_Yrxj=Mlooh@OoWdbSXGs^>+*%ZZ*>E%aO}7P{CjqltVK;Z*+&!OiV*Es-BX z^n?hfdKxVB7(^aTcEE+d^?NdS+Yb zxq-<4fY@`V1wTwU9lys3pGEW(;QwQSfc2UIm)w^nzK@i1H{7KkZXW3$Z9y(5U5`H<+^E}Z*?Rl4Q>W3qQV|``4KDFSV6FwE>rGG9E>o~0M zBBJMF!e0g zk*_Cu=zQKxIQ84DM9)~F=Rv|!Ep}6Ao-($&*eD79~XRqi9aFAz1qY(h5U6UzC-Y! zi9ap$EHd%ug}lJ*G!DB0{=N}|>_7O3e1qT)h+~j^li;$wB<~R1&7`yPI|Y~ik@C+9 zew|7FCBYqnOMi+-cJ_;L$>r~8mzm_{@8fryxcq(mVH20XkIxh3Oa1cq@gq%K{@%UW z#O3eT*PFQf{rYYbm%meAhXq2A<;vg5DJ9XRb$azexa$#qUnFCZP;GSy`>9k3`@K-f z!e~?}i8SB?ikFqZueazU{9KFW;Y>U*X}};^Qri%yuFd2LM0Lmkzk$O4`>B+`e+3Pd zz<-z;#eTsha)%cAYa;j?t#2tfKo7b|eC?Of>K3shVt$ng!kzL_!DO6M-5J6o8ZOcy zw4BB7*xxa)oM+{Hh~H@-&xMPIQF3CW5aQlgxg%tQx_^s8H;K)eu2(C5z^Z(A- zJiSfiNB`q1(Cq(eU|7D{e{Y`+5JDrrWj-C57?0rm*f(bWE ztTc-JEhfiGyQScr5b4i<-NJwQqCoVY9WI$)jvq`mmkmfcR*awUe;vj81D6#QaGCRC jo0v=l0{u@o)MiRF*B|woL|A?W7jF max) { + max = c; + } + } + for(i = k; i < 32; i++) { + nodelist[i + 1].flag = 1; + nodelist[i + 1].byte = i + 1; + table[i + 1].num = 0; + table[i + 1].next = 0; + } + k = 0; + for(i = 0; i <= max; i++) { + for(i1 = 1; i1 < 33; i1++) { + if(table[i1].num == i) { + table[k].next = i1; + k = i1; + } + } + } + stf_construct(32); + tmp_out_ptr = out_ptr; + out_ptr = length; + de_huffman((unsigned long)256); + out_ptr = tmp_out_ptr; + for(i = 1; i < 257; i++) { + table[i].num = 0x40000000 >> length[i - 1]; + nodelist[i].flag = 1; + nodelist[i].byte = i - 1; + table[i].next = 0; + } + k = 0; + for(i = 1; i < 0x40000000; i <<= 1) { + for(i1 = 1; i1 < 257; i1++) { + if(table[i1].num == i) { + table[k].next = i1; + k = i1; + } + } + } + stf_construct(256); + } + i = 0x1000 - offs; + offs = 0; + if(i > towrite - *num) { + i = towrite - *num; + } + de_huffman((unsigned long)i); + *num += i; + } +} + +static void stf_construct(n) +int n; +{ + int i, i1, i2, j1, k; + + j1 = n + 1; + i = table[0].next; + i1 = table[i].next; + while(table[i1].next != 0) { + k = table[i].num + table[i1].num; + table[j1].num = k; + nodelist[j1].flag = 0; + nodelist[j1].zero = nodelist + i; + nodelist[j1].one = nodelist + i1; + i2 = i1; + i = table[i2].next; + while(i != 0 && table[i].num <= k) { + i2 = i; + i = table[i].next; + } + table[j1].next = i; + table[i2].next = j1; + i = table[i1].next; + i1 = table[i].next; + j1++; + } + table[0].num = table[i].num + table[i1].num; + nodelist[0].flag = 0; + nodelist[0].zero = nodelist + i; + nodelist[0].one = nodelist + i1; +} +#else /* STF */ +int stf; /* keep lint and some compilers happy */ +#endif /* STF */ + diff --git a/macunpack/stf.h b/macunpack/stf.h new file mode 100755 index 0000000..5d5a9bd --- /dev/null +++ b/macunpack/stf.h @@ -0,0 +1,15 @@ +#define MAGIC "RTH" + +#define S_MAGIC 0 +#define S_FLENGTH 3 +#define S_RSRCLNGTH 3 /* + NAMELENGTH */ +#define S_DATALNGTH 7 /* + NAMELENGTH */ + +typedef struct fileHdr { + char magic[3]; + char flength; + char fname[32]; /* actually flength */ + unsigned long rsrcLength; + unsigned long dataLength; +}; + diff --git a/macunpack/stf.o b/macunpack/stf.o new file mode 100644 index 0000000000000000000000000000000000000000..2f3ffc0c5d2c9fcd1ccd803731c27c857a470869 GIT binary patch literal 7648 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 literal 0 HcmV?d00001 diff --git a/macunpack/zma.c b/macunpack/zma.c new file mode 100755 index 0000000..371d7eb --- /dev/null +++ b/macunpack/zma.c @@ -0,0 +1,389 @@ +#include "macunpack.h" +#ifdef ZMA +#include "globals.h" +#include "zma.h" +#include "crc.h" +#include "../fileio/machdr.h" +#include "../fileio/wrfile.h" +#include "../fileio/kind.h" +#include "../util/masks.h" +#include "../util/util.h" + +extern char *malloc(); +extern char *realloc(); +extern void de_lzh(); + +/* We do allow for possible backpointing, so we allocate the archive in core */ +static char *zma_archive; +static char *zma_current; +static char *zma_filestart; +static unsigned long zma_length; +static long zma_archlength; + +static int zma_filehdr(); +static void zma_folder(); +static void zma_mooz(); +static void zma_wrfile(); +static void zma_nocomp(); +static void zma_lzh(); + +void zma(start, length) + char *start; + unsigned long length; +{ + struct fileHdr filehdr; + int i, toread; + + if(length != 0) { + if(zma_archlength < length) { + if(zma_archlength == 0) { + zma_archive = malloc((unsigned)length); + } else { + zma_archive = realloc(zma_archive, (unsigned)length); + } + zma_archlength = length; + if(zma_archive == NULL) { + (void)fprintf(stderr, "Insufficient memory, aborting\n"); + exit(1); + } + } + if(fread(zma_archive, 1, (int)length, infp) != length) { + (void)fprintf(stderr, "Can't read archive.\n"); +#ifdef SCAN + do_error("macunpack: Can't read archive"); +#endif /* SCAN */ + exit(1); + } + zma_length = get4(zma_archive + ZMAHDRS + 1); + if(zma_length != length) { + (void)fprintf(stderr, "Archive length mismatch.\n"); +#ifdef SCAN + do_error("macunpack: Archive length mismatch"); +#endif /* SCAN */ + exit(1); + } + } else { + zma_length = get4(start + ZMAHDRS + 1); + if(zma_archlength < zma_length) { + if(zma_archlength == 0) { + zma_archive = malloc((unsigned)zma_length); + } else { + zma_archive = realloc(zma_archive, (unsigned)zma_length); + } + zma_archlength = zma_length; + if(zma_archive == NULL) { + (void)fprintf(stderr, "Insufficient memory, aborting\n"); + exit(1); + } + } + if(zma_archive == NULL) { + (void)fprintf(stderr, "Insufficient memory, aborting\n"); + exit(1); + } + for(i = 0; i <= ZMAHDRS2; i++) { + zma_archive[i] = start[i]; + } + toread = zma_length - ZMAHDRS2 - 1; + if(fread(zma_archive + ZMAHDRS2 + 1, 1, toread, infp) != toread) { + (void)fprintf(stderr, "Can't read archive.\n"); +#ifdef SCAN + do_error("macunpack: Can't read archive"); +#endif /* SCAN */ + exit(1); + } + } + /* Consistency checks */ + if(zma_archive[0] != 0) { + (void)fprintf(stderr, "Not a \"Zoom\" archive after all, aborting\n"); + exit(1); + } + if(strncmp(zma_archive + 1, ZMAHDR, ZMAHDRS)) { + (void)fprintf(stderr, "Not a \"Zoom\" archive after all, aborting\n"); + exit(1); + } + zma_current = zma_archive + 8; + updcrc = arc_updcrc; + crcinit = arc_crcinit; + while(zma_current != zma_archive) { + if(zma_filehdr(&filehdr, 0) == -1) { + (void)fprintf(stderr, "Can't find file header./n"); +#ifdef SCAN + do_error("macunpack: Can't find file header"); +#endif /* SCAN */ + exit(1); + } + zma_filestart = zma_current + filehdr.hlen; + if(filehdr.what == z_dir) { + zma_folder(filehdr); + } else { + zma_mooz(filehdr); + } + zma_current = zma_archive + filehdr.next; + } +} + +static int zma_filehdr(f, skip) +struct fileHdr *f; +int skip; +{ + register int i; + int n; + char ftype[5], fauth[5]; + + if(zma_current - zma_archive + Z_HDRSIZE > zma_length) { + return -1; + } + for(i = 0; i < INFOBYTES; i++) { + info[i] = '\0'; + } + + n = zma_current[Z_FNAME] & BYTEMASK; + if(n > F_NAMELEN) { + n = F_NAMELEN; + } + info[I_NAMEOFF] = n; + copy(info + I_NAMEOFF + 1, zma_current + Z_FNAME + 1, n); + transname(zma_current + Z_FNAME + 1, text, n); + + f->what = zma_current[Z_WHAT]; + f->rsrcLength = get4(zma_current + Z_URLEN); + f->dataLength = get4(zma_current + Z_UDLEN); + f->compRLength = get4(zma_current + Z_CRLEN); + f->compDLength = get4(zma_current + Z_CDLEN); + f->rsrcCRC = get2(zma_current + Z_RCRC); + f->dataCRC = get2(zma_current + Z_DCRC); + f->hlen = zma_current[Z_HLEN]; + f->next = get4(zma_current + Z_NEXT); + if(f->what == z_dir) { /* A hack */ + f->conts = get4(zma_current + Z_AUTH); + } + /* Set rsrc fork sizes correctly */ + f->rsrcLength -= f->dataLength; + f->compRLength -= f->compDLength; + + write_it = !skip; + if(f->what & 0x80) { + write_it = 0; + f->what = -f->what; + f->deleted = 1; + return 0; + } + f->deleted = 0; + if(list && !skip) { + do_indent(indent); + if(f->what == z_dir) { + (void)fprintf(stderr, "folder=\"%s\"", text); + } else { + transname(zma_current + Z_TYPE, ftype, 4); + transname(zma_current + Z_AUTH, 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); + } + switch(f->what) { + case z_plug: + (void)fputc('\n', stderr); + (void)fprintf(stderr, + "\tFile uses custom processing, cannot handle.\n"); + write_it = 0; + return 0; + case z_dir: + case z_file: + case z_plain: + break; + default: + (void)fputc('\n', stderr); + (void)fprintf(stderr, + "\tEh, do not understand this (%d); skipped.\n", f->what); + write_it = 0; + return 0; + } + + 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->what != z_dir) { + copy(info + I_TYPEOFF, zma_current + Z_TYPE, 4); + copy(info + I_AUTHOFF, zma_current + Z_AUTH, 4); + copy(info + I_FLAGOFF, zma_current + Z_FLAGS, 2); + copy(info + I_DLENOFF, zma_current + Z_UDLEN, 4); + put4(zma_current + Z_URLEN, f->rsrcLength); + copy(info + I_RLENOFF, zma_current + Z_URLEN, 4); + copy(info + I_CTIMOFF, zma_current + Z_MDATE, 4); + copy(info + I_MTIMOFF, zma_current + Z_MDATE, 4); + } + } + return 1; +} + +static void zma_folder(fhdr) +struct fileHdr fhdr; +{ + int i; + char loc_name[64]; + struct fileHdr filehdr; + + for(i = 0; i < 64; i++) { + loc_name[i] = text[i]; + } + zma_current = zma_archive + fhdr.conts; + if(write_it || info_only) { + if(write_it) { + do_mkdir(text, info); + } + indent++; + while(zma_current != zma_archive) { + if(zma_filehdr(&filehdr, 0) == -1) { + (void)fprintf(stderr, "Can't find file header.\n"); +#ifdef SCAN + do_error("macunpack: Can't find file header"); +#endif /* SCAN */ + exit(1); + } + zma_filestart = zma_current + filehdr.hlen; + if(filehdr.what == z_dir) { + zma_folder(filehdr); + } else { + zma_mooz(filehdr); + } + zma_current = zma_archive + filehdr.next; + } + if(write_it) { + enddir(); + } + indent--; + if(list) { + do_indent(indent); + (void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name); + } + } +} + +static void zma_mooz(filehdr) +struct fileHdr filehdr; +{ + unsigned long crc; + + if(write_it) { + start_info(info, filehdr.rsrcLength, filehdr.dataLength); + } + if(verbose) { + (void)fprintf(stderr, "\tData: "); + } + if(write_it) { + start_data(); + } + zma_wrfile(filehdr.compDLength, filehdr.dataLength, filehdr.what); + if(write_it) { + crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.dataLength); + if(filehdr.dataCRC != crc) { + (void)fprintf(stderr, + "CRC error on data fork: need 0x%04x, got 0x%04x\n", + (int)filehdr.dataCRC, (int)crc); +#ifdef SCAN + do_error("macunpack: CRC error on data fork"); +#endif /* SCAN */ + exit(1); + } + } + if(verbose) { + (void)fprintf(stderr, ", Rsrc: "); + } + if(write_it) { + start_rsrc(); + } + zma_wrfile(filehdr.compRLength, filehdr.rsrcLength, filehdr.what); + if(write_it) { + crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.rsrcLength); + if(filehdr.rsrcCRC != crc) { + (void)fprintf(stderr, + "CRC error on resource fork: need 0x%04x, got 0x%04x\n", + (int)filehdr.rsrcCRC, (int)crc); +#ifdef SCAN + do_error("macunpack: CRC error on resource fork"); +#endif /* SCAN */ + exit(1); + } + end_file(); + } + if(verbose) { + (void)fprintf(stderr, ".\n"); + } +} + +static void zma_wrfile(ibytes, obytes, type) +unsigned long ibytes, obytes; +char type; +{ + if(ibytes == 0) { + if(verbose) { + (void)fprintf(stderr, "empty"); + } + return; + } + switch(type) { + case z_plain: /* no compression */ + if(verbose) { + (void)fprintf(stderr, "No compression"); + } + if(write_it) { + zma_nocomp(ibytes); + } + break; + case z_file: /* lzh compression */ + if(verbose) { + (void)fprintf(stderr, + "LZH compressed (%4.1f%%)", 100.0 * ibytes / obytes); + } + if(write_it) { + zma_lzh(ibytes); + } + break; + default: + (void)fprintf(stderr, "Unknown compression method %2x\n", type); +#ifdef SCAN + do_idf("", UNKNOWN); +#endif /* SCAN */ + exit(1); + } +} + +/*---------------------------------------------------------------------------*/ +/* No compression */ +/*---------------------------------------------------------------------------*/ +static void zma_nocomp(ibytes) +unsigned long ibytes; +{ + int n = ibytes; + char *ptr = out_buffer; + + while(n-- > 0) { + *ptr++ = *zma_filestart++; + } +} + +/*---------------------------------------------------------------------------*/ +/* LZ compression plus Huffman encoding */ +/*---------------------------------------------------------------------------*/ +static void zma_lzh(ibytes) +unsigned long ibytes; +{ + /* Controlled by ibutes only */ + de_lzh((long)ibytes, (long)(-1), &zma_filestart, 13); +} +#else /* ZMA */ +int zma; /* keep lint and some compilers happy */ +#endif /* ZMA */ + diff --git a/macunpack/zma.h b/macunpack/zma.h new file mode 100755 index 0000000..04bfc9f --- /dev/null +++ b/macunpack/zma.h @@ -0,0 +1,53 @@ +#include "zmahdr.h" + +#define Z_HDRSIZE 78 + +#define Z_WHAT 0 /* What kind of data? */ +#define Z_HLEN 1 /* Header length */ +#define Z_BFLAGS 2 /* Boolean flags */ +#define Z_NEXT 4 /* Pointer to next entry */ +#define Z_CRLEN 8 /* Length compressed resource */ +#define Z_CDLEN 12 /* Length compressed data */ +#define Z_URLEN 16 /* Length uncompressed resource */ +#define Z_UDLEN 20 /* Length uncompressed data */ +#define Z_TYPE 24 /* File type */ +#define Z_AUTH 28 /* File creator */ +#define Z_CONTS 28 /* Directory contents pointer; overlayed */ +#define Z_MDATE 32 /* Date */ +#define Z_COMMENT 36 /* Comment offset, currently unused */ +#define Z_FLAGS 40 /* Finder flags */ +#define Z_DCRC 42 /* Data crc */ +#define Z_RCRC 44 /* Resource crc */ +#define Z_FNAME 46 /* File name length and name */ + +typedef struct fileHdr { /* 78 bytes */ + char deleted; /* Not in original, split off from: */ + char what; /* What kind? Negative if deleted */ + unsigned char hlen ; /* Header length */ + unsigned short boolFlags; /* Boolean flags */ + unsigned long next; /* Next entry */ + unsigned long compRLength; /* The compressed lengths. */ + unsigned long compDLength; /* For dirs, the second is # entries */ + unsigned long rsrcLength; /* The uncompressed lengths. */ + unsigned long dataLength; + unsigned long fType; /* file type */ + unsigned long fCreator; /* er... */ + unsigned long modDate; /* !restored-compat w/backup prgms */ + unsigned long comment; /* Comment offset */ + unsigned short FndrFlags; /* copy of Finder flags. For our + purposes, we can clear: + busy,onDesk */ + unsigned short dataCRC; /* Data fork crc */ + unsigned short rsrcCRC; /* Resource fork crc */ + unsigned char fName[32]; /* a STR32 */ + /* The following are overlayed in the original structure */ + unsigned long conts; /* Pointer to directory contents */ +}; + +/* zma types (see what) */ +#define z_noth 0 /* ??? */ +#define z_file 1 /* file is compressed */ +#define z_plain 2 /* file is uncompressed */ +#define z_dir 3 /* directory */ +#define z_plug 4 /* for plug in, not supported */ + diff --git a/macunpack/zma.o b/macunpack/zma.o new file mode 100644 index 0000000000000000000000000000000000000000..86d424d70966e3ec37ed3711a0f237fc85a41512 GIT binary patch literal 14976 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 DFrXMM literal 0 HcmV?d00001 diff --git a/macunpack/zmahdr.h b/macunpack/zmahdr.h new file mode 100755 index 0000000..c1acfc7 --- /dev/null +++ b/macunpack/zmahdr.h @@ -0,0 +1,4 @@ +#define ZMAHDR "\005\237\032" +#define ZMAHDRS 3 +#define ZMAHDRS2 7 + diff --git a/makefile b/makefile new file mode 100755 index 0000000..6a94a0e --- /dev/null +++ b/makefile @@ -0,0 +1,78 @@ +SHELL = /bin/sh +BINDIR = /ufs/dik/tmpbin +# Use the following flags on the CF macro definition as needed. +# +# -DBSD if you are on a BSD system +# +# -DTYPES_H if your system has /usr/include/sys/types.h +# +# -DDIRENT_H if your system has /usr/include/dirent.h +# +# -DTERMIOS_H if your system has /usr/include/sys/termios.h +# +# -DNODOT if you do not want to create files with an initial period +# +# -DLATIN1 if your system supports LATIN-1 and you want to use it +# +# Note you can use at most one of the following four! +# +# -DNOMKDIR if your system does not have the mkdir system call +# +# -DAUFS if you want to use an AUFS file system +# +# -DAUFSPLUS if you use CAP 6.0 and want to use times on files +# +# -DAPPLEDOUBLE if you want to be able to use an AppleDouble file system +# +CF = -DBSD -DTYPES_H -DDIRENT_H -DTERMIOS_H -DNODOT -DAPPLEDOUBLE + +all: + (cd crc; make CF='$(CF)') + (cd util; make CF='$(CF)') + (cd fileio; make CF='$(CF)') + (cd macunpack; make CF='$(CF)') + (cd hexbin; make CF='$(CF)') + (cd mixed; make CF='$(CF)') + (cd binhex; make CF='$(CF)') + (cd comm; make CF='$(CF)') + +clean: + (cd crc; make clean) + (cd util; make clean) + (cd fileio; make clean) + (cd macunpack; make clean) + (cd hexbin; make clean) + (cd mixed; make clean) + (cd binhex; make clean) + (cd comm; make clean) + +clobber: + (cd crc; make clean) + (cd util; make clean) + (cd fileio; make clean) + (cd macunpack; make clobber) + (cd hexbin; make clobber) + (cd mixed; make clobber) + (cd binhex; make clobber) + (cd comm; make clobber) + +lint: + (cd macunpack; make CF='$(CF)' lint) + (cd hexbin; make CF='$(CF)' lint) + (cd mixed; make CF='$(CF)' lint) + (cd binhex; make CF='$(CF)' lint) + (cd comm; make CF='$(CF)' lint) + +install: + cp macunpack/macunpack $(BINDIR)/. + cp hexbin/hexbin $(BINDIR)/. + cp mixed/macsave $(BINDIR)/. + cp mixed/macstream $(BINDIR)/. + cp binhex/binhex $(BINDIR)/. + cp comm/tomac $(BINDIR)/. + cp comm/frommac $(BINDIR)/. + +distr: + shar -a README makefile crc util fileio macunpack hexbin mixed binhex \ + comm doc man >macutil.shar + diff --git a/man/binhex.1 b/man/binhex.1 new file mode 100755 index 0000000..947ee9c --- /dev/null +++ b/man/binhex.1 @@ -0,0 +1,104 @@ +.TH BINHEX L "October 22, 1992" +.UC +.SH NAME +binhex \- Hexifies a series of files +.SH SYNOPSIS +.B binhex +[ +.B \- options +] [ files ] +.br +.SH DESCRIPTION +.I binhex +takes the files specified in +.I files +and hexifies them in BinHex 4.0 format on standard output +subject to the +.I options +specified. +If +.I files +also specifies directories they are followed recursively, and all files +found will be hexified. +If no +.I files +parameter is specified, binhex reads a MacBinary stream from standard +input and hexifies the files found; folder information is lost. +.SH OPTIONS +In the absence of any options, +.I binhex +takes the specified files and silently hexifies them to BinHex 4.0 +format, writing the result to standard output. +Directories named in +.I files +are followed recursively, all files found will be hexified. +Files are assumed to be in MacBinary format. +However, if the filename ends with .info the file is assumed to be +the info fork of a MacIntosh file split amongst more than one file. +In that case the files with .data and .rsrc extensions +are also read (if present). +Also, if the info fork is mentioned in the parameter list, the names +of data and resource forks can also be mentioned, but those will be +ignored (this is to allow wild-card expansion by the shell.) +Further, if some form of AppleShare is supported by the installed +program, and if the current directory, or one of the directories found +during recursive processing, is a directory in the format of the +supported version of AppleShare, those files will be handled according +to the properties of AppleShare. +.TP +.B \-r +No intelligent file-processing is performed; all files named are assumed +to be plain resource files, and are hexified as if they were +MacIntosh resource files with +creator "RSED" and type "RSRC", unless another creator and/or type are +specified. +.TP +.B \-d +No intelligent file-processing is performed; all files named are assumed +to be plain data files, and are hexified as if they were +MacIntosh data files with +creator "MACA" and type "TEXT", unless another creator and/or type are +specified. +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged. +.TP +.B \-U +Is a synonym for -u. +.TP +.B \-c creator +Defines the creator name to be used if one of the previous options is +specified. +.TP +.B \-t type +Defines the type name to be used if one of the previous options is +specified. +.TP +.B \-R +Do not use run-length encoding during the conversion. +This option may speed up the encoding a bit, but it is merely a +historical artifact. +.TP +.B \-l +List every file and directory processed. +.TP +.B \-i +Do not output files, give information only (implies -l.) +.TP +.B \-q +Ask the user for every file/directory whether it should be visited +(implies -l.) +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) diff --git a/man/frommac.1 b/man/frommac.1 new file mode 100755 index 0000000..1d435dc --- /dev/null +++ b/man/frommac.1 @@ -0,0 +1,99 @@ +.TH FROMMAC L "October 22, 1992" +.UC +.SH NAME +frommac \- Receive files from the Macintosh +.SH SYNOPSIS +.B frommac +[ +.B \- options +] +.br +.SH DESCRIPTION +.I frommac +receives files from the Macintosh and processes them +subject to the +.I options +specified. +.SH OPTIONS +In the absence of any options, +.I frommac +receives a single file and stores it +in MacBinary format, giving the output file ".bin" extensions and +placing it in the current working directory. +.TP +.B \-3 +Write files in fork format (.info, .data and .rsrc files.) +.TP +.B \-f +As -3, but empty data and rsrc files are not created. +.TP +.B \-r +Write resource forks only (.rsrc files.) +.TP +.B \-d +Write data forks only (.data files.) +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged, the filename extension +is .text. +.TP +.B \-U +As -u, but there is no filename extension. +.TP +.B \-a +Write files in AppleShare format. +This option is only valid if the program is compiled with support +for some form of AppleShare. +The current directory must be a valid AppleShare folder. +.TP +.B \-s +Write received files to standard output in MacBinary format. +.TP +.B \-l +List every file received. +.TP +.B \-m +Receive multiple files. +Entering ^X (CNTRL-X) after the last file will terminate the program. +.TP +.B \-x +Use the XMODEM protocol for transmission. +.TP +.B \-y +Use the YMODEM protocol for transmission (not yet supported.) +.TP +.B \-z +Use the ZMODEM protocol for transmission (not yet supported.) +.TP +.B \-o +Use the pre-beta version of XMODEM. +.TP +.B \-T +Allow for time-out detection during the protocol. +Normally you will not need this option because on occasion, when network +delays do occur, time-out detection interferes with a good transmission. +Also, when for some reason the connection is broken the program will +normally receive a hang-up signal and terminate. +However, in some situations it might be necessary to early detect time-outs +(because of communication loss or whatever, without loss of connection). +You should check whether use of this option has profits in your situation +or not. +Normally when transmission errors did occur entering a number of times +^X (CNTRL-X) will gracefully terminate the program. +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) +.sp 1 +Parts of the code are based on codes from: +Dave Johnson. diff --git a/man/hexbin.1 b/man/hexbin.1 new file mode 100755 index 0000000..04041cb --- /dev/null +++ b/man/hexbin.1 @@ -0,0 +1,106 @@ +.TH HEXBIN L "October 22, 1992" +.UC +.SH NAME +hexbin \- Macintosh file de-binhexer +.SH SYNOPSIS +.B hexbin +[ +.B \- options +] [ files ] +.br +.SH DESCRIPTION +.I hexbin +takes the text files specified in +.I files +(or standard input if none is specified) and converts them +subject to the +.I options +specified. +.SH OPTIONS +In the absence of any options, +.I hexbin +takes the specified files and silently converts them +into MacBinary format, giving the output files ".bin" extensions and +placing them in the current working directory. +.TP +.B \-3 +Write files in fork format (.info, .data and .rsrc files.) +.TP +.B \-f +As -3, but empty data and rsrc files are not created. +.TP +.B \-r +Write resource forks only (.rsrc files.) +.TP +.B \-d +Write data forks only (.data files.) +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged, the filename extension +is .text. +.TP +.B \-U +As -u, but there is no filename extension. +.TP +.B \-a +Write files in AppleShare format. +This option is only valid if the program is compiled with support +for some form of AppleShare. +The current directory must be a valid AppleShare folder. +.TP +.B \-s +Write extracted files to standard output in MacBinary format. +.TP +.B \-l +List every file extracted (and every directory/folder created etc.) +.TP +.B \-v +Like -l, but more verbose. +When this option is specified all lines skipped because they do not +belong to the hexified format are listed (implies -l.) +.TP +.B \-i +Do not convert, give information only (implies -l.) +.TP +.B \-c +Do not check whether the hexified lines have equal size. +Normally the hexifiers gives text files with equal length line size, +hexbin uses this in its heuristics to determine whether a line must +be skipped. +There are however hexified files that do not conform to that pattern. +If this option is specified hexbin will in general be unable to detect +whether a line is garbage or not, so you have to remove the garbage by +hand. +.TP +.B \-n name +Gives the Unix base file name for the converted files. +For files hexified with BinHex 4.0 or compatible hexifiers this flag +is not needed; hexbin will determine the Unix file name based on the +Mac file name. +For files in dl, hex or hcx format this parameter may be needed as +these formats do not include the Mac filename. +Normally hexbin will in those cases base the Unix file name on the +text file name, but that can be overruled with this parameter. +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) +.sp 1 +Parts of the code are based on codes from: +ahm (?), +Darin Adler, +Jim Budler, +Dave Johnson, +Dan LaLiberte, +Jeff Meyer, +Guido van Rossum. diff --git a/man/macsave.1 b/man/macsave.1 new file mode 100755 index 0000000..2e946ac --- /dev/null +++ b/man/macsave.1 @@ -0,0 +1,78 @@ +.TH MACSAVE L "October 22, 1992" +.UC +.SH NAME +macsave \- Save Mac files read from standard input +.SH SYNOPSIS +.B macsave +[ +.B \- options +] +.br +.SH DESCRIPTION +.I macsave +reads a sequence of Macintosh MacBinary files from standard input and writes +the files it contains subject to the +.I options +specified. +.SH OPTIONS +In the absence of any options, +.I macsave +reads standard input and silently writes the file(s) it contains +in MacBinary format, giving the output files ".bin" extensions and +placing them in the current working directory. +Subdirectories are created for embedded folders. +.TP +.B \-3 +Write files in fork format (.info, .data and .rsrc files.) +.TP +.B \-f +As -3, but empty data and rsrc files are not created. +.TP +.B \-r +Write resource forks only (.rsrc files.) +.TP +.B \-d +Write data forks only (.data files.) +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged, the filename extension +is .text. +.TP +.B \-U +As -u, but there is no filename extension. +.TP +.B \-a +Write files in AppleShare format. +This option is only valid if the program is compiled with support +for some form of AppleShare. +The current directory must be a valid AppleShare folder. +.TP +.B \-s +Write extracted files to standard output in MacBinary format. +.TP +.B \-l +List every file extracted (and every directory/folder created etc.) +.TP +.B \-v +Like -l, but more verbose (implies -l.) +.TP +.B \-i +Do not extract, give information only (implies -l.) +.TP +.B \-q +Ask the user for every file/folder whether it should be extracted +(implies -l.) +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) diff --git a/man/macstream.1 b/man/macstream.1 new file mode 100755 index 0000000..ca8d360 --- /dev/null +++ b/man/macstream.1 @@ -0,0 +1,95 @@ +.TH MACSTREAM L "October 22, 1992" +.UC +.SH NAME +macstream \- Convert a series of files to a MacBinary stream +.SH SYNOPSIS +.B macstream +[ +.B \- options +] files +.br +.SH DESCRIPTION +.I macstream +takes the files specified in +.I files +and combines them to a MacBinary stream on standard output +subject to the +.I options +specified. +If +.I files +also specifies directories they are followed recursively, and all files +found will be put in the MacBinary stream, together with directory +information. +.SH OPTIONS +In the absence of any options, +.I macstream +takes the specified files and silently combines them +to a MacBinary stream, writing the result to standard output. +Directories named in +.I files +are followed recursively, all files found will be put in the MacBinary +stream, together with directory information. +Files are assumed to be in MacBinary format. +However, if the filename ends with .info the file is assumed to be +the info fork of a MacIntosh file split amongst more than one file. +In that case the files with .data and .rsrc extension +are also read (if present). +Also, if the info fork is mentioned in the parameter list, the names +of data and resource forks can also be mentioned, but those will be +ignored (this is to allow wild-card expansion by the shell.) +Further, if some form of AppleShare is supported by the installed +program, and if the current directory, or one of the directories found +during recursive processing, is a directory in the format of the +supported version of AppleShare, those files will be handled according +to the properties of AppleShare. +.TP +.B \-r +No intelligent file-processing is performed; all files named are assumed +to be plain resource files, and are written as MacIntosh resource files with +creator "RSED" and type "RSRC", unless another creator and/or type are +specified. +.TP +.B \-d +No intelligent file-processing is performed; all files named are assumed +to be plain data files, and are written as MacIntosh data files with +creator "MACA" and type "TEXT", unless another creator and/or type are +specified. +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged. +.TP +.B \-U +Is a synonym for -u. +.TP +.B \-c creator +Defines the creator name to be used if one of the previous options is +specified. +.TP +.B \-t type +Defines the type name to be used if one of the previous options is +specified. +.TP +.B \-l +List every file and directory processed. +.TP +.B \-i +Do not output files, give information only (implies -l.) +.TP +.B \-q +Ask the user for every file/directory whether it should be visited +(implies -l.) +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) diff --git a/man/macunpack.1 b/man/macunpack.1 new file mode 100755 index 0000000..696256a --- /dev/null +++ b/man/macunpack.1 @@ -0,0 +1,100 @@ +.TH MACUNPACK L "October 22, 1992" +.UC +.SH NAME +macunpack \- Macintosh file de-archiver +.SH SYNOPSIS +.B macunpack +[ +.B \- options +] [ file ] +.br +.SH DESCRIPTION +.I macunpack +takes the Macintosh MacBinary archive specified in +.I file +(or standard input if none is specified) and extracts the files it +contains subject to the +.I options +specified. +The program will also accept the data fork of the archive for some kinds +of archive as standard input. +.SH OPTIONS +In the absence of any options, +.I macunpack +takes the specified archive and silently extracts the file(s) it contains +into MacBinary format, giving the output files ".bin" extensions and +placing them in the current working directory. +Subdirectories are created for embedded folders. +.TP +.B \-3 +Write files in fork format (.info, .data and .rsrc files.) +.TP +.B \-f +As -3, but empty data and rsrc files are not created. +.TP +.B \-r +Write resource forks only (.rsrc files.) +.TP +.B \-d +Write data forks only (.data files.) +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged, the filename extension +is .text. +.TP +.B \-U +As -u, but there is no filename extension. +.TP +.B \-a +Write files in AppleShare format. +This option is only valid if the program is compiled with support +for some form of AppleShare. +The current directory must be a valid AppleShare folder. +.TP +.B \-s +Write extracted files to standard output in MacBinary format. +.TP +.B \-l +List every file extracted (and every directory/folder created etc.) +.TP +.B \-v +Like -l, but more verbose (implies -l.) +.TP +.B \-i +Do not extract, give information only (implies -l.) +.TP +.B \-q +Ask the user for every file/folder whether it should be extracted +(implies -l.) +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. Archives +that are password protected and multi-file archives +are not dealt with. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) +.sp 1 +Parts of the code are based on codes from: +Steve Davies, +Rahul Dhesi, +Casper H.S. Dik, +Jim McKie, +Mark G. Mendel, +Haruhiko Okumura, +Joe Orost, +Samuel H. Smith, +Yooichi Tagawa, +Spencer W. Thomas, +Ken Turkowski, +Allan G. Weber, +James A. Woods and +Haruyasu Yoshizaki. diff --git a/man/macutil.1 b/man/macutil.1 new file mode 100755 index 0000000..bcce0b7 --- /dev/null +++ b/man/macutil.1 @@ -0,0 +1,42 @@ +.TH MACUTIL L "October 22, 1992" +.UC +.SH NAME +macutil \- A package that deals with MacIntosh files on a Unix system +.SH DESCRIPTION +.I macutil +is a package that contains a number of utilities that deal with MacIntosh +files on a Unix system. +It contains the following programs: +.TP +.B binhex +Convert files to BinHex 4.0 compatible hexified form. +.TP +.B frommac +Receives files from the MacIntosh on the Unix system. +.TP +.B hexbin +Convert hexified files to their MacIntosh format. +.TP +.B macsave +Save a series of files from a MacBinary stream as individual files. +.TP +.B macstream +Combine a series of files to a MacBinary stream. +.TP +.B macunpack +Unpack a MacIntosh archive into its constituents. +.TP +.B tomac +Transmits files from the Unix system to a MacIntosh. +.SH BUGS +This manual page is hopelessly incomplete! +.SH SEE ALSO +binhex(1), +frommac(1), +hexbin(1), +macsave(1), +macstream(1), +macunpack(1), +tomac(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) diff --git a/man/tomac.1 b/man/tomac.1 new file mode 100755 index 0000000..1b52a45 --- /dev/null +++ b/man/tomac.1 @@ -0,0 +1,124 @@ +.TH TOMAC L "October 22, 1992" +.UC +.SH NAME +tomac \- Transmit files to the Mac +.SH SYNOPSIS +.B tomac +[ +.B \- options +] [ files ] +.br +.SH DESCRIPTION +.I tomac +takes the files specified in +.I tomac +and transmits them to the Mac subject to the +.I options +specified. +If +.I files +also specifies directories they are followed recursively, and all files +found will be transmitted. +If no +.I files +parameter is specified, binhex reads a MacBinary stream from standard +input and transmits the files found; folder information is lost. +.SH OPTIONS +In the absence of any options, +.I tomac +takes the specified files and transmits them to to the Mac using the +XMODEM protocol. +Directories named in +.I files +are followed recursively, all files found will be transmitted. +Files are assumed to be in MacBinary format. +However, if the filename ends with .info the file is assumed to be +the info fork of a MacIntosh file split amongst more than one file. +In that case the files with .data and .rsrc extensions +are also read (if present). +Also, if the info fork is mentioned in the parameter list, the names +of data and resource forks can also be mentioned, but those will be +ignored (this is to allow wild-card expansion by the shell.) +Further, if some form of AppleShare is supported by the installed +program, and if the current directory, or one of the directories found +during recursive processing, is a directory in the format of the +supported version of AppleShare, those files will be handled according +to the properties of AppleShare. +.TP +.B \-r +No intelligent file-processing is performed; all files named are assumed +to be plain resource files, and are transmitted as if they were +MacIntosh resource files with +creator "RSED" and type "RSRC", unless another creator and/or type are +specified. +.TP +.B \-d +No intelligent file-processing is performed; all files named are assumed +to be plain data files, and are transmitted as if they were +MacIntosh data files with +creator "MACA" and type "TEXT", unless another creator and/or type are +specified. +.TP +.B \-u +As -d, but the codes for CR and LF are interchanged. +.TP +.B \-U +Is a synonym for -u. +.TP +.B \-c creator +Defines the creator name to be used if one of the previous options is +specified. +.TP +.B \-t type +Defines the type name to be used if one of the previous options is +specified. +.TP +.B \-l +List every file and directory processed. +.TP +.B \-i +Do not transmit files, give information only (implies -l.) +.TP +.B \-q +Ask the user for every file/directory whether it should be visited +(implies -l.) +.TP +.B \-x +Use the XMODEM protocol for transmission. +.TP +.B \-y +Use the YMODEM protocol for transmission (not yet supported.) +.TP +.B \-z +Use the ZMODEM protocol for transmission (not yet supported.) +.TP +.B \-o +Use the pre-beta version of XMODEM. +.TP +.B \-T +Allow for time-out detection during the protocol. +Normally you will not need this option because on occasion, when network +delays do occur, time-out detection interferes with a good transmission. +Also, when for some reason the connection is broken the program will +normally receive a hang-up signal and terminate. +However, in some situations it might be necessary to early detect time-outs +(because of communication loss or whatever, without loss of connection). +You should check whether use of this option has profits in your situation +or not. +.TP +.B \-V +Gives the patchlevel of the program, and other information. +Other options are ignored and the program quits immediately. +.TP +.B \-H +Give short information about the options. +Other options are ignored and the program quits immediately. +.SH BUGS +As this is a beta release, there may still be some problems. +.SH SEE ALSO +macutil(1) +.SH AUTHOR +Dik T. Winter, CWI, Amsterdam, The Netherlands (dik@cwi.nl) +.sp 1 +Parts of the code are based on codes from: +Dave Johnson. diff --git a/mixed/dir.c b/mixed/dir.c new file mode 100755 index 0000000..494b395 --- /dev/null +++ b/mixed/dir.c @@ -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++; +} + diff --git a/mixed/globals.c b/mixed/globals.c new file mode 100755 index 0000000..da9e076 --- /dev/null +++ b/mixed/globals.c @@ -0,0 +1,12 @@ +#include "globals.h" +#include "../fileio/machdr.h" + +char info[INFOBYTES]; +char text[F_NAMELEN+1]; + +int list, info_only, query, write_it, indent, dir_skip; +FILE *infp; +int in_data_size = -1; +int in_rsrc_size = -1; +int in_ds, in_rs, ds_skip, rs_skip; + diff --git a/mixed/globals.h b/mixed/globals.h new file mode 100755 index 0000000..6c058e8 --- /dev/null +++ b/mixed/globals.h @@ -0,0 +1,13 @@ +#include + +extern void exit(); +extern void transname(); + +extern char info[]; +extern char text[]; + +extern int list, info_only, query, write_it, indent, dir_skip; +extern FILE *infp; + +extern int in_data_size, in_rsrc_size, in_ds, in_rs, ds_skip, rs_skip; + diff --git a/mixed/macbinary.c b/mixed/macbinary.c new file mode 100755 index 0000000..5bf6bfd --- /dev/null +++ b/mixed/macbinary.c @@ -0,0 +1,121 @@ +#include "globals.h" +#include "../fileio/machdr.h" +#include "../fileio/kind.h" +#include "../util/util.h" + +extern void dir(); +extern void mcb(); +extern void do_indent(); + +static void skip_file(); +#ifdef SCAN +static void get_idf(); +#endif /* SCAN */ + +void macbinary() +{ + char header[INFOBYTES]; + int c; + + while(1) { + if((c = fgetc(infp)) == EOF) { + break; + } + (void)ungetc(c, infp); + if(fread(header, 1, INFOBYTES, infp) != INFOBYTES) { + (void)fprintf(stderr, "Can't read MacBinary header.\n"); + exit(1); + } + if(header[I_NAMEOFF] & 0x80) { + dir(header); + continue; + } + in_data_size = get4(header + I_DLENOFF); + in_rsrc_size = get4(header + I_RLENOFF); + in_ds = (((in_data_size + 127) >> 7) << 7); + in_rs = (((in_rsrc_size + 127) >> 7) << 7); + ds_skip = in_ds - in_data_size; + rs_skip = in_rs - in_rsrc_size; + if(dir_skip != 0) { + skip_file(in_ds + in_rs); + continue; + } +#ifdef SCAN + if(header[I_NAMEOFF] == 0) { + get_idf((int)header[I_NAMEOFF + 1]); + skip_file(ds_skip + in_rs); + continue; + } +#endif /* SCAN */ + if(header[0] == 0 /* MORE CHECKS HERE! */) { + mcb(header, (unsigned long)in_rsrc_size, + (unsigned long)in_data_size, in_ds + in_rs); + continue; + } else { + (void)fprintf(stderr, "Unrecognized header.\n"); + exit(1); + } + } +} + +static void skip_file(skip) + int skip; +{ + char buff[1024]; + int n; + + while(skip > 0) { + n = (skip < 1024 ? skip : 1024); + if(fread(buff, 1, n, infp) != n) { + (void)fprintf(stderr, "Incomplete file.\n"); + exit(1); + } + skip -= n; + } +} + +#ifdef SCAN +static void get_idf(kind) + int kind; +{ + char filename[1024], filename1[255]; + + if(fread(filename, 1, in_data_size, infp) != in_data_size) { + (void)fprintf(stderr, "Incomplete file.\n"); + exit(1); + } + filename[in_data_size] = 0; + if(list) { + do_indent(indent); + switch(kind) { + case UNIX_NAME: + (void)fprintf(stderr, "Unix filename: \"%s\"\n", filename); + break; + case PACK_NAME: + transname(filename, filename1, in_data_size); + (void)fprintf(stderr, "Packed filename: \"%s\"\n", filename1); + break; + case ARCH_NAME: + transname(filename, filename1, in_data_size); + (void)fprintf(stderr, "Archive name: \"%s\"\n", filename1); + break; + case UNKNOWN: + (void)fprintf(stderr, "Unknown method detected\n"); + break; + case ERROR: + (void)fprintf(stderr, "Error detected\n"); + break; + case PROTECTED: + (void)fprintf(stderr, "Protected file detected\n"); + break; + case COPY: + (void)fprintf(stderr, "Copied file found\n"); + break; + default: + (void)fprintf(stderr, "Do not understand this identification\n"); + exit(1); + } + } +} +#endif /* SCAN */ + diff --git a/mixed/macsave.c b/mixed/macsave.c new file mode 100755 index 0000000..5fa797a --- /dev/null +++ b/mixed/macsave.c @@ -0,0 +1,96 @@ +#include "globals.h" +#include "../util/patchlevel.h" +#include "../fileio/wrfile.h" +#include "../fileio/wrfileopt.h" +#include "../util/util.h" + +#define LOCALOPT "ilqVH" + +extern char *strcat(); +void macbinary(); + +static void usage(); + +static char options[128]; + +int main(argc, argv) +int argc; +char *argv[]; +{ + int c; + extern int optind; + extern char *optarg; + int errflg; + + set_wrfileopt(0); + set_s_wrfileopt(1); + (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': + list++; + break; + case 'q': + query++; + break; + case 'i': + info_only++; + break; + case '?': + errflg++; + break; + case 'H': + give_wrfileopt(); + (void)fprintf(stderr, "Macsave specific options:\n"); + (void)fprintf(stderr, + "-i:\tgive information only, do not save\n"); + (void)fprintf(stderr, "-l:\tgive listing\n"); + (void)fprintf(stderr, + "-q:\tquery for every file/folder before saving\n"); + (void)fprintf(stderr, + "-V:\tgive information about this version\n"); + (void)fprintf(stderr, "-H:\tthis message\n"); + (void)fprintf(stderr, "Default is silent saving\n"); + exit(0); + case 'V': + (void)fprintf(stderr, "Version %s, ", VERSION); + (void)fprintf(stderr, "patchlevel %d", PATCHLEVEL); + (void)fprintf(stderr, "%s.\n", get_mina()); + exit(0); + } + } + } + if(errflg || optind != argc) { + usage(); + exit(1); + } + + infp = stdin; + + if(info_only || query) { + list++; + } + c = getc(infp); + (void)ungetc(c, infp); + switch(c) { + case 0: + macbinary(); + break; + default: + (void)fprintf(stderr, "Input is not MacBinary\n"); + exit(1); + } + exit(0); + /* NOTREACHED */ +} + +static void usage() +{ + (void)fprintf(stderr, "Usage: macsave [-%s]\n", options); + (void)fprintf(stderr, "Use \"macsave -H\" for help.\n"); +} + diff --git a/mixed/macstream.c b/mixed/macstream.c new file mode 100755 index 0000000..a9b61aa --- /dev/null +++ b/mixed/macstream.c @@ -0,0 +1,183 @@ +#include +#include "../fileio/machdr.h" +#include "../fileio/rdfile.h" +#include "../fileio/rdfileopt.h" +#include "../util/patchlevel.h" + +extern char *malloc(); +extern char *realloc(); +extern char *strcat(); +extern void exit(); +extern void transname(); +extern void do_indent(); + +#define LOCALOPT "ilqVH" + +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 '?': + errflg++; + break; + case 'H': + give_rdfileopt(); + (void)fprintf(stderr, "Macstream 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"); + (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 || optind == argc) { + 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) { + (void)fwrite(file_info, 1, 128, stdout); + if(i == ISFILE) { + if(data_size != 0) { + (void)fwrite(data_fork, 1, data_size, stdout); + i = (((data_size + 127) >> 7) << 7) - data_size; + while(i-- > 0) { + (void)fputc(0, stdout); + } + } + if(rsrc_size != 0) { + (void)fwrite(rsrc_fork, 1, rsrc_size, stdout); + i = (((rsrc_size + 127) >> 7) << 7) - rsrc_size; + while(i-- > 0) { + (void)fputc(0, stdout); + } + } + } + } + } + exit(0); + /* NOTREACHED */ +} + +static void usage() +{ + (void)fprintf(stderr, "Usage: macstream [-%s] files\n", options); + (void)fprintf(stderr, "Use \"macstream -H\" for help.\n"); +} + diff --git a/mixed/makefile b/mixed/makefile new file mode 100755 index 0000000..5a887bb --- /dev/null +++ b/mixed/makefile @@ -0,0 +1,92 @@ +CFLAGS = -O $(CF) + +SRCS1 = macsave.c \ + globals.c \ + macbinary.c \ + dir.c \ + mcb.c + +SRCS2 = macstream.c + +OBJS1 = macsave.o \ + globals.o \ + macbinary.o \ + dir.o \ + mcb.o + +OBJS2 = macstream.o + +TNAME = ../util/transname +BNAME = ../util/backtrans +UNAME = ../util/util +ONAME = ../fileio/wrfile +INAME = ../fileio/rdfile +GNAME = ../fileio/fileglob +XOBJS1= $(TNAME).o $(UNAME).o $(ONAME).o $(GNAME).o +XSRCS1= $(TNAME).c $(UNAME).c $(ONAME).c $(GNAME).c +XOBJS2= $(TNAME).o $(BNAME).o $(UNAME).o $(INAME).o $(GNAME).o +XSRCS2= $(TNAME).c $(BNAME).c $(UNAME).c $(INAME).c $(GNAME).c + +all: macsave macstream + touch all + +macsave: $(OBJS1) $(XOBJS1) + $(CC) $(CFLAGS) -o macsave $(OBJS1) $(XOBJS1) + +macstream: $(OBJS2) $(XOBJS2) + $(CC) $(CFLAGS) -o macstream $(OBJS2) $(XOBJS2) + +$(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)" ) + +$(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) $(SRCS1) $(XSRCS1) + lint $(CF) $(LFLAGS) $(SRCS2) $(XSRCS2) + +clean: + -rm -f *.o + +clobber:clean + -rm -f all macsave macstream + +macsave.o: globals.h +macsave.o: ../util/patchlevel.h +macsave.o: ../fileio/wrfile.h +macsave.o: ../fileio/wrfileopt.h +macsave.o: ../util/util.h +globals.o: globals.h +globals.o: ../fileio/machdr.h +macbinary.o: globals.h +macbinary.o: ../fileio/machdr.h +macbinary.o: ../fileio/kind.h +macbinary.o: ../util/util.h +dir.o: globals.h +dir.o: ../fileio/machdr.h +dir.o: ../fileio/wrfile.h +dir.o: ../util/util.h +dir.o: ../util/masks.h +mcb.o: globals.h +mcb.o: ../fileio/machdr.h +mcb.o: ../fileio/wrfile.h +mcb.o: ../util/masks.h +mcb.o: ../util/util.h +macstream.o: ../fileio/machdr.h +macstream.o: ../fileio/rdfile.h +macstream.o: ../fileio/rdfileopt.h +macstream.o: ../util/patchlevel.h + diff --git a/mixed/mcb.c b/mixed/mcb.c new file mode 100755 index 0000000..51b5987 --- /dev/null +++ b/mixed/mcb.c @@ -0,0 +1,109 @@ +#include "globals.h" +#include "../fileio/machdr.h" +#include "../fileio/wrfile.h" +#include "../util/masks.h" +#include "../util/util.h" + +static int mcb_read; + +static void mcb_wrfile(); + +void mcb(hdr, rsrcLength, dataLength, toread) +char *hdr; +unsigned long rsrcLength, dataLength; +int toread; +{ + register int i; + int n; + char ftype[5], fauth[5]; + + mcb_read = toread; + for(i = 0; i < INFOBYTES; i++) { + info[i] = hdr[i]; + } + + n = hdr[I_NAMEOFF] & BYTEMASK; + if(n > F_NAMELEN) { + n = F_NAMELEN; + } + info[I_NAMEOFF] = n; + transname(hdr + I_NAMEOFF + 1, text, n); + if(hdr[I_LOCKOFF] & 1) { + hdr[I_FLAGOFF + 1] = PROTCT_MASK; + hdr[I_LOCKOFF] &= ~1; + } + + write_it = 1; + if(list) { + transname(hdr + I_TYPEOFF, ftype, 4); + transname(hdr + I_AUTHOFF, fauth, 4); + do_indent(indent); + (void)fprintf(stderr, + "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld", + text, ftype, fauth, (long)dataLength, (long)rsrcLength); + if(info_only) { + write_it = 0; + } + if(query) { + write_it = do_query(); + } else { + (void)fputc('\n', stderr); + } + } + + if(write_it) { + define_name(text); + start_info(info, rsrcLength, dataLength); + start_data(); + } + mcb_wrfile(dataLength); + if(write_it) { + start_rsrc(); + } + mcb_wrfile(rsrcLength); + if(write_it) { + end_file(); + } +} + +static void mcb_wrfile(ibytes) +unsigned long ibytes; +{ + int n; + + if(write_it) { + if(ibytes == 0) { + return; + } + n = fread(out_buffer, 1, (int)ibytes, infp); + if(n != ibytes) { + (void)fprintf(stderr, "Premature EOF\n"); + exit(1); + } + mcb_read -= n; + n = ((n + 127) / 128) * 128 - n; + if(n > mcb_read) { + n = mcb_read; + } + mcb_read -= n; + while(n-- > 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); + exit(1); + } + } + } else { + n = ((ibytes + 127) / 128) * 128; + if(n > mcb_read) { + n = mcb_read; + } + mcb_read -= n; + while(n-- > 0) { + if(getc(infp) == EOF) { + (void)fprintf(stderr, "Premature EOF\n"); + exit(1); + } + } + } +} + diff --git a/util/all b/util/all new file mode 100644 index 0000000..e69de29 diff --git a/util/backtrans.c b/util/backtrans.c new file mode 100755 index 0000000..fb6dd5d --- /dev/null +++ b/util/backtrans.c @@ -0,0 +1,104 @@ +#include "masks.h" + +/* Map a command line given name to a Mac name. If LATIN1 is not defined + the translation is direct, except that \ is handled special. \\ is + translated to \, \ddd (three digits) is translated to the octal code. + If LATIN1 is defined, special care has been taken with the 8 bit chars + to get a proper mapping, if possible. Note: colon is translated to _. */ +static char char_mapping[] = { + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '_', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', 0177, + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +#ifndef LATIN1 + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_'}; +#else /* LATIN1 */ + '_', 0301, 0242, 0243, 0327, 0265, '_', 0244, + 0254, 0251, '_', 0307, 0302, '_', 0250, '_', + 0241, 0261, '_', '_', 0253, '_', 0246, 0245, + '_', '_', '_', 0310, '_', '_', '_', 0300, + 0313, 0207, 0211, 0313, 0200, 0201, 0256, 0202, + 0217, 0203, 0220, 0221, 0223, 0314, 0224, 0225, + '_', 0204, 0230, 0227, 0231, 0233, 0205, '_', + 0257, 0235, 0234, 0236, 0206, '_', '_', 0247, + 0210, 0207, 0211, 0213, 0212, 0214, 0276, 0215, + 0217, 0216, 0220, 0221, 0223, 0222, 0224, 0225, + '_', 0226, 0230, 0227, 0231, 0233, 0232, 0326, + 0277, 0235, 0234, 0236, 0237, '_', '_', 0330}; +#endif /* LATIN1 */ + +void backtrans(macname, name) +char *macname, *name; +{ + char *in, *out; + int c, count = 0; + + out = macname; + for (in = name; *in; in++){ + if(count == 31) { + break; + } + if(*in != '\\') { + *out++ = char_mapping[*in & BYTEMASK]; + count++; + continue; + } + in++; + if(*in == 0) { + break;; + } + if(*in < '0' || *in > '9') { + *out++ = char_mapping[*in & BYTEMASK]; + count++; + continue; + } + c = *in - '0'; + in++; + if(*in < '0' || *in > '9') { + *out++ = c; + count++; + in--; + continue; + } + c = (c << 3) + *in - '0'; + in++; + if(*in < '0' || *in > '9') { + *out++ = c; + count++; + in--; + continue; + } + c = (c << 3) + *in - '0'; + *out++ = c; + count++; + } + *out++ = 0; +} + diff --git a/util/backtrans.o b/util/backtrans.o new file mode 100644 index 0000000000000000000000000000000000000000..ec3bd4465d4da4d18ce5e7ef5afab41ecc7f4b18 GIT binary patch literal 1936 zcmcIjO-~bH5Pp|Mp$b_fXo#3tzYr8wuqxsQZlORytWfz}>HvsZpnPI8Dr=x)52osL9 zketU*LV62xwv;g?Qc6mQkUW%F7ZRTUvaf7gUm@38yVIi{#Gp-!U5#==a@{H2w-lEo5Uf<2niuvMpC)(;Hogt-O0%MBYF*IdSbG=3~cCoIF*1x~BHb*}8i1Ttnk| z%Y}=Vnl3lHu3o#|aznDVw%OV{I_+KEH+yb5Zuj;%@AMB04h`SEcYkE`f$O2{_KbPQ zCw!BSrl$RY;LL0&tjs-*MCTWtJbkvfv`hK_{!BXC+OC*uIvoSG<|ff1Hqg;jP|Ynk z2^THns!EEASK&AiKSJNWQvD}|_f$x>()nWeyq8J{51)L(Lnfn?0>F_yIaqi6ydKX* zK=vY?mos@%oO5&*Pxk6O%{&aMT-Seg7H-)yrG(@_So9E&PY${K^32R+V1i^HG6|56 zQUG7f{sZn4#SAtI;`q&q7@qelvYUuuC8TK|vqIi!Sya4Hg@|LaA`{Ua4ihmH)ErOH z@An4aEf7?^A}qQ-tU!+tfHbeqH6D`v-fW$JG|a%q6&NQb0fv&DljiCsr~y@=aLbbB zX8*pVCs9d}eW0-p+Ze;EDQ>(Vi|#IHii|SCbu{PS@*8RWUv>wW#0oK;sZNNQYNndO zz!3I-$Z&}!EN1}KEFIIWfHPYk>NGZF;Ir5v$~T4&Q^434n?K__!N|A2RG$4Im+{&D xuy +#endif /* TYPES_H */ + +#ifdef BSD +#include +extern time_t time(); +#else /* BSD */ +#include +#endif /* BSD */ + +/* Mac time of 00:00:00 GMT, Jan 1, 1970 */ +#define TIMEDIFF 0x7c25b080 + diff --git a/util/makefile b/util/makefile new file mode 100755 index 0000000..92647f5 --- /dev/null +++ b/util/makefile @@ -0,0 +1,22 @@ +CFLAGS= -O $(CF) + +all: util.o transname.o backtrans.o + touch all + +util.o: util.c + +transname.o: transname.c + +backtrans.o: backtrans.c + +clean: + -rm -f util.o + -rm -f transname.o + -rm -f backtrans.o + -rm -f all + +util.o: ../fileio/fileglob.h +util.o: masks.h +util.o: util.h +backtrans.o: masks.h + diff --git a/util/masks.h b/util/masks.h new file mode 100755 index 0000000..b812a32 --- /dev/null +++ b/util/masks.h @@ -0,0 +1,4 @@ +#define NIBBLEMASK 0x0000000f +#define BYTEMASK 0x000000ff +#define WORDMASK 0x0000ffff + diff --git a/util/patchlevel.h b/util/patchlevel.h new file mode 100755 index 0000000..4d8bba1 --- /dev/null +++ b/util/patchlevel.h @@ -0,0 +1,3 @@ +#define VERSION "2.0b3 (22-OCT-1992)" +#define PATCHLEVEL 0 + diff --git a/util/transname.c b/util/transname.c new file mode 100755 index 0000000..70f4591 --- /dev/null +++ b/util/transname.c @@ -0,0 +1,109 @@ +#include +#include + +char *strncpy(); + +#ifdef MAXNAMLEN /* 4.2 BSD */ +#define FNAMELEN MAXNAMLEN +#else +#define FNAMELEN DIRSIZ +#endif + +/* Create a Unix file name based on the Mac filename. First off we have + * possible problems with filename sizes (Sys V) and also with allowable + * characters. Mac filename characters can be anything from 1 to 254 (I + * think 0 and 255 are not allowed) with colon disallowed. Unix filenames + * have also a lot of freedom, but cannot contain 0 or '/'. Also on Unix + * non-printable are a trouble (you will never see the filename correctly; + * and it may even lock your terminal with some versions of Unix). + * So first off non-printable characters are mapped to underscore. + * Although there are Unix systems that allow the high order bit set in + * a filename character in all programs, nearly all implementations do not + * allow that, so also characters in the range 0200-0377 are mapped to + * underscore (except as noted below). Some people would also like to + * remap characters that are special to some shells (open brackets, + * asterisks, exclamation point (csh), etc.) I did elect not to do so + * because there is no end. (The previous code disallowed a lot, but not + * the braces that are special to some shells, obviously he was a C-shell user!) + * Characters in the range 0200-0377 are in part accented letters + * (the Swedes, Norwegians and Danes would not agree, but who listens to + * them!); those are mapped to the unaccented version. All other characters + * in this range are mapped to underscore. Note: this is based on the + * Geneva font! + * This stuff is now largely table driven. + * One day I may modify this so that an environment variable may be used + * to define mappings. */ + +static char char_mapping[] = { + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '_', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '_', +#ifndef LATIN1 + 'A', 'A', 'C', 'E', 'N', 'O', 'U', 'a', + 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', + 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', + 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', 'O', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', 'o', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', 'A', 'A', 'O', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + 'y', '_', '_', '_', '_', '_', '_', '_', +#else /* LATIN1 */ + 0304, 0305, 0307, 0311, 0321, 0326, 0334, 0341, + 0340, 0342, 0344, 0343, 0345, 0347, 0351, 0350, + 0352, 0353, 0355, 0354, 0356, 0357, 0361, 0363, + 0362, 0364, 0366, 0365, 0372, 0371, 0373, 0374, + '_', 0260, 0242, 0243, 0247, 0267, 0266, 0337, + 0256, 0251, '_', 0264, 0250, '_', 0306, 0330, + '_', 0261, '_', '_', 0245, '_', '_', '_', + '_', '_', '_', '_', '_', '_', 0346, 0370, + 0277, 0241, 0254, '_', '_', '_', '_', 0253, + 0273, '_', '_', 0300, 0303, 0325, '_', '_', + '_', '_', '_', '_', '_', '_', 0367, 0244, + 0377, '_', '_', '_', '_', '_', '_', '_', +#endif /* LATIN1 */ + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_'}; + +void transname(name, namebuf, n) +char *name, *namebuf; +int n; +{ + char *np; + + /* make sure host file name doesn't get truncated beyond recognition */ + if (n > FNAMELEN - 2) { + n = FNAMELEN - 2; + } + (void)strncpy(namebuf, name, n); + namebuf[n] = '\0'; + + /* now: translate name */ + for (np = namebuf; *np; np++){ + *np = char_mapping[*np & 0xff]; + } +#ifdef NODOT + if(*namebuf == '.') { + *namebuf = '_'; + } +#endif /* NODOT */ +} + diff --git a/util/transname.o b/util/transname.o new file mode 100644 index 0000000000000000000000000000000000000000..a73de2e9b773a295b70c53f237387e12ebea4361 GIT binary patch literal 1936 zcmbtUOHUI~6u#43Z3nH3SMFfQjh{{97PD|;iwMC$SB96l_P=rovJ19l*ks4zc zCjJCB{)KMbG-_BIR|fw8Q4(W}8>8Ym?Y+z}DVpfl+`%BDzUd2#R`LNu(5BQv) zJj(0!V)mo>vxZUO0U z*ni+){h@}#jZH_6Hn;FnYumB*<0npbbar*0I(??+tVi(rdi{L?@!a_f!Hc1A|D}P! zp~&#a=;bS8SI4hO*X0RiQk|NP&fJ)ti)r!1&16cSzjb>dy?E#D(mhEKeEv{4A{U^j zfEj=mN6Z5(j~BMsag!|wCU4s0_>)QkK3})HF%XJ0xjXoFzLlQSZYsIO0m3a*b9I&F zj%RSO&A{)aJ{6_ltbS}0oV6KyuhVTCu5i`@BRCzxP8wBO;Ea@!FYBee_L37sh#h{V zV24Up;COIkn?aj~(r)IB2&i6evJBNu9EM@i>}0#iDyn-x)R>;Xa7Mt@!>TTZY}&iG z;EA4;wUj2uR9+!UR8C4UIgyyrrVR&?0>Q9X2uk6;zCr(xG$eR~eu<>?q^2a&w2PZc zJfTWhKh}%Dz6cvEd<(|AK}R5uYXf{L9n<9r!bAO{j4~~$&dI#4F6e}xly#Z#6R8y8 zlkuXV#A7j41D_VxRUQVdC8f*CECgVh8kMG!@Rl2W{!?*7K3=u;W<0X-tlks_)SHlP@Sve-Xz%$((`mPjNB6fsw*5`ju^F?z}(AoJjdH|GC_xF|_ zD7z=TKg?zMjK? +#include "../fileio/fileglob.h" +#include "masks.h" +#include "util.h" + +extern void exit(); + +#define MACTIMOFFS 1904 + +static int mlength[] = {0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337}; + +unsigned long get4(bp) +char *bp; +{ + register int i; + long value = 0; + + for(i = 0; i < 4; i++) { + value <<= 8; + value |= (*bp & BYTEMASK); + bp++; + } + return value; +} + +/* For if integers are stored wrong-endian. */ +unsigned long get4i(bp) +char *bp; +{ + register int i; + long value = 0; + + bp += 3; + for(i = 0; i < 4; i++) { + value <<= 8; + value |= (*bp & BYTEMASK); + bp--; + } + return value; +} + +unsigned long get2(bp) +char *bp; +{ + register int i; + int value = 0; + + for(i = 0; i < 2; i++) { + value <<= 8; + value |= (*bp & BYTEMASK); + bp++; + } + return value; +} + +/* For if integers are stored wrong-endian. */ +unsigned long get2i(bp) +char *bp; +{ + register int i; + long value = 0; + + bp += 1; + for(i = 0; i < 2; i++) { + value <<= 8; + value |= (*bp & BYTEMASK); + bp--; + } + return value; +} + +unsigned char getb(fp) +FILE *fp; +{ + int c; + + bytes_read += 1; + c = getc(fp); + if(c == EOF) { + (void)fprintf(stderr, "\nPremature EOF\n"); + exit(1); + } + return c & BYTEMASK; +} + +void copy(d, s, n) +char *d, *s; +int n; +{ + while(--n >= 0) { + *d++ = *s++; + } +} + +int do_query() +{ + char *tp, temp[10]; + + (void)fprintf(stderr, "? "); + (void) fflush(stdout); + (void) read(2, temp, sizeof(temp)); + temp[sizeof(temp) - 1] = 0; + tp = temp; + while(*tp != 0) { + if(*tp == 'y' || *tp == 'Y') { + return 1; + } else { + tp++; + } + } + return 0; +} + +void put4(dest, value) +char *dest; +unsigned long value; +{ + *dest++ = (value >> 24) & BYTEMASK; + *dest++ = (value >> 16) & BYTEMASK; + *dest++ = (value >> 8) & BYTEMASK; + *dest++ = value & BYTEMASK; +} + +void put2(dest, value) +char *dest; +unsigned long value; +{ + *dest++ = (value >> 8) & BYTEMASK; + *dest++ = value & BYTEMASK; +} + +void do_indent(indent) +int indent; +{ + int i; + + for(i = 0; i < indent; i++) { + (void)fputc(' ', stderr); + } +} + +real_time set_time(year, month, day, hours, minutes, seconds) +int year, month, day, hours, minutes, seconds; +{ + real_time toset; + + toset.year = year; + toset.month = month; + toset.day = day; + toset.hours = hours; + toset.minutes = minutes; + toset.seconds = seconds; + return toset; +} + +unsigned long tomactime(time) +real_time time; +{ + long accum; + int year; + + accum = time.month - 3; + year = time.year; + if(accum < 0) { + accum += 12; + year--; + } + accum = time.day + mlength[accum] + 59; + accum += (year - MACTIMOFFS) * 365 + year / 4 - MACTIMOFFS / 4; + accum = ((accum * 24 + time.hours) * 60 + time.minutes) * 60 + time.seconds; + return (unsigned)accum; +} + +real_time frommactime(accum) +unsigned long accum; +{ +long tmp1, tmp2; +real_time time; + + time.seconds = tmp1 = accum % 60; + accum /= 60; + time.minutes = tmp1 = accum % 60; + accum /= 60; + time.hours = tmp1 = accum % 24; + accum /= 24; + tmp1 = (long)accum - 60; + tmp2 = tmp1 % 1461; + if(tmp2 < 0) { + tmp2 += 1461; + } + tmp1 = (tmp1 - tmp2) / 1461; + time.year = tmp1 * 4; + tmp1 = tmp2 / 365; + if(tmp1 > 3) { + tmp1 = 3; + } + time.year += tmp1 + MACTIMOFFS; + tmp2 -= tmp1 * 365; + tmp1 = 12; + while(mlength[--tmp1] > tmp2); + time.day = tmp2 + 1 - mlength[tmp1]; + time.month = tmp1 + 3; + if(tmp1 > 9) { + time.month = tmp1 - 9; + time.year++; + } + return time; +} + diff --git a/util/util.h b/util/util.h new file mode 100755 index 0000000..90112be --- /dev/null +++ b/util/util.h @@ -0,0 +1,23 @@ +typedef struct real_time { + int year; + int month; + int day; + int hours; + int minutes; + int seconds; +} real_time; + +extern unsigned long get4(); +extern unsigned long get4i(); +extern unsigned long get2(); +extern unsigned long get2i(); +extern unsigned char getb(); +extern void copy(); +extern int do_query(); +extern void put4(); +extern void put2(); +extern void do_indent(); +extern real_time set_time(); +extern unsigned long tomactime(); +extern real_time frommactime(); + diff --git a/util/util.o b/util/util.o new file mode 100644 index 0000000000000000000000000000000000000000..ee28cc466e5e93670763a249bca961b3ca8e5ab6 GIT binary patch literal 4360 zcmbuDeQZ-z6u|H6>sU8yTV=|ksMS=nDmDx-ieGD?W4EMQfgu_{YU$owWo5H_4a3B* zJ*RuA&tNohCPs}KrK$Hi<>sUNi%i zsrI8wtHEBR34CjlRkem{@43pfz{WM|1-cW*O^s{NgSqWOz%0F@O-TItEz5~#V__Q$H7d6y?XS5#NcA+nu zFzb3e8dyNQBhi58p`zNN?fv%Zo7EO-vT!18!|Xro%8;7ac72-$jixFj~PmAV&i}t#}n3Hs07aS*>P{W?^>58hLP!H}+ZS zxWjnz%)p6im8L(ZQiU1~VVaHx8o;Pfy#o91q`?YJw+9*l4V;V?8qNXOuA*BzARRK+ z(H;7bDLB<*`(k<}R+^}Z>qQI`52A9!^j~AaF=WT~(bB;hOGK;<7GwI6Sm}V1jy~9P z`*l}ea#mej-%XG0kLjNQmg(s0ubE2Wjc}JhrPCVT@|W730LSB&vR0B0?W?~br({!VKBxFw6RYY;iyxyBavnUG zDYwFN4?Iu9gD3e5cz%axJ{*iC@T|e(-?nn)mHwu->(>YUmxq>y76U?QFcp#RSxcmT zpLDjn*0l}%eZUv;x^uZkCfZ$KVNq_MZecfZdp_5Vpu4#pK^^t@*4KMnkyFgRhIrkD zT%-Rp+#W$4^(=NgYc{}f;5<>R#Knk?f?M-4GFhddzhxp21`3SFJ#NOeX90D0D52IP49 zW{M1vW)qpPyZodo7nCG2Z;FZiLm*rDlmp|~YNp7fZU)4?AhYz#ZY$ts{mIQ_0;yt? zv!HysWgWzs!!wRtl*NAIIYAxFV$ z;DqxFLEw&?p4m;;GE?hus7kEZJax}|99M9gdkK3nb0gWfRaN?uIVIIWl5O$Ciby<}ShZ?h zYkRUivLfD^B*|DJ360XEPwh~0Inuc$mr)g>^k-C(?&;l1I(m|K=at-6bm+;eq_eX- z-`7Qw$v!oe-jqytZAx~gGTo#%4}*Z$5^Ry#+@Wj+UnoOlMNO)itU}bDY%0yH&RkDc z*qh905}Yoc@jt7k+|4=O1bB!4#rXi|=#M!l_!Ab6UsHk)bB=M&wD1=!e1V1U=iDCu zHw%X=eJcJW=l1yGBE&eD`(iv!zTfDNXF>3DEFAA(!SA(j{IM1Mea`LU{M6!qzQun& zI)b3W+eyUP&97iP_k#}#a^94cm$COW7xxym@h~snYUASG>a}rkZ#`<`;+}Zk#>GAH zu8oU4uGqN9R? z33a5@6bWtY>m#9D4;Ik9In*qQB$S36!7K`G?opKxeAiscQVtw2iqe(r%%vc!{;&8U z08VB47u1XxHWhK>LA3~<_7uT0j4t6RVj2{a5M-D)z??x-{PN=W56VUGAh&-B#BKee zFN(eYMZhrTe{J8)V~TqmicCcR;`dc>(ZA4Ps6gAABj|evAOB)3Sj2C!(ZsyL_IAH* zyglBDRuTOQy#^|UZS{NMU#?##Z*L#}E4=*;w%}s_L|-W|&^0Uo*L!ipK}4Ql5x=fP zd$Io*-rhGLGFgLfLi+i}y1~Xj+3oEyrhV@LkzW2O_Z1c_Vw(;*4eDlV-^l-OA?_&= H!ruNL{|WD; literal 0 HcmV?d00001