/* * mwrescue.c -- rescue a damaged MacWrite file (version 3.0 and later) * * Versions of MacWrite after 3.0 and before 4.0 have been unreliable. * This program decodes damaged MacWrite files and recovers the text in * them (once you've uploaded them to Unix). Someone should get it * running on the native Mac. * * It is currently very simple since it treats the entire file as compacted * text. However, MacWrite files can also contain some uncompacted text * and some formatting information. The uncompacted text can be retrieved * with the Unix strings command. The formatting information is output by * this program as nonsense text. * * The text retrieved by this program emerges in the order it is stored in * the file by MacWrite, which is not necessarily the order in which it is * supposed to appear in the document. * * As primitive as this program is, I'm releasing it because: * 1) I hope someone will improve it. * 2) I've found that panicked students are more than glad to get * their papers back even if the paragraphs are in random * order with garbage text in between. * * History: * * 5/11/85 Winkler Created * */ #include #include #define TRUE 1 #define FALSE 0 /* Compressed characters for English. MacWrite stores this string * in the resource fork of the document. A future improvement would * be to find the string there (presumably in file.rsrc on Unix) rather * than assume this one. */ char compchars[] = {' ', 'e', 't', 'n', 'r', 'o', 'a', 'i', 's', 'd', 'l', 'h', 'c', 'f', 'p', '\n' } ; main() /* read encoded file from stdin and write text to stdout */ { int c ; do { c = getnibble() ; if ( c != 0x0000000f ) macputchar( compchars[c] ) ; else { int c2 ; c = getnibble() ; c2 = getnibble() ; /* need variables because C doesn't guarantee * the order of evaluation of arguments. So if * c and c2 below were replaced by getnibble()'s * there would be no way of knowing which of the * next two nibbles on stdin would be shifted */ macputchar( (c << 4) + c2 ) ; } } while ( TRUE ) ; /* infinite loop. getnibble() exits on EOF */ } macputchar( c ) /* translate returns to newlines and suppress nonprinting characters */ int c; { if ( isprint(c) ) { if ( c != '\r' ) putchar(c) ; else putchar('\n'); } } getnibble() /* return the next nibble from stdin. exits on EOF. */ { static int got = FALSE ; static int c ; if ( ! got ) { if ( (c = getchar()) == EOF ) exit(1) ; got = TRUE ; return ( ( c >> 4 ) & 0x0000000f) ; } else { got = FALSE ; return (c & 0x0000000f) ; } }