0
|
1 /* atob: version 4.0
|
|
2 * stream filter to change printable ascii from "btoa" back into 8 bit bytes
|
|
3 * if bad chars, or Csums do not match: exit(1) [and NO output]
|
|
4 *
|
|
5 * Paul Rutter Joe Orost
|
|
6 * philabs!per petsd!joe
|
|
7 */
|
|
8
|
|
9 #include <stdio.h>
|
|
10
|
|
11 #define reg register
|
|
12
|
|
13 #define streq(s0, s1) strcmp(s0, s1) == 0
|
|
14
|
|
15 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
|
|
16
|
|
17 long int Ceor = 0;
|
|
18 long int Csum = 0;
|
|
19 long int Crot = 0;
|
|
20 long int word = 0;
|
|
21 long int bcount = 0;
|
|
22
|
|
23 fatal() {
|
|
24 fprintf(stderr, "bad format or Csum to atob\n");
|
|
25 exit(1);
|
|
26 }
|
|
27
|
|
28 #define DE(c) ((c) - '!')
|
|
29
|
|
30 decode(c)
|
|
31 reg c;
|
|
32 {
|
|
33 if (c == 'z') {
|
|
34 if (bcount != 0) {
|
|
35 fatal();
|
|
36 } else {
|
|
37 byteout(0);
|
|
38 byteout(0);
|
|
39 byteout(0);
|
|
40 byteout(0);
|
|
41 }
|
|
42 } else if ((c >= '!') && (c < ('!' + 85))) {
|
|
43 if (bcount == 0) {
|
|
44 word = DE(c);
|
|
45 ++bcount;
|
|
46 } else if (bcount < 4) {
|
|
47 word = times85(word);
|
|
48 word += DE(c);
|
|
49 ++bcount;
|
|
50 } else {
|
|
51 word = times85(word) + DE(c);
|
|
52 byteout((int)((word >> 24) & 255));
|
|
53 byteout((int)((word >> 16) & 255));
|
|
54 byteout((int)((word >> 8) & 255));
|
|
55 byteout((int)(word & 255));
|
|
56 word = 0;
|
|
57 bcount = 0;
|
|
58 }
|
|
59 } else {
|
|
60 fatal();
|
|
61 }
|
|
62 }
|
|
63
|
|
64 FILE *tmp_file;
|
|
65
|
|
66 byteout(c)
|
|
67 reg c;
|
|
68 {
|
|
69 Ceor ^= c;
|
|
70 Csum += c;
|
|
71 Csum += 1;
|
|
72 if ((Crot & 0x80000000)) {
|
|
73 Crot <<= 1;
|
|
74 Crot += 1;
|
|
75 } else {
|
|
76 Crot <<= 1;
|
|
77 }
|
|
78 Crot += c;
|
|
79 putc(c, tmp_file);
|
|
80 }
|
|
81
|
|
82 main(argc, argv)
|
|
83 char **argv;
|
|
84 {
|
|
85 reg c;
|
|
86 reg long int i;
|
|
87 char tmp_name[100];
|
|
88 char buf[100];
|
|
89 long int n1, n2, oeor, osum, orot;
|
|
90
|
|
91 if (argc != 1) {
|
|
92 fprintf(stderr,"bad args to %s\n", argv[0]);
|
|
93 exit(2);
|
|
94 }
|
|
95 sprintf(tmp_name, "/usr/tmp/atob.%x", getpid());
|
|
96 tmp_file = fopen(tmp_name, "w+");
|
|
97 if (tmp_file == NULL) {
|
|
98 fatal();
|
|
99 }
|
|
100 unlink(tmp_name); /* Make file disappear */
|
|
101 /*search for header line*/
|
|
102 for (;;) {
|
|
103 if (fgets(buf, sizeof buf, stdin) == NULL) {
|
|
104 fatal();
|
|
105 }
|
|
106 if (streq(buf, "xbtoa Begin\n")) {
|
|
107 break;
|
|
108 }
|
|
109 }
|
|
110
|
|
111 while ((c = getchar()) != EOF) {
|
|
112 if (c == '\n') {
|
|
113 continue;
|
|
114 } else if (c == 'x') {
|
|
115 break;
|
|
116 } else {
|
|
117 decode(c);
|
|
118 }
|
|
119 }
|
|
120 if(scanf("btoa End N %ld %lx E %lx S %lx R %lx\n",
|
|
121 &n1, &n2, &oeor, &osum, &orot) != 5) {
|
|
122 fatal();
|
|
123 }
|
|
124 if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
|
|
125 fatal();
|
|
126 } else {
|
|
127 /*copy OK tmp file to stdout*/;
|
|
128 fseek(tmp_file, 0L, 0);
|
|
129 for (i = n1; --i >= 0;) {
|
|
130 putchar(getc(tmp_file));
|
|
131 }
|
|
132 }
|
|
133 exit(0);
|
|
134 }
|