/* atob: version 4.0 * stream filter to change printable ascii from "btoa" back into 8 bit bytes * if bad chars, or Csums do not match: exit(1) [and NO output] * * Paul Rutter Joe Orost * philabs!per petsd!joe * * Hacked on somewhat by der Mouse to (a) remove ASCII dependency, (b) port * to gcc -Wstrict-prototypes -Wmissing-prototypes, and (c) generally clean * up the code. It should now work right on >32-bit machines. */ #include #include #include #include extern char *__progname; #include "common.h" static unsigned long int word = 0; static int bcount = 0; static int fast_way = -1; static FILE *outf; static void fatal(const char *fmt, ...) { va_list ap; fprintf(stderr,"%s: invalid input file (",__progname); va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); fprintf(stderr,")\n"); exit(1); } static void byteout(int c) { dochecksum(c); putc(c,outf); } static void decode(int ch) { if (fast_way < 0) { int i; for (i=1;digits[i];i++) if (digits[i-1] != digits[i]-1) break; fast_way = !digits[i]; } if (ch == zdig) { if (bcount != 0) { fatal("zero on wrong boundary"); } else { byteout(0); byteout(0); byteout(0); byteout(0); } } else { int d; if (fast_way) { d = ch - digits[0]; if ((d < 0) || (d >= 85)) { fatal("invalid digit (%c)",ch); } } else { const char *dp; dp = index(&digits[0],ch); if (! dp) fatal("invalid digit (%c)",ch); d = dp - &digits[0]; } switch (bcount) { case 0: word = d; bcount ++; break; case 1: case 2: case 3: word = (word * 85) + d; bcount ++; break; default: word = (word * 85) + d; byteout((word>>24)&0xff); byteout((word>>16)&0xff); byteout((word>> 8)&0xff); byteout((word )&0xff); bcount = 0; break; } } } int main(int, char **); int main(int ac, char **av) { int force; char buf[100]; int ch; if ((ac > 1) && !strcmp(av[1],"-f")) { force = 1; ac --; av ++; } else { force = 0; } if (ac != 1) { fprintf(stderr,"%s: bad args (usage: %s [-f])\n",__progname,__progname); exit(1); } if (force) { outf = stdout; } else { outf = tmpfile(); if (outf == 0) fatal("can't open temp file"); } do { if (fgets(&buf[0],sizeof(buf),stdin) != &buf[0]) fatal("no header line found"); } while (strcmp(&buf[0],"xbtoa Begin\n")); while ((ch=getchar()) != EOF) { if (ch == '\n') { continue; } else if (ch == endmarker) { break; } else { decode(ch); } } if (! force) { long int n1; long int n2; long int oeor; long int osum; long int orot; if (scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1,&n2,&oeor,&osum,&orot) != 5) { fatal("ending line mangled"); } if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) { fatal("checksum mismatch"); } rewind(outf); for (;n1>0;n1--) { putchar(getc(outf)); } } exit(0); }