straka@ihlpf.UUCP (02/17/87)
A while ago, some code was posted which stripped out file header info from netnews Mac binaries, leaving a clean, downloadable file suitable for BinHex. The author admitted that it was a bit of a hack, as it "even used gotos". I took a fresh look at the problem, and came up with the following code. It is rather simple, but given simple stdin, stdout, stderr, and one BinHex file per invocation, it seems pretty robust. (and NO gotos!) A typical invocation might look like: bhcomb <camera[1-5].net >camera 2>camera.doc || echo ^G bhcomb Failed! It was developed under SYS V.2. Use it in good health. Please excuse me if this doesn't really belong in unmoderated comp.sys.mac. (It isn't that big.) Rich Straka ihnp4!ihlpf!straka ------------------------------cut here ---8<----8<----8<------------------ /* bhcomb.c: combine and strip header information from BinHexed files. assumes the following structure: several lines of unrelated header (This file must be converted by BinHex 4.0) :123456789012345678901234567890123456789012345678901234567890123 1234567890123456789012345678901234567890123456789012345678901234 . . . 1234567890123456789012345678901234567890123456789012345678901234 1234...4321: several lines of unrelated footer Additional unrelated headers and/or footers may be present within the data stream. The actual data is prepended with "(This file... BinHex 4.0)" and an extra blank line. The actual data begins with a framing ":" (not checked) The actual data must end with a framing ":" All data lines (except the last) are of the same length (default=64). The last data line is of random length, and ends with the ":". Certain characters are never seen within the BinHex portion: nothing < \012 nothing > \012, yet < \040 no spaces no . / ; < = > ? O g n o s t u v w x y z { } characters no | ~ \ ] ^ _ characters nothing > \176 Data is gathered through stdin. Good data is sent to stdout. Bad data and diagnostics are sent to stderr. A shell line (or procedure) of the following form is recommednded: bhcomb <camera[1-5].net >camera 2>camera.doc || echo ^G bhcomb Failed! BUGS: More than one BinHexed file per invocation ignores all but the first file. Does not check for additional ":"s inside of the valid portion of the data. */ #include <stdio.h> #include <string.h> #define LENGTH 64 /* LENGTH = default BinHex line length = 64 */ main(argc,argv) { int valid=0, started=0, lth; /* started = "we have started collecting valid BinHex data" valid = "the last line encountered was a valid BinHex line" lth = line length */ char inline[256]; while (gets (inline) >0) { if (strncmp (inline,"(This file must be converted with BinHex 4.0)",45)==0) { if (started != 0) /* Have we already started? */ /* If so, something is wrong! */ { started=0; /* Unused hook for multiple files */ fprintf(stderr,"%s\n",inline); /* Print it */ fprintf(stderr,"More than one BinHex file!"); /*ERROR*/ exit (1); } else { printf("%s\n",inline); gets (inline); /* read dummy blank line */ printf("\n"); /* put out dummy blank line */ valid=1; /* This line of data is valid */ started=1; /* We started data gathering */ } } else { lth=strlen (inline); if (badchars (inline,lth) != 0) /* Do we have illegal chars? */ { fprintf(stderr,"%s\n",inline); /* Put to stderr */ valid=0; /* Line not valid */ } else { /* All chars OK */ if (strlen (inline) != LENGTH) /* if bad line length */ { if (valid!=1) /*not expecting last line with :*/ { fprintf(stderr,"%s\n",inline); /*bad line*/ valid=0; /* Line not valid */ } else /*expecting last line with : */ { if (findcolon (inline) == 0) /* if colon at end of line */ { printf("%s\n",inline); /* last line */ started=2; /* FINISHED */ exit (0); /* NORMAL EXIT */ } else { fprintf(stderr,"%s\n",inline); valid=0; /* bad line */ } } } else { printf("%s\n",inline); /* Good line */ valid=1; } } } } fprintf(stderr,"Improper EOF; no ending colon!\n"); /* should never get here */ exit (2); } badchars(lptr,length) /* Look for illegal characters */ char *lptr; int length; { int badchar, p; char c; c='a'; badchar=0; for (p=0;p<length;p++) { c=lptr[p]; if (c < '\n') {badchar=1; break;} if (c > '\n' && c < '!') {badchar=1; break;} if (c > '-' && c < 0) {badchar=1; break;} if (c > ':' && c < '@') {badchar=1; break;} if (c == 'O') {badchar=1; break;} if (c > '[' && c < '`') {badchar=1; break;} if (c == 'g') {badchar=1; break;} if (c > 'n' && c < 'o') {badchar=1; break;} if (c > 's') {badchar=1; break;} } return (badchar); } findcolon(lptr) /* Look for : at end of line */ char *lptr; { int p; p=strlen(lptr); while (lptr[p--]=='\n') ; /* get rid of all possible trailing \n_s */ if (lptr[p]==':') { return (0); } else { return (1); } } ------------------------------cut here ---8<----8<----8<------------------ -- Rich Straka ihnp4!ihlpf!straka