Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / miscellany / compress-4.0 / atob.c
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 }