mess822x 1.23
mess822x
Loading...
Searching...
No Matches
822print.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <time.h>
4#include "buffer.h"
5#include "getln.h"
6#include "mess822.h"
7#include "logmsg.h"
8#include "exit.h"
9#include "leapsecs.h"
10#include "caltime.h"
11#include "tai.h"
12#include "logmsg.h"
13#include "str.h"
14#include "byte.h"
15
16#define WHO "822print"
17
18static void nomem()
19{
20 logmsg(WHO,111,FATAL,"out of memory");
21}
22
23static void putspaces(int len)
24{
25 while (len-- > 0) buffer_put(buffer_1," ",1);
26}
27
28static void putformat(char *buf,unsigned int len)
29{
30 while (len > 1) {
31 switch(*buf++) {
32 case '_':
33 buffer_put(buffer_1,"_\010",2);
34 break;
35 case '+':
36 buffer_put(buffer_1,buf,1);
37 buffer_put(buffer_1,"\010",1);
38 break;
39 }
40 buffer_put(buffer_1,buf++,1);
41 len -= 2;
42 }
43}
44
45static void format(stralloc *out,char *buf,int len,char *pre,char *style1,char *style2)
46{
47 char ch;
48 char ch2;
49
50 if (!stralloc_copys(out,pre)) nomem();
51
52 while (len--) {
53 ch = *buf++;
54 if (ch == '\n') ch = 0;
55 if (ch == '\t') ch = ' ';
56 if ((ch >= 32) && (ch <= 126)) {
57 if (!stralloc_append(out,style1)) nomem();
58 if (!stralloc_append(out,&ch)) nomem();
59 continue;
60 }
61
62 if (!stralloc_cats(out,style2)) nomem();
63 if (!stralloc_append(out,"\\")) nomem();
64 ch2 = '0' + (ch >> 6);
65 if (!stralloc_cats(out,style2)) nomem();
66 if (!stralloc_append(out,&ch2)) nomem();
67 ch2 = '0' + (7 & (ch >> 3));
68 if (!stralloc_cats(out,style2)) nomem();
69 if (!stralloc_append(out,&ch2)) nomem();
70 ch2 = '0' + (7 & ch);
71 if (!stralloc_cats(out,style2)) nomem();
72 if (!stralloc_append(out,&ch2)) nomem();
73 }
74}
75
76stralloc leftline = {0};
77stralloc rightline = {0};
78stralloc tmp = {0};
79
80static void doleft()
81{
82 int len;
83 int pos;
84 int i;
85
86 len = leftline.len / 2;
87 pos = 0;
88 while (len > 73) {
89 i = byte_rchr(leftline.s + pos,73 * 2,' ') / 2; /*XXX*/
90 if (!i) i = 73;
91 putformat(leftline.s + pos,i * 2);
92 buffer_puts(buffer_1,"\n");
93 len -= i;
94 pos += 2 * i;
95 }
96 putformat(leftline.s + pos,len * 2);
97 buffer_puts(buffer_1,"\n");
98}
99
100static void doleftright()
101{
102 int leftxlen;
103 int leftxpos;
104 int rightxlen;
105 int rightxpos;
106 int i;
107 int j;
108
109 rightxlen = rightline.len / 2;
110 leftxlen = leftline.len / 2;
111
112 leftxpos = 0;
113 rightxpos = 0;
114
115 while (leftxlen + rightxlen > 76) {
116 i = 50;
117 if (i > leftxlen) i = leftxlen;
118 j = 50;
119 if (j > rightxlen) j = rightxlen;
120 if (i + j > 76) j = 76 - i;
121
122 putformat(leftline.s + leftxpos,i * 2);
123 putspaces(78 - i - j);
124 putformat(rightline.s + rightxpos,j * 2);
125 buffer_put(buffer_1,"\n",1);
126 leftxlen -= i;
127 leftxpos += 2 * i;
128 rightxlen -= j;
129 rightxpos += 2 * j;
130 }
131
132 putformat(leftline.s + leftxpos,leftxlen * 2);
133 putspaces(78 - leftxlen - rightxlen);
134 putformat(rightline.s + rightxpos,rightxlen * 2);
135 buffer_put(buffer_1,"\n",1);
136}
137
138static void putvalue(stralloc *a,char *pre)
139{
140 int j;
141
142 j = a->len;
143 if (j && (a->s[j - 1] == '\n')) --j;
144 format(&rightline,a->s,j,"","_","=");
145 format(&leftline,"",0,pre,"=","_");
146
147 doleftright();
148}
149
150static void putfields(stralloc *a)
151{
152 int j;
153 int i;
154
155 for (j = i = 0; j < a->len; ++j)
156 if (a->s[j] == '\n') {
157 format(&leftline,a->s + i,j - i,"","=","_");
158 doleft();
159 i = j + 1;
160 }
161}
162
163static void putaddr(stralloc *a,char *pre,char *post,char *style)
164{
165 int i;
166 int j;
167 int comment;
168 char *addr;
169
170 comment = 0;
171 for (j = i = 0; j < a->len; ++j)
172 if (!a->s[j]) {
173 if (a->s[i] == '(') {
174 if (comment) {
175 format(&leftline,a->s + comment,str_len(a->s + comment),pre,"_","=");
176 doleft();
177 }
178 comment = i + 1;
179 }
180 else if (a->s[i] == '+') {
181 addr = a->s + i + 1;
182 /* XXX: replace addr with nickname? */
183 if (comment)
184 format(&leftline,a->s + comment,str_len(a->s + comment),pre,"_","=");
185 else
186 format(&leftline,"",0,pre,"=","_");
187 format(&rightline,addr,str_len(addr),post,style,"_");
188 doleftright();
189 comment = 0;
190 }
191 i = j + 1;
192 }
193
194 if (comment) {
195 format(&leftline,a->s + comment,str_len(a->s + comment),pre,"_","=");
196 doleft();
197 }
198}
199
200static void putdate(stralloc *text,mess822_time *t)
201{
202 struct tai sec;
203 unsigned char secpack[TAI_PACK];
204 time_t secunix;
205 struct tm *tm;
206 struct caltime local;
207 int j;
208
209 j = text->len;
210 if (j && (text->s[j - 1] == '\n')) --j;
211 format(&leftline,text->s,j,"=D=a=t=e=:","=","_");
212 if (!t->known) {
213 doleft();
214 return;
215 }
216
217 caltime_tai(&t->ct,&sec);
218 tai_pack((char *)secpack,&sec);
219 secunix = secpack[0] - 64;
220 secunix = (secunix << 8) + secpack[1];
221 secunix = (secunix << 8) + secpack[2];
222 secunix = (secunix << 8) + secpack[3];
223 secunix = (secunix << 8) + secpack[4];
224 secunix = (secunix << 8) + secpack[5];
225 secunix = (secunix << 8) + secpack[6];
226 secunix = (secunix << 8) + secpack[7];
227 secunix -= 10;
228
229 tm = localtime(&secunix);
230 local.offset = 0;
231 local.date.year = tm->tm_year + 1900;
232 local.date.month = tm->tm_mon + 1;
233 local.date.day = tm->tm_mday;
234 local.hour = tm->tm_hour;
235 local.minute = tm->tm_min;
236 local.second = tm->tm_sec;
237
238 if (!stralloc_ready(&tmp,caltime_fmt((char *) 0,&local))) nomem();
239 tmp.len = caltime_fmt(tmp.s,&local) - 6;
240
241 format(&rightline,tmp.s,tmp.len,"","_","=");
242 doleftright();
243}
244
245stralloc returnpath = {0};
246stralloc envelope = {0};
247stralloc threading = {0};
248stralloc mid = {0};
249stralloc refs = {0};
250
251stralloc subject = {0};
252
253stralloc dates = {0};
255
256stralloc to = {0};
257stralloc cc = {0};
258stralloc bcc = {0};
259stralloc nrudt = {0};
260
261stralloc from = {0};
262stralloc sender = {0};
263stralloc replyto = {0};
264stralloc mailreplyto = {0};
265stralloc followupto = {0};
266stralloc spf = {0};
267stralloc dkim = {0};
268stralloc qdkim = {0};
269
270stralloc misc = {0};
271
274 { "date", 0, 0, &dates, 0, &date, 0 }
275, { "subject", 0, 0, &subject, 0, 0, 0 }
276, { "to", 0, 0, 0, &to, 0, 0 }
277, { "cc", 0, 0, 0, &cc, 0, 0 }
278, { "bcc", 0, 0, 0, &bcc, 0, 0 }
279, { "apparently-to", 0, 0, 0, &bcc, 0, 0 }
280, { "notice-requested-upon-delivery-to", 0, 0, 0, &nrudt, 0, 0 }
281, { "from", 0, 0, 0, &from, 0, 0 }
282, { "sender", 0, 0, 0, &sender, 0, 0 }
283, { "reply-to", 0, 0, 0, &replyto, 0, 0 }
284, { "mail-reply-to", 0, 0, 0, &mailreplyto, 0, 0 }
285, { "mail-followup-to", 0, 0, 0, &followupto, 0, 0 }
286, { "message-id", 0, 0, 0, &mid, 0, 0 }
287, { "references", 0, 0, 0, &refs, 0, 0 }
288, { "in-reply-to", 0, &threading, 0, 0, 0, 0 }
289, { "return-path", 0, 0, 0, &returnpath, 0, 0 }
290, { "received:", 0, &envelope, 0, 0, 0, 0 }
291, { "received-spf", 0, 0, &spf, 0 , 0, 0 } // poorly chosen header identifier
292, { "dkim", 0, 0, &dkim, 0 , 0, 0 }
293, { "x-authentication-results", 0, 0, &qdkim, 0 , 0, 0 } // s/qmail extension
294, { "arc-", 0, 0, &dkim, 0, 0, 0 }
295, { "delivered-to", 0, &envelope, 0, 0, 0, 0 }
296, { "errors-to", 0, &envelope, 0, 0, 0, 0 }
297, { "resent-sender", 0, &envelope, 0, 0, 0 }
298, { "resent-from", 0, &envelope, 0, 0, 0, 0 }
299, { "resent-reply-to", 0, &envelope, 0, 0, 0, 0 }
300, { "resent-to", 0, &envelope, 0, 0, 0, 0 }
301, { "resent-cc", 0, &envelope, 0, 0, 0, 0 }
302, { "resent-bcc", 0, &envelope, 0, 0, 0, 0 }
303, { "resent-date", 0, &envelope, 0, 0, 0, 0 }
304, { "resent-message-id", 0, &envelope, 0, 0, 0, 0 }
305, { 0, 0, &misc, 0, 0, 0, 0 }
306} ;
307
308static void finishheader()
309{
310 if (!mess822_end(&h)) nomem();
311
312 putvalue(&subject,"=S=u=b=j=e=c=t=:");
313 putaddr(&from,"=F=r=o=m=:= ","","+");
314
315 putdate(&dates,&date);
316
317 putaddr(&returnpath,"=R=e=t=u=r=n=-=P=a=t=h=:= ","=r=e=t=u=r=n= ","+");
318 putfields(&envelope);
319 putfields(&threading);
320 putaddr(&refs,"=R=e=f=:= ","","_");
321 putaddr(&mid,"=M=e=s=s=a=g=e=-=I=D=:= ","","_");
322
323 buffer_puts(buffer_1,"------------------------------------------------------------------------------\n");
324
325 putaddr(&to,"=T=o=:= ","","+");
326 putaddr(&cc,"=C=c=:= ","","+");
327 putaddr(&bcc,"=B=c=c=:= ","","+");
328 putaddr(&nrudt,"=N=o=t=i=c=e=-=R=e=q=u=e=s=t=e=d=-=U=p=o=n=-=D=e=l=i=v=e=r=y=-=T=o=:= ","","+");
329
330 buffer_puts(buffer_1,"------------------------------------------------------------------------------\n");
331
332 putaddr(&sender,"=S=e=n=d=e=r=:= ","=s=e=n=d=e=r= ","+");
333 putaddr(&replyto,"=R=e=p=l=y=-=T=o=:= ","=r=e=p=l=y= =t=o= ","+");
334 putaddr(&mailreplyto,"=M=a=i=l=-=R=e=p=l=y=-=T=o=:= ","=r=e=p=l=y= =t=o= ","+");
335 putaddr(&followupto,"=M=a=i=l=-=F=o=l=l=o=w=u=p=-=T=o=:= ","=f=o=l=l=o=w= =u=p= =t=o= ","+");
336
337 buffer_puts(buffer_1,"------------------------------------------------------------------------------\n");
338
339 putvalue(&spf,"=S=P=F=-=V=a=l=i=d=a=t=i=o=n=:=");
340 // putvalue(&dkim,"=D=K=I=M=-=H=e=a=d=e=r=:="); /* FIXME */
341 putvalue(&qdkim,"=D=K=I=M=-=V=e=r=i=f=i=c=a=t=i=o=n=:=");
342
343 buffer_puts(buffer_1,"------------------------------------------------------------------------------\n");
344
345 putfields(&misc);
346}
347
348stralloc line = {0};
350
351int main()
352{
353 int flagheader = 1;
354
355 if (leapsecs_init() == -1)
356 logmsg(WHO,111,FATAL,"unable to init leapsecs: ");
357
358 if (!mess822_begin(&h,a)) nomem();
359 for (;;) {
360 if (getln(buffer_0,&line,&match,'\n') == -1)
361 logmsg(WHO,111,FATAL,"unable to read input: ");
362 if (flagheader)
363 if (!mess822_ok(&line)) {
364 finishheader();
365 flagheader = 0;
366 }
367 if (!flagheader)
368 buffer_put(buffer_1,line.s,line.len);
369 else
370 if (!mess822_line(&h,&line)) nomem();
371 if (!match) break;
372 }
373 if (flagheader)
374 finishheader();
375
376 buffer_flush(buffer_1);
377 _exit(0);
378}
char * comment
Definition: quote.c:15
struct tai sec
Definition: 822date.c:20
time_t secunix
Definition: 822date.c:22
unsigned char secpack[TAI_PACK]
Definition: 822date.c:21
mess822_time t
Definition: 822date.c:19
stralloc rightline
Definition: 822print.c:77
stralloc misc
Definition: 822print.c:270
stralloc envelope
Definition: 822print.c:246
stralloc mid
Definition: 822print.c:248
stralloc bcc
Definition: 822print.c:258
mess822_action a[]
Definition: 822print.c:273
stralloc dkim
Definition: 822print.c:267
stralloc leftline
Definition: 822print.c:76
stralloc nrudt
Definition: 822print.c:259
stralloc sender
Definition: 822print.c:262
stralloc replyto
Definition: 822print.c:263
stralloc qdkim
Definition: 822print.c:268
stralloc refs
Definition: 822print.c:249
mess822_header h
Definition: 822print.c:272
stralloc threading
Definition: 822print.c:247
stralloc followupto
Definition: 822print.c:265
mess822_time date
Definition: 822print.c:254
stralloc spf
Definition: 822print.c:266
stralloc from
Definition: 822print.c:261
stralloc tmp
Definition: 822print.c:78
stralloc line
Definition: 822print.c:348
stralloc returnpath
Definition: 822print.c:245
int match
Definition: 822print.c:349
stralloc cc
Definition: 822print.c:257
#define WHO
Definition: 822print.c:16
stralloc subject
Definition: 822print.c:251
int main()
Definition: 822print.c:351
stralloc dates
Definition: 822print.c:253
stralloc to
Definition: 822print.c:256
stralloc mailreplyto
Definition: 822print.c:264
unsigned int caltime_fmt(char *s, struct caltime *ct)
Definition: caltime_fmt.c:4
stralloc out
Definition: b64decode.c:12
stralloc addr
Definition: ofmipd.c:60
int leapsecs_init(void)
Definition: leapsecs_init.c:5
int mess822_line(mess822_header *, stralloc *)
Definition: mess822_line.c:107
int mess822_end(mess822_header *)
Definition: mess822_line.c:26
int mess822_ok(stralloc *)
Definition: mess822_ok.c:4
#define MESS822_HEADER
Definition: mess822.h:48
int mess822_begin(mess822_header *, mess822_action *)
Definition: mess822_line.c:5
void caltime_tai(struct caltime *ct, struct tai *t)
Definition: caltime_tai.c:8
Definition: caltime.h:7
int known
Definition: mess822.h:9
struct caltime ct
Definition: mess822.h:8