/* * a2b2t * stream filter equivalent to "atob | b2t" in one combined program. * This is intended for converting HKU news (encoded using btoa) * into Taipei-100 readable Hanzi. * * atob code by Paul Rutter & Joe Orost * b2t code and a2b2t by Pai Chou */ #define A2B2T /* * ===== original atob code ===== * modification: instead of dumping the file, the file is read in * by b2t instead and written to standard out. */ /* atob * 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 */ #include #define reg register #define streq(s0, s1) strcmp(s0, s1) == 0 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) long int Ceor = 0; long int Csum = 0; long int Crot = 0; long int word = 0; long int bcount = 0; fatal() { fprintf(stderr, "bad format or Csum to atob\n"); exit(1); } #define DE(c) ((c) - '!') decode(c) reg c; { if (c == 'z') { if (bcount != 0) { fatal(); } else { byteout(0); byteout(0); byteout(0); byteout(0); } } else if ((c >= '!') && (c < ('!' + 85))) { if (bcount == 0) { word = DE(c); ++bcount; } else if (bcount < 4) { word = times85(word); word += DE(c); ++bcount; } else { word = times85(word) + DE(c); byteout((int)((word >> 24) & 255)); byteout((int)((word >> 16) & 255)); byteout((int)((word >> 8) & 255)); byteout((int)(word & 255)); word = 0; bcount = 0; } } else { fatal(); } } FILE *tmp_file; byteout(c) reg c; { Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; putc(c, tmp_file); } main(argc, argv) char **argv; { reg c; reg long int i; char tmp_name[100]; char buf[100]; long int n1, n2, oeor, osum, orot; if (argc != 1) { fprintf(stderr,"bad args to %s\n", argv[0]); exit(2); } sprintf(tmp_name, "/usr/tmp/atob.%x", getpid()); tmp_file = fopen(tmp_name, "w+"); if (tmp_file == NULL) { fatal(); } unlink(tmp_name); /* Make file disappear */ /*search for header line*/ for (;;) { if (fgets(buf, sizeof buf, stdin) == NULL) { fatal(); } if (streq(buf, "xbtoa Begin\n")) { break; } } while ((c = getchar()) != EOF) { if (c == '\n') { continue; } else if (c == 'x') { break; } else { decode(c); } } if (scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, & orot) != 5) { fatal(); } if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) { fatal(); } else { /* Now that we know everything is OK, copy tmp file to stdout */ fseek(tmp_file, 0L, 0); #ifdef A2B2T /* this has been added for a2b2t */ taipei_main(); unlink(tmp_name); /* Make file disappear */ #else for (i = n1; --i >= 0;) { putchar(getc(tmp_file)); } #endif } exit(0); } #ifdef A2B2T /* b2t : binary -> T3 converter for Taipei-100 and TaipeiTerm. written by Pai Chou */ typedef unsigned char uchar; #define COLUMNS 80 void C2A_(c, a) uchar *c, *a; { uchar temp; if (c[1] >= 0xB0) { a[0] = '^'; } else { a[0] = '`'; } temp = c[0] - 0xA1 + 0x21; if (temp >= '^') temp += 3; a[1] = temp; temp = c[1]; if (temp >= 0xA0) temp -= 0x20; temp = (temp & 0xF) + (((temp >>4) - 4) % 5) * 0x10 + 0x21; if (temp >= '^') temp += 3; a[2] = temp; } taipei_main() { uchar c[2], d[4]; int thisLen, len = 0; while (!feof(tmp_file)) { c[0] = fgetc(tmp_file); if (c[0] >= 0x80) { if (feof(tmp_file)) exit(-1); c[1] = fgetc(tmp_file); C2A_(c, d); thisLen = 3; } else { if (c[0]=='\n') { len = -1; } thisLen = 1; d[0] = c[0]; } len += thisLen; if (len >= COLUMNS) { putchar('\n'); len = 0; } d[thisLen] = '\0'; printf("%s",d); } } #endif