chiark / gitweb /
Import fastforward 0.51
[fastforward] / printforward.c
1 #include "substdio.h"
2 #include "subfd.h"
3 #include "strerr.h"
4 #include "stralloc.h"
5 #include "cdb.h"
6
7 #define FATAL "printmaillist: fatal: "
8
9 void badformat()
10 {
11   strerr_die2x(100,FATAL,"bad database format");
12 }
13 void nomem()
14 {
15   strerr_die2x(111,FATAL,"out of memory");
16 }
17
18 void getch(ch)
19 char *ch;
20 {
21   int r;
22   r = substdio_get(subfdinsmall,ch,1);
23   if (r == -1)
24     strerr_die2sys(111,FATAL,"unable to read input: ");
25   if (r == 0)
26     badformat();
27 }
28
29 void putch(ch)
30 char *ch;
31 {
32   if (substdio_put(subfdoutsmall,ch,1) == -1)
33     strerr_die2x(111,FATAL,"unable to write output: ");
34 }
35
36 void print(buf)
37 char *buf;
38 {
39   while (*buf)
40     putch(buf++);
41 }
42
43 void printsafe(buf,len)
44 char *buf;
45 int len;
46 {
47   char ch;
48
49   while (len) {
50     ch = *buf;
51     if ((ch <= 32) || (ch == ',') || (ch == ':') || (ch == ';') || (ch == '\\') || (ch == '#'))
52       putch("\\");
53     putch(&ch);
54     ++buf;
55     --len;
56   }
57 }
58
59 stralloc key = {0};
60 stralloc data = {0};
61
62 void main()
63 {
64   uint32 eod;
65   uint32 pos;
66   uint32 klen;
67   uint32 dlen;
68   char buf[8];
69   char ch;
70   int i;
71   int j;
72
73   for (i = 0;i < 4;++i) getch(buf + i);
74   eod = cdb_unpack(buf);
75
76   for (i = 4;i < 2048;++i) getch(&ch);
77
78   pos = 2048;
79   while (pos < eod) {
80     if (eod - pos < 8) badformat();
81     pos += 8;
82     for (i = 0;i < 8;++i) getch(buf + i);
83     klen = cdb_unpack(buf);
84     dlen = cdb_unpack(buf + 4);
85
86     if (!stralloc_copys(&key,"")) nomem();
87     if (eod - pos < klen) badformat();
88     pos += klen;
89     while (klen) {
90       --klen;
91       getch(&ch);
92       if (!stralloc_append(&key,&ch)) nomem();
93     }
94
95     if (eod - pos < dlen) badformat();
96     pos += dlen;
97     if (!stralloc_copys(&data,"")) nomem();
98     while (dlen) {
99       --dlen;
100       getch(&ch);
101       if (!stralloc_append(&data,&ch)) nomem();
102     }
103
104     if (!key.len) badformat();
105     if (key.s[0] == '?') {
106       printsafe(key.s + 1,key.len - 1);
107       print(": ?");
108       printsafe(data.s,data.len);
109       print(";\n");
110     }
111     else if (key.s[0] == ':') {
112       printsafe(key.s + 1,key.len - 1);
113       print(":\n");
114
115       i = 0;
116       for (j = 0;j < data.len;++j)
117         if (!data.s[j]) {
118           if ((data.s[i] == '.') || (data.s[i] == '/')) {
119             print(", ");
120             printsafe(data.s + i,j - i);
121             print("\n");
122           }
123           else if ((data.s[i] == '|') || (data.s[i] == '!')) {
124             print(", ");
125             printsafe(data.s + i,j - i);
126             print("\n");
127           }
128           else if ((data.s[i] == '&') && (j - i < 900)) {
129             print(", ");
130             printsafe(data.s + i,j - i);
131             print("\n");
132           }
133           else badformat();
134           i = j + 1;
135         }
136       if (i != j) badformat();
137       print(";\n");
138     }
139     else badformat();
140   }
141
142   if (substdio_flush(subfdoutsmall) == -1)
143     strerr_die2sys(111,FATAL,"unable to write output: ");
144   _exit(0);
145 }