Mercurial > hg > Applications > mh
comparison miscellany/compress-4.0/atob.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
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 } |