macutils/ 40775 33261 310 0 5575234367 10511 5ustar mirrormacutils/man/ 40775 33261 310 0 5574773371 11266 5ustar mirrormacutils/man/macstream.1100775 33261 310 5624 5453360600 13412 0ustar mirror.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) macutils/man/frommac.1100775 33261 310 5135 5453360600 13057 0ustar mirror.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. macutils/man/macunpack.1100775 33261 310 4622 5453360600 13375 0ustar mirror.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. macutils/man/macutil.1100775 33261 310 1723 5453360600 13070 0ustar mirror.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) macutils/man/tomac.1100775 33261 310 7346 5453360600 12544 0ustar mirror.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. macutils/man/macsave.1100775 33261 310 3625 5453360600 13054 0ustar mirror.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) macutils/man/hexbin.1100775 33261 310 5575 5453360600 12720 0ustar mirror.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. macutils/man/binhex.1100775 33261 310 6112 5453360600 12704 0ustar mirror.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) macutils/doc/ 40775 33261 310 0 5574773373 11262 5ustar mirrormacutils/doc/README.crc.orig100775 33261 310 13446 5453360600 13754 0ustar mirror/* updcrc(3), crc(1) - calculate crc polynomials * * Calculate, intelligently, the CRC of a dataset incrementally given a * buffer full at a time. * * Usage: * newcrc = updcrc( oldcrc, bufadr, buflen ) * unsigned int oldcrc, buflen; * char *bufadr; * * Compiling with -DTEST creates a program to print the CRC of stdin to stdout. * Compile with -DMAKETAB to print values for crctab to stdout. If you change * the CRC polynomial parameters, be sure to do this and change * crctab's initial value. * * Notes: * Regards the data stream as an integer whose MSB is the MSB of the first * byte recieved. This number is 'divided' (using xor instead of subtraction) * by the crc-polynomial P. * XMODEM does things a little differently, essentially treating the LSB of * the first data byte as the MSB of the integer. Define SWAPPED to make * things behave in this manner. * * Author: Mark G. Mendel, 7/86 * UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm */ /* The CRC polynomial. * These 4 values define the crc-polynomial. * If you change them, you must change crctab[]'s initial value to what is * printed by initcrctab() [see 'compile with -DMAKETAB' above]. */ /* Value used by: CITT XMODEM ARC */ #define P 0xA001 /* the poly: 0x1021 0x1021 A001 */ #define INIT_CRC 0L /* init value: -1 0 0 */ #define SWAPPED /* bit order: undef defined defined */ #define W 16 /* bits in CRC:16 16 16 */ /* data type that holds a W-bit unsigned integer */ #if W <= 16 # define WTYPE unsigned short #else # define WTYPE unsigned long #endif /* the number of bits per char: don't change it. */ #define B 8 static WTYPE crctab[1<>(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 **************************************************************************** macutils/doc/README.macget100775 33261 310 1052 5453360600 13454 0ustar mirror/* * 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) */ macutils/doc/README.macput100775 33261 310 1164 5453360600 13511 0ustar mirror/* * * 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 * */ macutils/doc/README.unsit100775 33261 310 3574 5453360600 13371 0ustar mirror/* unsit - Macintosh StuffIt file extractor Version 1, for StuffIt 1.31 This program will unpack a Macintosh StuffIt file into separate files. The data fork of a StuffIt file contains both the data and resource forks of the packed files. The program will unpack each Mac file into separate .data, .rsrc., and .info files that can be downloaded to a Mac using macput. The program is much like the "unpit" program for breaking apart Packit archive files. ***** IMPORTANT ***** To extract StuffIt files that have been compressed with the Lempel-Ziv compression method, unsit pipes the data through the "compress" program with the appropriate switches, rather than incorporate the uncompression routines within "unsit". Therefore, it is necessary to have the "compress" program on the system and in the search path to make "unsit" work. "Compress" is available from the comp.sources.unix archives. The program syntax is much like unpit and macput/macget, with some added options: unsit [-rdulvq] stuffit-file.data The -r and -d flags will cause only the resource and data forks to be written. The -u flag will cause only the data fork to be written and to have carriage return characters changed to Unix newline characters. The -l flag will make the program only list the files in the StuffIt file. The -v flag causes the program to list the names, sizes, type, and creators of the files it is writing. The -q flag causes it to list the name, type and size of each file and wait for a 'y' or 'n' for either writing that file or skipping it, respectively. Some of the program is borrowed from the macput.c/macget.c programs. Many, many thanks to Raymond Lau, the author of StuffIt, for including information on the format of the StuffIt archives in the documentation. Author: Allan G. Weber weber%brand.usc.edu@oberon.usc.edu ...sdcrdcf!usc-oberon!brand!weber Date: January 15, 1988 */ macutils/doc/README.zoom100775 33261 310 6475 5453360600 13216 0ustar mirrorTaken from the file plugins.h in the Zoom distribution. /* * The Zoom archive format is: * * (char) Magic1 * (char) Magic2 - or - (char) Magic2B * (char) Magic3 * (char) Magic4 * * IF Magic2B was received THEN * (long) logicalEof /* For multi-file archives * / * END IF * * * * 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 ; macutils/doc/README.crc100775 33261 310 355 5453360600 12750 0ustar mirrorThis code is based on the code described in README.ORIG. Changes are: 1. A program (makecrc) will create the different C source files to do crc calculations. 2. The crc calculation method of binhex is added. 3. 32 bit crc's are added. macutils/doc/README.hexbin100775 33261 310 2615 5453360600 13477 0ustar mirrorThe 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. */ macutils/doc/README.unpit100775 33261 310 4232 5453360600 13356 0ustar mirror/* * @(#)unpit.c 1.2 (CWI) 87/11/05 */ /* unpit - Macintosh PackIt file unpacker Version 2, for PackIt II This program will unpack a Macintosh PackIt file into separate files. The data fork of a PackIt file contains both the data and resource forks of the packed files. The program will unpack each Mac file into separate .data, .rsrc., and .info files that can be downloaded to a Mac using macput. The program syntax is much like macput/macget: unpit [-rdu] packit-file.data The -r and -d flags will cause only the resource and data forks to be written. The -u flag will cause only the data fork to be written and to have carriage return characters changed to Unix newline characters. Some of the program is borrowed from the macput.c/macget.c programs. Author: Allan G. Weber, (Weber%Brand@USC-ECL) Date: September 30, 1985 Revised: January 24, 1986 - added CRC checking March 25, 1986 - support compressed mode of PackIt II, check for illegal Unix file names */ /* There is some confusion as to what to do with the "inited" flag in the finder info bytes that are in the header of each file in the packit file. If this flag bit is copied to the .info file, it seems to confuse MacTerminal into placing the file icons in the upper left corner of the window on top of each other. Setting this bit to zero in the .info file seems to fix that problem but may cause others. I haven't been able to find any .info files that have this flag set so making it zero may be OK. Anyway, MacTerminal seems to set the flag when it create the file on the Mac. The "#define INITED_BUG" can be used to try both settings. */ /* Format of a Packit file: Repeat the following sequence for each file in the Packit file: 4 byte identifier ("PMag" = not compressed, "Pma4" = compressed) variable length compression data (if compressed file) 92 byte header (see struct pit_header below) * 2 bytes CRC number * data fork (length from header) * resource fork (length from header) * 2 bytes CRC number * Last file is followed by the 4 byte Ascii string, "Pend", and then the EOF. * these are in compressed form if compression is on for the file */ macutils/doc/README.scan100775 33261 310 6765 5453360600 13160 0ustar mirrorPreliminary 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 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 */ macutils/comm/tty.c100775 33261 310 4626 5453360600 12521 0ustar mirror#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); } macutils/comm/globals.c100775 33261 310 122 5453360600 13267 0ustar mirror#include "globals.h" int xfertype = XMODEM; int pre_beta = 0; int time_out = 0; macutils/comm/makefile100775 33261 310 4125 5453360600 13227 0ustar mirrorCFLAGS = -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 macutils/comm/tomac.c100775 33261 310 11720 5453360600 13015 0ustar mirror#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"); } macutils/comm/globals.h100775 33261 310 164 5453360600 13302 0ustar mirror#define XMODEM 0 #define YMODEM 1 #define ZMODEM 2 extern int xfertype; extern int pre_beta; extern int time_out; macutils/comm/protocol.h100775 33261 310 560 5453360600 13520 0ustar mirror#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' macutils/comm/frommac.c100775 33261 310 6732 5453360600 13325 0ustar mirror#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"); } macutils/comm/xm_from.c100775 33261 310 5201 5453360600 13336 0ustar mirror#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 */ macutils/comm/comm.h100775 33261 310 150 5453360600 12605 0ustar mirror#define XM /* Know about XMODEM */ #undef YM /* Know about YMODEM */ #undef ZM /* Know about ZMODEM */ macutils/binhex/ 40775 33261 310 0 5574773375 11774 5ustar mirrormacutils/binhex/dofile.c100775 33261 310 6545 5453360600 13467 0ustar mirror#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; } } macutils/binhex/binhex.c100775 33261 310 7213 5453360600 13473 0ustar mirror#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"); } macutils/binhex/makefile100775 33261 310 2056 5453360600 13552 0ustar mirrorCFLAGS = -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 macutils/mixed/ 40775 33261 310 0 5574773376 11626 5ustar mirrormacutils/mixed/macbinary.c100775 33261 310 5210 5453360600 14007 0ustar mirror#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 */ macutils/mixed/globals.h100775 33261 310 406 5453360600 13454 0ustar mirror#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; macutils/mixed/mcb.c100775 33261 310 3756 5453360600 12620 0ustar mirror#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); } } } } macutils/mixed/makefile100775 33261 310 3675 5453360600 13413 0ustar mirrorCFLAGS = -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 macutils/mixed/macstream.c100775 33261 310 7734 5453360600 14033 0ustar mirror#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"); } macutils/mixed/globals.c100775 33261 310 372 5453360600 13451 0ustar mirror#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; macutils/mixed/dir.c100775 33261 310 2515 5453360600 12625 0ustar mirror#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++; } macutils/mixed/macsave.c100775 33261 310 3611 5453360600 13464 0ustar mirror#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"); } macutils/hexbin/ 40775 33261 310 0 5574773377 11776 5ustar mirrormacutils/hexbin/hexbin.h100775 33261 310 410 5453360600 13450 0ustar mirror#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) macutils/hexbin/hecx.c100775 33261 310 12534 5453360600 13167 0ustar mirror#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 */ macutils/hexbin/buffer.c100775 33261 310 2664 5453360600 13474 0ustar mirror#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(); } macutils/hexbin/printhdr.h100775 33261 310 130 5453360600 14024 0ustar mirrorextern void print_header0(); extern void print_header1(); extern void print_header2(); macutils/hexbin/mu.c100775 33261 310 11433 5453360600 12656 0ustar mirror#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 */ macutils/hexbin/buffer.h100775 33261 310 214 5453360600 13446 0ustar mirrorextern char *data_fork, *rsrc_fork; extern int data_size, rsrc_size; extern void put_byte(); extern void set_put(); extern void end_put(); macutils/hexbin/readline.c100775 33261 310 1277 5453360600 14005 0ustar mirror#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; } macutils/hexbin/hqx.c100775 33261 310 22117 5453360600 13036 0ustar mirror#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 */ macutils/hexbin/printhdr.c100775 33261 310 1635 5453360600 14052 0ustar mirror#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); } } macutils/hexbin/hqx.diff100775 33261 310 1640 5453360600 13502 0ustar mirror*** 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)) { macutils/hexbin/readline.h100775 33261 310 25 5453360600 13740 0ustar mirrorextern char line[]; macutils/hexbin/dl.c100775 33261 310 5234 5453360600 12616 0ustar mirror#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 */ macutils/hexbin/crc.h100775 33261 310 327 5453360600 12751 0ustar mirror#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(); macutils/hexbin/globals.h100775 33261 310 1174 5453360600 13646 0ustar mirror#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(); macutils/hexbin/globals.c100775 33261 310 564 5453360600 13623 0ustar mirror#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 */ macutils/hexbin/crc.c100775 33261 310 1365 5453360600 12767 0ustar mirror/* 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); } } macutils/hexbin/makefile100775 33261 310 4710 5453360600 13551 0ustar mirrorCFLAGS= -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 macutils/hexbin/hexbin.c100775 33261 310 17127 5453360600 13520 0ustar mirror#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"); } macutils/macunpack/ 40775 33261 310 0 5574773377 12463 5ustar mirrormacutils/macunpack/de_lzh.c100775 33261 310 14003 5453360600 14163 0ustar mirror#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 */ macutils/macunpack/dd.c100775 33261 310 60767 5453360600 13327 0ustar mirror#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 */ macutils/macunpack/dd.h100775 33261 310 6051 5453360600 13276 0ustar mirror#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 */ macutils/macunpack/macunpack.h100775 33261 310 1073 5453360600 14650 0ustar mirror#define UNTESTED /* Know about the untested algorithms */ #define BIN /* Know about BinHex 5.0 etc. */ #define JDW /* Know about Compress It */ #define STF /* Know about ShrinkToFit */ #define LZC /* Know about MacCompress */ #undef ASQ /* Know about AutoSqueeze */ #undef ARC /* Know about ArcMac */ #define PIT /* Know about PackIt */ #define SIT /* Know about StuffIt */ #define DIA /* Know about Diamond */ #define CPT /* Know about Compactor */ #define ZMA /* Know about Zoom */ #define LZH /* Know about LHa */ #define DD /* Know about DiskDoubler */ macutils/macunpack/jdw.h100775 33261 310 676 5453360600 13462 0ustar mirror#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 */ }; macutils/macunpack/jdw.c100775 33261 310 6740 5453360600 13473 0ustar mirror#include "macunpack.h" #ifdef JDW #include "jdw.h" #include "globals.h" #include "huffman.h" #include "../fileio/wrfile.h" #include "../fileio/machdr.h" #include "../util/util.h" #include "../util/masks.h" extern void de_huffman(); extern void set_huffman(); extern void read_tree(); extern void clrhuff(); static void jdw_wrfile(); static void jdw_wrfork(); static void jdw_block(); void jdw(ibytes) unsigned long ibytes; { char fauth[5], ftype[5]; int filel, i; unsigned int rsrcLength, dataLength; set_huffman(HUFF_BE); for(i = 0; i < 6; i++) (void)getb(infp); for(i = 0; i < INFOBYTES; i++) { info[i] = 0; } for(i = 0; i < 4; i++) { info[I_TYPEOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_AUTHOFF + i] = getb(infp); } for(i = 0; i < 8; i++) { info[I_FLAGOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_DLENOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_RLENOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_CTIMOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_MTIMOFF + i] = getb(infp); } filel = getb(infp); info[I_NAMEOFF] = filel; i = filel; for(i = 1; i <= filel; i++) { info[I_NAMEOFF + i] = getb(infp); } (void)getb(infp); rsrcLength = get4(info + I_RLENOFF); dataLength = get4(info + I_DLENOFF); ibytes -= filel + 40; write_it = 1; if(list) { transname(info + I_NAMEOFF + 1, text, (int)info[I_NAMEOFF]); transname(info + I_TYPEOFF, ftype, 4); transname(info + 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); } } jdw_wrfile((unsigned long)rsrcLength, (unsigned long)dataLength); } static void jdw_wrfile(rsrcLength, dataLength) unsigned long rsrcLength, dataLength; { if(write_it) { define_name(text); start_info(info, rsrcLength, dataLength); start_data(); } if(verbose) { (void)fprintf(stderr, "\tData: "); } jdw_wrfork(dataLength); if(write_it) { start_rsrc(); } if(verbose) { (void)fprintf(stderr, ", Rsrc: "); } jdw_wrfork(rsrcLength); if(write_it) { end_file(); } if(verbose) { (void)fprintf(stderr, ".\n"); } } static void jdw_wrfork(length) unsigned long length; { int olength, ilength, i; unsigned long origlength, comprlength; if(length == 0) { (void)fprintf(stderr, "empty"); return; } (void)fprintf(stderr, "Huffman compressed "); comprlength = 0; origlength = length; while(length > 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 */ macutils/macunpack/arc.h100775 33261 310 2254 5453360600 13455 0ustar mirror#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 macutils/macunpack/dia.h100775 33261 310 647 5453360600 13431 0ustar mirror#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 macutils/macunpack/dia.c100775 33261 310 31332 5453360600 13457 0ustar mirror#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 */ macutils/macunpack/de_compress.c100775 33261 310 12061 5453360600 15223 0ustar mirror#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 */ macutils/macunpack/de_huffman.c100775 33261 310 4763 5453360600 15006 0ustar mirror#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 */ macutils/macunpack/lzh.h100775 33261 310 2473 5453360600 13510 0ustar mirror#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; macutils/macunpack/macunpack.c100775 33261 310 10135 5453360600 14662 0ustar mirror#include "macunpack.h" #include "globals.h" #include "../util/patchlevel.h" #include "../fileio/wrfile.h" #include "../fileio/wrfileopt.h" #include "../fileio/kind.h" #include "../util/util.h" #define LOCALOPT "ilvqVH" extern char *strcat(); #ifdef STF extern void stf(); #endif /* STF */ #ifdef PIT extern void pit(); #endif /* PIT */ #ifdef SIT extern void sit(); #endif /* SIT */ #ifdef CPT extern void cpt(); #endif /* CPT */ 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); (void)strcat(options, get_wrfileopt()); (void)strcat(options, LOCALOPT); errflg = 0; while((c = getopt(argc, argv, options)) != EOF) { #ifdef SCAN if(c == 'S') { no_dd++; } #endif /* SCAN */ if(!wrfileopt((char)c)) { switch(c) { case 'l': list++; break; case 'q': query++; break; case 'v': verbose++; break; case 'i': info_only++; break; case '?': errflg++; break; case 'H': give_wrfileopt(); (void)fprintf(stderr, "Macunpack specific options:\n"); (void)fprintf(stderr, "-i:\tgive information only, do not unpack\n"); (void)fprintf(stderr, "-l:\tgive listing\n"); (void)fprintf(stderr, "-v:\tgive verbose listing\n"); (void)fprintf(stderr, "-q:\tquery for every file/folder before unpacking\n"); (void)fprintf(stderr, "-V:\tgive information about this version\n"); (void)fprintf(stderr, "-H:\tthis message\n"); (void)fprintf(stderr, "Default is silent unpacking\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, "Archive/file types recognized:\n"); #ifdef BIN (void)fprintf(stderr, "\tBinHex 5.0, MacBinary 1.0 and UMCP (with caveat)\n"); #endif /* BIN */ #ifdef JDW (void)fprintf(stderr, "\tCompress It\n"); #endif /* JDW */ #ifdef STF (void)fprintf(stderr, "\tShrinkToFit\n"); #endif /* STF */ #ifdef LZC (void)fprintf(stderr, "\tMacCompress\n"); #endif /* LZC */ #ifdef ASQ (void)fprintf(stderr, "\tAutoSqueeze\n"); #endif /* ASQ */ #ifdef ARC (void)fprintf(stderr, "\tArcMac\n"); #endif /* ARC */ #ifdef PIT (void)fprintf(stderr, "\tPackIt\n"); #endif /* PIT */ #ifdef SIT (void)fprintf(stderr, "\tStuffIt and StuffIt Deluxe\n"); #endif /* SIT */ #ifdef DIA (void)fprintf(stderr, "\tDiamond\n"); #endif /* DIA */ #ifdef CPT (void)fprintf(stderr, "\tCompactor\n"); #endif /* CPT */ #ifdef ZMA (void)fprintf(stderr, "\tZoom\n"); #endif /* ZMA */ #ifdef LZH (void)fprintf(stderr, "\tMacLHa\n"); #endif /* LZH */ #ifdef DD (void)fprintf(stderr, "\tDiskDoubler and AutoDoubler\n"); #endif /* DD */ exit(0); } } } if(errflg) { usage(); exit(1); } if(optind == argc) { infp = stdin; } else { if((infp = fopen(argv[optind], "r")) == NULL) { (void)fprintf(stderr,"Can't open input file \"%s\"\n",argv[optind]); exit(1); } #ifdef SCAN do_idf(argv[optind], UNIX_NAME); #endif /* SCAN */ } if(info_only || verbose || query) { list++; } c = getc(infp); (void)ungetc(c, infp); switch(c) { case 0: macbinary(); break; #ifdef STF case 'R': if(verbose) { (void)fprintf(stderr, "This is a \"ShrinkToFit\" packed file.\n"); } stf(~(unsigned long)1); break; #endif /* STF */ #ifdef PIT case 'P': if(verbose) { (void)fprintf(stderr, "This is a \"PackIt\" archive.\n"); } pit(); break; #endif /* PIT */ #ifdef SIT case 'S': if(verbose) { (void)fprintf(stderr, "This is a \"StuffIt\" archive.\n"); } sit(); break; #endif /* SIT */ #ifdef CPT case 1: if(verbose) { (void)fprintf(stderr, "This is a \"Compactor\" archive.\n"); } cpt(); break; #endif /* CPT */ default: (void)fprintf(stderr, "Unrecognized archive type\n"); exit(1); } exit(0); /* NOTREACHED */ } static void usage() { (void)fprintf(stderr, "Usage: macunpack [-%s] [filename]\n", options); (void)fprintf(stderr, "Use \"macunpack -H\" for help.\n"); } macutils/macunpack/zmahdr.h100775 33261 310 104 5453360600 14145 0ustar mirror#define ZMAHDR "\005\237\032" #define ZMAHDRS 3 #define ZMAHDRS2 7 macutils/macunpack/bits_be.c100775 33261 310 1663 5453360600 14315 0ustar mirror#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); } macutils/macunpack/bits_be.h100775 33261 310 334 5453360600 14274 0ustar mirror#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(); macutils/macunpack/stf.h100775 33261 310 454 5453360600 13464 0ustar mirror#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; }; macutils/macunpack/zma.h100775 33261 310 4032 5453360600 13473 0ustar mirror#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 */ macutils/macunpack/sit.h100775 33261 310 5172 5453360600 13511 0ustar mirror#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 */ macutils/macunpack/huffman.h100775 33261 310 336 5453360600 14313 0ustar mirror#define HUFF_BE 0 #define HUFF_LE 1 typedef struct node { int flag, byte; struct node *one, *zero; } node; extern int (*get_bit)(); extern void clrhuff(); extern struct node nodelist[]; extern int bytesread; macutils/macunpack/cpt.h100775 33261 310 4635 5453360600 13503 0ustar mirror#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 macutils/macunpack/stf.c100775 33261 310 11601 5453360600 13513 0ustar mirror#include "macunpack.h" #ifdef STF #include "stf.h" #include "globals.h" #include "huffman.h" #include "../util/curtime.h" #include "../fileio/wrfile.h" #include "../fileio/machdr.h" #include "../util/util.h" extern void de_huffman(); extern void set_huffman(); typedef struct{ int num; int next; } table_struct; static table_struct table[511]; static char length[256]; static void stf_wrfile(); static void stf_wrfork(); static void stf_construct(); void stf(ibytes) unsigned long ibytes; { char magic[3], fauth[5], ftype[5]; int filel, i; unsigned int rsrcLength, dataLength; unsigned long curtime; set_huffman(HUFF_LE); for(i = 0; i < 3; i++) { magic[i] = getb(infp); } if(strncmp(magic, MAGIC, 3)) { (void)fprintf(stderr, "Error in magic header.\n"); #ifdef SCAN do_error("macunpack: Error in magic header"); #endif /* SCAN */ exit(1); } for(i = 0; i < INFOBYTES; i++) { info[i] = 0; } filel = getb(infp); info[I_NAMEOFF] = filel; i = filel; for(i = 1; i <= filel; i++) { info[I_NAMEOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_TYPEOFF + i] = getb(infp); } for(i = 0; i < 4; i++) { info[I_AUTHOFF + i] = getb(infp); } curtime = (unsigned long)time((time_t *)0) + TIMEDIFF; put4(info + I_CTIMOFF, curtime); put4(info + I_MTIMOFF, curtime); rsrcLength = 0; for(i = 0; i < 4; i++) { rsrcLength = (rsrcLength << 8) + getb(infp); } put4(info + I_RLENOFF, (unsigned long)rsrcLength); dataLength = 0; for(i = 0; i < 4; i++) { dataLength = (dataLength << 8) + getb(infp); } put4(info + I_DLENOFF, (unsigned long)dataLength); ibytes -= filel + 20; write_it = 1; if(list) { transname(info + I_NAMEOFF + 1, text, (int)info[I_NAMEOFF]); transname(info + I_TYPEOFF, ftype, 4); transname(info + 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); } } stf_wrfile((unsigned long)rsrcLength, (unsigned long)dataLength, ibytes); } static void stf_wrfile(rsrcLength, dataLength, ibytes) unsigned long rsrcLength, dataLength, ibytes; { unsigned long num = 0; if(write_it) { define_name(text); start_info(info, rsrcLength, dataLength); start_rsrc(); stf_wrfork(&num, rsrcLength, 0); start_data(); stf_wrfork(&num, rsrcLength + dataLength, (int)(rsrcLength & 0xfff)); end_file(); } else { for(num = 0; num < ibytes; num++) { (void)getb(infp); } } if(verbose) { (void)fprintf(stderr, "\tHuffman compressed (%4.1f%%).\n", 100.0 * ibytes / (rsrcLength + dataLength)); } } static void stf_wrfork(num, towrite, offs) unsigned long *num, towrite; int offs; { int c, k, max, i, i1; char *tmp_out_ptr; while(*num < towrite) { if((*num & 0xfff) == 0) { clrhuff(); c = getb(infp) & 0xff; k = c; max = 0; for(i = 0; i < k; i++) { c = getb(infp) & 0xff; nodelist[i + 1].flag = 1; nodelist[i + 1].byte = i + 1; table[i + 1].num = c; table[i + 1].next = 0; if(c > 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 */ macutils/macunpack/pit.h100775 33261 310 1546 5453360600 13507 0ustar mirror#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 macutils/macunpack/globals.h100775 33261 310 456 5453360600 14315 0ustar mirror#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; macutils/macunpack/crc.h100775 33261 310 462 5453360600 13436 0ustar mirror#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)(); macutils/macunpack/bin.c100775 33261 310 3370 5453360600 13453 0ustar mirror#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 */ macutils/macunpack/dir.c100775 33261 310 2515 5453360600 13461 0ustar mirror#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++; } macutils/macunpack/crc.c100775 33261 310 64 5453360600 13407 0ustar mirrorunsigned long crcinit; unsigned long (*updcrc)(); macutils/macunpack/globals.c100775 33261 310 646 5453360600 14311 0ustar mirror#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 */ macutils/macunpack/macbinary.c100775 33261 310 32353 5453360600 14673 0ustar mirror#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 */ macutils/macunpack/lzc.c100775 33261 310 10465 5453360600 13516 0ustar mirror#include "macunpack.h" #ifdef LZC #include "globals.h" #include "lzc.h" #include "../util/util.h" #include "../fileio/machdr.h" #include "../fileio/wrfile.h" #include "../util/masks.h" extern void de_compress(); extern void core_compress(); extern void mcb(); static void lzc_zivm(); static void lzc_wrfile(); static void lzc_zivu(); void lzc(ohdr) char *ohdr; { core_compress((char *)NULL); if(!strncmp(ohdr + I_TYPEOFF, "ZIVM", 4)) { lzc_zivm(ohdr); } else { lzc_zivu(ohdr); } } static void lzc_zivm(ohdr) char *ohdr; { char hdr[HEADERBYTES]; unsigned long dataLength, rsrcLength, dataCLength, rsrcCLength; char ftype[5], fauth[5]; if(fread(hdr, 1, HEADERBYTES, infp) != HEADERBYTES) { (void)fprintf(stderr, "Can't read file header\n"); #ifdef SCAN do_error("macunpack: Can't read file header"); #endif /* SCAN */ exit(1); } if(strncmp(hdr, MAGIC1, 4)) { (void)fprintf(stderr, "Magic header mismatch\n"); #ifdef SCAN do_error("macunpack: Magic header mismatch"); #endif /* SCAN */ exit(1); } dataLength = get4(hdr + C_DLENOFF); dataCLength = get4(hdr + C_DLENOFFC); rsrcLength = get4(hdr + C_RLENOFF); rsrcCLength = get4(hdr + C_RLENOFFC); write_it = 1; if(list) { copy(info, ohdr, INFOBYTES); copy(info + I_TYPEOFF, hdr + C_TYPEOFF, 4); copy(info + I_AUTHOFF, hdr + C_AUTHOFF, 4); copy(info + I_DLENOFF, hdr + C_DLENOFF, 4); copy(info + I_RLENOFF, hdr + C_RLENOFF, 4); copy(info + I_CTIMOFF, hdr + C_CTIMOFF, 4); copy(info + I_MTIMOFF, hdr + C_MTIMOFF, 4); copy(info + I_FLAGOFF, hdr + C_FLAGOFF, 8); transname(ohdr + I_NAMEOFF + 1, text, (int)ohdr[I_NAMEOFF]); transname(hdr + C_TYPEOFF, ftype, 4); transname(hdr + C_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(); } lzc_wrfile(dataLength, dataCLength); if(verbose) { (void)fprintf(stderr, ", Rsrc: "); } if(write_it) { start_rsrc(); } lzc_wrfile(rsrcLength, rsrcCLength); if(write_it) { end_file(); } if(verbose) { (void)fprintf(stderr, ".\n"); } } static void lzc_wrfile(obytes, ibytes) unsigned long obytes, ibytes; { int n, nbits; char subheader[3]; if(ibytes == 0) { if(verbose) { (void)fprintf(stderr, "empty"); } return; } if(ibytes == obytes) { 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); } } else { n = ibytes; 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 { 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 */ macutils/macunpack/lzh.c100775 33261 310 44423 5453360600 13524 0ustar mirror#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 */ macutils/macunpack/zma.c100775 33261 310 22470 5453360600 13514 0ustar mirror#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 */ macutils/macunpack/cpt.c100775 33261 310 42551 5453360600 13515 0ustar mirror#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 */ macutils/macunpack/makefile100775 33261 310 10712 5453360600 14255 0ustar mirrorCFLAGS = -O $(CF) SRCS = macunpack.c \ globals.c \ macbinary.c \ dir.c \ mcb.c \ bin.c \ jdw.c \ stf.c \ lzc.c \ pit.c \ sit.c \ dia.c \ cpt.c \ zma.c \ lzh.c \ dd.c \ de_huffman.c \ de_compress.c \ de_lzah.c \ de_lzh.c \ crc.c \ bits_be.c OBJS = macunpack.o \ globals.o \ macbinary.o \ dir.o \ mcb.o \ bin.o \ jdw.o \ stf.o \ lzc.o \ pit.o \ sit.o \ dia.o \ cpt.o \ zma.o \ lzh.o \ dd.o \ de_huffman.o \ de_compress.o \ de_lzah.o \ de_lzh.o \ crc.o \ bits_be.o LIB = ../crc/libcrc.a TNAME = ../util/transname UNAME = ../util/util ONAME = ../fileio/wrfile GNAME = ../fileio/fileglob XOBJS = $(TNAME).o $(UNAME).o $(ONAME).o $(GNAME).o XSRCS = $(TNAME).c $(UNAME).c $(ONAME).c $(GNAME).c CRCS = ../crc/arc.c ../crc/binhex.c ../crc/zip.c macunpack: $(OBJS) $(LIB) $(XOBJS) $(CC) $(CFLAGS) -o macunpack $(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)" ) $(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 macunpack macunpack.o: macunpack.h macunpack.o: globals.h macunpack.o: ../util/patchlevel.h macunpack.o: ../fileio/wrfile.h macunpack.o: ../fileio/wrfileopt.h macunpack.o: ../fileio/kind.h macunpack.o: ../util/util.h globals.o: globals.h globals.o: ../fileio/machdr.h globals.o: ../fileio/wrfile.h globals.o: ../fileio/kind.h macbinary.o: macunpack.h macbinary.o: globals.h macbinary.o: zmahdr.h macbinary.o: ../fileio/machdr.h macbinary.o: ../fileio/wrfile.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 bin.o: macunpack.h bin.o: globals.h bin.o: ../fileio/machdr.h bin.o: ../fileio/wrfile.h bin.o: ../fileio/kind.h bin.o: ../util/util.h bin.o: ../util/masks.h jdw.o: macunpack.h jdw.o: jdw.h jdw.o: globals.h jdw.o: huffman.h jdw.o: ../fileio/wrfile.h jdw.o: ../fileio/machdr.h jdw.o: ../util/util.h jdw.o: ../util/masks.h stf.o: macunpack.h stf.o: stf.h stf.o: globals.h stf.o: huffman.h stf.o: ../util/curtime.h stf.o: ../fileio/wrfile.h stf.o: ../fileio/machdr.h stf.o: ../util/util.h lzc.o: macunpack.h lzc.o: globals.h lzc.o: lzc.h lzc.o: ../util/util.h lzc.o: ../fileio/machdr.h lzc.o: ../fileio/wrfile.h lzc.o: ../util/masks.h pit.o: macunpack.h pit.o: ../fileio/fileglob.h pit.o: ../fileio/wrfile.h pit.o: ../fileio/kind.h pit.o: globals.h pit.o: pit.h pit.o: ../fileio/machdr.h pit.o: crc.h pit.o: ../util/masks.h pit.o: ../util/util.h pit.o: huffman.h sit.o: macunpack.h sit.o: globals.h sit.o: sit.h sit.o: crc.h sit.o: ../util/util.h sit.o: ../fileio/machdr.h sit.o: ../fileio/wrfile.h sit.o: ../fileio/kind.h sit.o: ../util/masks.h sit.o: huffman.h dia.o: macunpack.h dia.o: globals.h dia.o: dia.h dia.o: ../util/curtime.h dia.o: ../util/masks.h dia.o: ../fileio/machdr.h dia.o: ../fileio/wrfile.h dia.o: ../fileio/kind.h dia.o: ../util/util.h cpt.o: macunpack.h cpt.o: globals.h cpt.o: cpt.h cpt.o: crc.h cpt.o: ../util/util.h cpt.o: ../fileio/machdr.h cpt.o: ../fileio/wrfile.h cpt.o: ../fileio/kind.h cpt.o: ../util/masks.h cpt.o: huffman.h zma.o: macunpack.h zma.o: globals.h zma.o: zma.h zma.o: crc.h zma.o: ../fileio/machdr.h zma.o: ../fileio/wrfile.h zma.o: ../fileio/kind.h zma.o: ../util/masks.h zma.o: ../util/util.h lzh.o: macunpack.h lzh.o: globals.h lzh.o: lzh.h lzh.o: crc.h lzh.o: ../fileio/wrfile.h lzh.o: ../fileio/machdr.h lzh.o: ../util/masks.h lzh.o: ../util/util.h lzh.o: bits_be.h dd.o: macunpack.h dd.o: globals.h dd.o: dd.h dd.o: crc.h dd.o: ../fileio/machdr.h dd.o: ../fileio/wrfile.h dd.o: ../fileio/fileglob.h dd.o: ../util/masks.h dd.o: ../util/util.h de_huffman.o: macunpack.h de_huffman.o: globals.h de_huffman.o: ../util/masks.h de_huffman.o: huffman.h de_huffman.o: ../fileio/wrfile.h de_huffman.o: ../util/util.h de_compress.o: macunpack.h de_compress.o: globals.h de_compress.o: ../fileio/wrfile.h de_lzah.o: macunpack.h de_lzah.o: globals.h de_lzah.o: ../util/masks.h de_lzah.o: ../fileio/wrfile.h de_lzh.o: macunpack.h de_lzh.o: globals.h de_lzh.o: ../util/masks.h de_lzh.o: ../fileio/wrfile.h de_lzh.o: bits_be.h bits_be.o: ../util/masks.h bits_be.o: bits_be.h macutils/macunpack/mcb.c100775 33261 310 5037 5453360600 13446 0ustar mirror#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); } 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); } } } } macutils/macunpack/lzc.h100775 33261 310 1127 5453360600 13476 0ustar mirror#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; }; macutils/macunpack/sit.c100775 33261 310 46076 5453360600 13534 0ustar mirror#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 */ macutils/macunpack/pit.c100775 33261 310 14452 5453360600 13522 0ustar mirror#include "macunpack.h" #ifdef PIT #include "../fileio/wrfile.h" #include "../fileio/fileglob.h" #include "../fileio/kind.h" #include "globals.h" #include "pit.h" #include "../fileio/machdr.h" #include "crc.h" #include "../util/masks.h" #include "../util/util.h" #include "huffman.h" extern void read_tree(); extern void de_huffman(); extern void set_huffman(); static int pit_filehdr(); static void pit_wrfile(); static void pit_nocomp(); static void pit_huffman(); void pit() { struct pit_header filehdr; char pithdr[4]; int decode, synced, ch; unsigned long data_crc, crc; updcrc = binhex_updcrc; crcinit = binhex_crcinit; set_huffman(HUFF_BE); synced = 0; while(1) { if(!synced) { if(fread(pithdr, 1, 4, infp) != 4) { (void)fprintf(stderr, "Premature EOF\n"); #ifdef SCAN do_error("macunpack: Premature EOF"); #endif /* SCAN */ exit(1); } } synced = 0; if(strncmp(pithdr, "PEnd", 4) == 0) { break; } if(strncmp(pithdr, "PMa", 3) != 0) { (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); } switch(pithdr[3]) { case 'g': case '4': break; case '5': case '6': if(pithdr[3] == '6') { (void)fprintf(stderr, "DES-"); } (void)fprintf(stderr, "Encrypted file found, trying to sync"); while(!synced) { ch = getb(infp); if(ch == 'P') { pithdr[0] = ch; pithdr[1] = ch = getb(infp); if(ch == 'M') { pithdr[2] = ch = getb(infp); if(ch == 'a') { pithdr[3] = ch = getb(infp); if((ch >= '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 */ macutils/macunpack/de_lzah.c100775 33261 310 15235 5453360600 14334 0ustar mirror#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 */ macutils/fileio/ 40775 33261 310 0 5574773400 11753 5ustar mirrormacutils/fileio/rdfileopt.h100775 33261 310 162 5453360600 14161 0ustar mirrorextern int rdfileopt(); extern void give_rdfileopt(); extern void set_norecurse(); extern char *get_rdfileopt(); macutils/fileio/kind.h100775 33261 310 247 5453360600 13122 0ustar mirror#ifdef SCAN #define UNIX_NAME 0 #define PACK_NAME 1 #define ARCH_NAME 2 #define UNKNOWN 16 #define PROTECTED 17 #define ERROR 32 #define COPY 33 #endif /* SCAN */ macutils/fileio/appledouble.h100775 33261 310 3500 5453360600 14504 0ustar mirror#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; macutils/fileio/rdfile.h100775 33261 310 367 5453360600 13445 0ustar mirror#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(); macutils/fileio/rdfile.c100775 33261 310 64107 5453360600 13502 0ustar mirror#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 */ } macutils/fileio/fileglob.c100775 33261 310 40 5453360600 13722 0ustar mirrorint bytes_read, bytes_written; macutils/fileio/aufs.h100775 33261 310 2532 5453360600 13152 0ustar mirror#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; macutils/fileio/wrfileopt.h100775 33261 310 221 5453360600 14200 0ustar mirrorextern int wrfileopt(); extern void give_wrfileopt(); extern void set_wrfileopt(); extern void set_s_wrfileopt(); extern char *get_wrfileopt(); macutils/fileio/machdr.h100775 33261 310 660 5453360600 13432 0ustar mirror#define INFOBYTES 128 /* The following are copied out of macput.c/macget.c */ #define I_NAMEOFF 1 /* 65 <-> 80 is the FInfo structure */ #define I_TYPEOFF 65 #define I_AUTHOFF 69 #define I_FLAGOFF 73 #define I_LOCKOFF 81 #define I_DLENOFF 83 #define I_RLENOFF 87 #define I_CTIMOFF 91 #define I_MTIMOFF 95 #define F_NAMELEN 63 #define I_NAMELEN 69 /* 63 + strlen(".info") + 1 */ #define INITED_MASK 1 #define PROTCT_MASK 0x40 macutils/fileio/wrfile.c100775 33261 310 45740 5453360600 13527 0ustar mirror#ifdef TYPES_H #include #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 */ } macutils/fileio/makefile100775 33261 310 1054 5453360600 13541 0ustar mirrorCFLAGS= -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 macutils/fileio/fileglob.h100775 33261 310 47 5453360600 13736 0ustar mirrorextern int bytes_read, bytes_written; macutils/fileio/wrfile.h100775 33261 310 441 5453360600 13461 0ustar mirrorextern 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(); macutils/util/ 40775 33261 310 0 5574773402 11463 5ustar mirrormacutils/util/transname.c100775 33261 310 10561 5453360600 13726 0ustar mirror#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 */ } macutils/util/curtime.h100775 33261 310 360 5453360600 13347 0ustar mirror#ifdef TYPES_H #include #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 macutils/util/backtrans.c100775 33261 310 6447 5453360600 13676 0ustar mirror#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; } macutils/util/masks.h100775 33261 310 127 5453360600 13016 0ustar mirror#define NIBBLEMASK 0x0000000f #define BYTEMASK 0x000000ff #define WORDMASK 0x0000ffff macutils/util/patchlevel.h100775 33261 310 75 5453360600 14011 0ustar mirror#define VERSION "2.0b3 (22-OCT-1992)" #define PATCHLEVEL 0 macutils/util/util.h100775 33261 310 721 5453360600 12655 0ustar mirrortypedef 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(); macutils/util/util.c100775 33261 310 6777 5453360600 12711 0ustar mirror#include #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; } macutils/util/makefile100775 33261 310 443 5453360600 13230 0ustar mirrorCFLAGS= -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 macutils/crc/ 40775 33261 310 0 5574773403 11256 5ustar mirrormacutils/crc/makefile100775 33261 310 733 5453360600 13024 0ustar mirrorCFLAGS = -O $(CF) CRCC = arc.c ccitt.c kermit.c binhex.c ccitt32.c zip.c CRCO = arc.o ccitt.o kermit.o binhex.o ccitt32.o zip.o libcrc.a: $(CRCO) ar r libcrc.a $(CRCO) if test -f /usr/bin/ranlib ;\ then \ ranlib libcrc.a ;\ fi clean: -rm -f $(CRCC) $(CRCO) libcrc.a makecrc makecrc.o $(CRCC): makecrc ./makecrc makecrc: makecrc.o cc -O -o makecrc makecrc.o arc.o: arc.c ccitt.o: ccitt.c kermit.o: kermit.c binhex.o: binhex.c ccitt32.o: ccitt32.c zip.o: zip.c macutils/crc/makecrc.c100775 33261 310 10500 5453360600 13126 0ustar mirror/* 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); } macutils/makefile100775 33261 310 3734 5453360600 12301 0ustar mirrorSHELL = /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 macutils/README100775 33261 310 55206 5453360600 11502 0ustar mirrorThis 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"