mess822x 1.23
mess822x
Loading...
Searching...
No Matches
new-inject.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "buffer.h"
3#include "getln.h"
4#include "mess822.h"
5#include "logmsg.h"
6#include "exit.h"
7#include "caltime.h"
8#include "leapsecs.h"
9#include "tai.h"
10#include "stralloc.h"
11#include "config.h"
12#include "auto_qmail.h"
13#include "case.h"
14#include "constmap.h"
15#include "qmail.h"
16#include "sig.h"
17#include "rewritehost.h"
18#include "rwhconfig.h"
19#include "getoptb.h"
20#include "str.h"
21#include "logmsg.h"
22
23#define WHO "new-inject"
24
25static void nomem()
26{
27 logmsg(WHO,111,FATAL,"out of memory");
28}
29
31
37
40struct constmap mapmft;
41
44stralloc idappend = {0};
45
46struct tai start;
47
48stralloc tmp = {0};
49stralloc tmp2 = {0};
50
51static void rewritelist(stralloc *list)
52{
53 if (!rewritehost_list(&tmp,list->s,list->len,config_data(&rewrite))) nomem();
54 if (!stralloc_copy(list,&tmp)) nomem();
55}
56
57int recipstrategy = 'A';
63
64stralloc sender = {0};
65stralloc recipients = {0};
66
67static void recipient_add(char *addr)
68{
69 if (!rewritehost_addr(&tmp,addr,str_len(addr),config_data(&rewrite))) nomem();
70 if (!stralloc_cat(&recipients,&tmp)) nomem();
71 if (!stralloc_0(&recipients)) nomem();
72}
73
74static void recipient_addlist(stralloc *list)
75{
76 int i;
77 int j;
78
79 for (j = i = 0; j < list->len; ++j)
80 if (!list->s[j]) {
81 if (list->s[i] == '+')
82 if (!stralloc_catb(&recipients,list->s + i + 1,j - i)) nomem();
83 i = j + 1;
84 }
85}
86
87static void sender_get(stralloc *list)
88{
89 int i;
90 int j;
91
92 for (j = i = 0; j < list->len; ++j)
93 if (!list->s[j]) {
94 if (list->s[i] == '+')
95 if (!stralloc_copyb(&sender,list->s + i + 1,j - i)) nomem();
96 i = j + 1;
97 }
98}
99
100int flagqueue = 1;
101struct qmail qq;
102
103static void put(char *buf,int len)
104{
105 if (flagqueue)
106 qmail_put(&qq,buf,len);
107 else
108 buffer_put(buffer_1,buf,len);
109}
110
111static void spit(char *buf)
112{
113 put(buf,str_len(buf));
114}
115
116static void putlist(char *name,stralloc *list)
117{
118 if (!list->len) return;
119 if (!mess822_quotelist(&tmp,list)) nomem();
120 if (!mess822_fold(&tmp2,&tmp,name,78)) nomem();
121 put(tmp2.s,tmp2.len);
122}
123
127stralloc to = {0};
128stralloc cc = {0};
129stralloc bcc = {0};
130stralloc nrudt = {0};
131stralloc returnpath = {0};
132stralloc from = {0};
133stralloc headersender = {0};
134stralloc replyto = {0};
135stralloc mailreplyto = {0};
136stralloc followupto = {0};
137
138stralloc msgid = {0};
139stralloc top = {0};
140stralloc bottom = {0};
141
144 { "date", 0, 0, 0, 0, &date, 0 }
145, { "to", 0, 0, 0, &to, 0, 0 }
146, { "cc", 0, 0, 0, &cc, 0, 0 }
147, { "bcc", 0, 0, 0, &bcc, 0, 0 }
148, { "apparently-to", 0, 0, 0, &bcc, 0, 0 }
149, { "notice-requested-upon-delivery-to", 0, 0, 0, &nrudt, 0, 0 }
150, { "from", 0, 0, 0, &from, 0, 0 }
151, { "sender", 0, 0, 0, &headersender, 0, 0 }
152, { "reply-to", 0, 0, 0, &replyto, 0, 0 }
153, { "mail-reply-to", 0, 0, 0, &mailreplyto, 0, 0 }
154, { "mail-followup-to", 0, 0, 0, &followupto, 0, 0 }
155, { "return-path", 0, 0, 0, &returnpath, 0, 0 }
156, { "envelope-recipients", &flagenveloperecipients, 0, 0, &enveloperecipients, 0, 0 }
157, { "envelope-sender", &flagenvelopesender, 0, 0, &envelopesender, 0, 0 }
158, { "message-id", 0, &msgid, 0, 0, 0, 0 }
159, { "received", 0, &top, 0, 0, 0, 0 }
160, { "delivered-to", 0, &top, 0, 0, 0, 0 }
161, { "errors-to", 0, &top, 0, 0, 0, 0 }
162, { "return-receipt-to", 0, &top, 0, 0, 0, 0 }
163, { "resent-sender", 0, &top, 0, 0, 0, 0 }
164, { "resent-from", 0, &top, 0, 0, 0, 0 }
165, { "resent-reply-to", 0, &top, 0, 0, 0, 0 }
166, { "resent-to", 0, &top, 0, 0, 0, 0 }
167, { "resent-cc", 0, &top, 0, 0, 0, 0 }
168, { "resent-bcc", 0, &top, 0, 0, 0, 0 }
169, { "resent-date", 0, &top, 0, 0, 0, 0 }
170, { "resent-message-id", 0, &top, 0, 0, 0, 0 }
171, { "content-length", 0, 0, 0, 0, 0, 0 }
172, { 0, 0, &bottom, 0, 0, 0, 0 }
173} ;
174
175static void envelope_make()
176{
177 if (recipstrategy != 'a') {
179 recipient_addlist(&enveloperecipients);
180 } else {
181 recipient_addlist(&to);
182 recipient_addlist(&cc);
183 recipient_addlist(&bcc);
184 }
185 }
186
187 if (!sender.len)
188 sender_get(&envelopesender);
189 if (!sender.len)
190 sender_get(&returnpath);
191 if (!sender.len) {
193 if (flagverprecip)
194 if (!stralloc_cats(&sender,"-@[]")) nomem();
195 if (!stralloc_0(&sender)) nomem();
196 }
197}
198
199static void envelope_print()
200{
201 int i;
202 int j;
203
204 spit("Envelope-Sender: ");
205 if (!mess822_quote(&tmp,sender.s,(char *) 0)) nomem();
206 put(tmp.s,tmp.len);
207 spit("\n");
208
209 spit("Envelope-Recipients:\n");
210 for (j = i = 0; j < recipients.len; ++j)
211 if (!recipients.s[j]) {
212 if (!mess822_quote(&tmp,recipients.s + i,(char *) 0)) nomem();
213 spit(" ");
214 put(tmp.s,tmp.len);
215 spit(",\n");
216 i = j + 1;
217 }
218}
219
220static void datemsgid_print()
221{
222 if (!date.known) {
223 caltime_utc(&date.ct,&start,(int *) 0,(int *) 0);
224 date.known = 1;
225 }
226 if (!mess822_date(&tmp,&date)) nomem();
227 spit("Date: ");
228 put(tmp.s,tmp.len);
229 spit("\n");
230
231 if (!msgid.len) {
232 if (!stralloc_copys(&msgid,"Message-ID: <")) nomem();
233 if (!stralloc_catlong(&msgid,date.ct.date.year)) nomem();
234 if (!stralloc_catint0(&msgid,date.ct.date.month,2)) nomem();
235 if (!stralloc_catint0(&msgid,date.ct.date.day,2)) nomem();
236 if (!stralloc_catint0(&msgid,date.ct.hour,2)) nomem();
237 if (!stralloc_catint0(&msgid,date.ct.minute,2)) nomem();
238 if (!stralloc_catint0(&msgid,date.ct.second,2)) nomem();
239 if (!stralloc_cat(&msgid,&idappend)) nomem();
240 if (!stralloc_cats(&msgid,">\n")) nomem();
241 }
242 put(msgid.s,msgid.len);
243}
244
245static void from_print()
246{
247 putlist("From: ",&from);
248 if (!from.len) {
250 if (!stralloc_0(&tmp2)) nomem();
251 spit("From: ");
252 if (!mess822_quote(&tmp,tmp2.s,config(&name) ? config_data(&name)->s : (char *) 0)) nomem();
253 put(tmp.s,tmp.len);
254 spit("\n");
255 }
256
257 putlist("Sender: ",&headersender);
258}
259
260static int inmft(stralloc *list)
261{
262 int i;
263 int j;
264
265 for (j = i = 0; j < list->len; ++j)
266 if (!list->s[j]) {
267 if (list->s[i] == '+')
268 if (constmap(&mapmft,list->s + i + 1,j - i - 1))
269 return 1;
270 i = j + 1;
271 }
272 return 0;
273}
274
275static void response_print()
276{
277 putlist("Reply-To: ",&replyto);
278 putlist("Mail-Reply-To: ",&mailreplyto);
279
280 if (!followupto.len)
281 if (config(&mft))
282 if (inmft(&to) || inmft(&cc)) {
283 if (!stralloc_cat(&followupto,&to)) nomem();
284 if (!stralloc_cat(&followupto,&cc)) nomem();
285 }
286 putlist("Mail-Followup-To: ",&followupto);
287}
288
289static void to_print()
290{
291 if (!to.len && !cc.len)
292 spit("Cc: recipient list not shown: ;\n");
293 putlist("To: ",&to);
294 putlist("Cc: ",&cc);
295 putlist("Notice-Requested-Upon-Delivery-To: ",&nrudt);
296}
297
298static void finishheader()
299{
300 if (!mess822_end(&h)) nomem();
301
302 if (flagqueue)
303 if (qmail_open(&qq) == -1)
304 logmsg(WHO,111,FATAL,"unable to run qmail-queue: ");
305
306 if (flagkillreturnpath) returnpath.len = 0;
307 if (flagkillmsgid) msgid.len = 0;
308 if (flagkillfrom) from.len = 0;
309
310 rewritelist(&to);
311 rewritelist(&cc);
312 rewritelist(&bcc);
313 rewritelist(&nrudt);
314 rewritelist(&from);
315 rewritelist(&headersender);
316 rewritelist(&replyto);
317 rewritelist(&mailreplyto);
318 rewritelist(&followupto);
319 rewritelist(&returnpath);
320 rewritelist(&enveloperecipients);
321 rewritelist(&envelopesender);
322
323 envelope_make();
324 if (!flagqueue)
325 envelope_print();
326
327 put(top.s,top.len);
328 datemsgid_print();
329 from_print();
330 response_print();
331 to_print();
332 put(bottom.s,bottom.len);
333}
334
335static void finishmessage()
336{
337 char *qqx;
338 int i;
339 int j;
340
341 if (!flagqueue)
342 buffer_flush(buffer_1);
343 else {
344 qmail_from(&qq,sender.s);
345
346 for (j = i = 0; j < recipients.len; ++j)
347 if (!recipients.s[j]) {
348 qmail_to(&qq,recipients.s + i);
349 i = j + 1;
350 }
351 qqx = qmail_close(&qq);
352 if (*qqx) logmsg(WHO,*qqx == 'D' ? 100 : 111,FATAL,qqx + 1);
353 }
354
355 _exit(0);
356}
357
358char *argsender = 0;
359
360stralloc line = {0};
362
363int main(int argc,char **argv)
364{
365 int i;
366 int flagheader = 1;
367 int opt;
368
369 sig_pipeignore();
370 tai_now(&start);
371
372 if (config_env(&qmailinject,"QMAILINJECT") == -1) nomem();
373 if (config(&qmailinject))
374 for (i = 0; i < config_data(&qmailinject)->len; ++i)
375 switch (config_data(&qmailinject)->s[i]) {
376 case 'F': case 'f': flagkillfrom = 1; break;
377 case 'I': case 'i': flagkillmsgid = 1; break;
378 case 'M': case 'm': flagverpmess = 1; break;
379 case 'R': case 'r': flagverprecip = 1; break;
380 case 'S': case 's': flagkillreturnpath = 1; break;
381 }
382
383 while ((opt = getoptb(argc,argv,"nNaAhHFIMRSf:")) != opteof)
384 switch (opt) {
385 case 'n': flagqueue = 0; break;
386 case 'N': flagqueue = 1; break;
387 case 'a': case 'A': case 'h': case 'H': recipstrategy = opt; break;
388 case 'F': flagkillfrom = 1; break;
389 case 'I': flagkillmsgid = 1; break;
390 case 'M': flagverpmess = 1; break;
391 case 'R': flagverprecip = 1; break;
392 case 'S': flagkillreturnpath = 1; break;
393 case 'f': argsender = optarg; break;
394 default:
395 logmsg(WHO,100,USAGE,"new-inject [ -nNaAhHFIMRS ] [ -f sender ] [ recip ... ]\n");
396 }
397 argv += optind;
398
399 if (leapsecs_init() == -1)
400 logmsg(WHO,111,FATAL,"unable to init leapsecs: ");
401
402 if (config_env(&fnmft,"QMAILMFTFILE") == -1) nomem();
403 if (config(&fnmft)) {
404 if (!stralloc_0(config_data(&fnmft))) nomem();
405 if (config_readfile(&mft,config_data(&fnmft)->s) == -1)
406 logmsg(WHO,111,FATAL,"unable to read $QMAILMFTFILE: ");
407 if (config(&mft))
408 if (!constmap_init(&mapmft,config_data(&mft)->s,config_data(&mft)->len,0)) nomem();
409 }
410
411 if (config_env(&fnrewrite,"QMAILREWRITEFILE") == -1) nomem();
412 if (config(&fnrewrite)) {
413 if (!stralloc_0(config_data(&fnrewrite))) nomem();
415 logmsg(WHO,111,FATAL,"unable to read $QMAILREWRITEFILE: ");
416 }
417
418 if (chdir(auto_qmail) == -1)
419 logmsg(WHO,111,FATAL,B("unable to switch to: ",auto_qmail));
420
421 if (config_env(&name,"QMAILNAME") == -1) nomem();
422
423 if (config_env(&name,"MAILNAME") == -1) nomem();
424 if (config_env(&name,"NAME") == -1) nomem();
425 if (config(&name))
426 if (!stralloc_0(config_data(&name))) nomem();
427
428 if (config_env(&user,"QMAILUSER") == -1) nomem();
429 if (config_env(&user,"MAILUSER") == -1) nomem();
430 if (config_env(&user,"USER") == -1) nomem();
431 if (config_env(&user,"LOGNAME") == -1) nomem();
432 if (config_default(&user,"anonymous") == -1) nomem();
433
434 if (config_env(&suser,"QMAILSUSER") == -1) nomem();
435 if (config_copy(&suser,&user) == -1) nomem();
436
437 if (config_env(&host,"QMAILHOST") == -1) nomem();
438 if (config_env(&host,"MAILHOST") == -1) nomem();
439 if (config_default(&host,"") == -1) nomem();
440
441 if (rwhconfig(&rewrite,&idappend) == -1)
442 logmsg(WHO,111,FATAL,"can't append to rewrite");
443
444 if (config_env(&shost,"QMAILSHOST") == -1) nomem();
445 if (config_copy(&shost,&host) == -1) nomem();
446
447 if (!stralloc_copys(&sender,"")) nomem();
448 if (argsender) {
450 if (!stralloc_0(&sender)) nomem();
451 }
452
453 if (recipstrategy == 'A')
454 recipstrategy = (*argv ? 'a' : 'h');
455
456 if (!stralloc_copys(&recipients,"")) nomem();
457 if (recipstrategy != 'h')
458 while (*argv)
459 recipient_add(*argv++);
460
461 if (flagverpmess) {
462 unsigned char nowpack[TAI_PACK];
463 unsigned long u;
464
465 tai_pack((char *)nowpack,&start);
466 u = nowpack[4]; u <<= 8;
467 u += nowpack[5]; u <<= 8;
468 u += nowpack[6]; u <<= 8;
469 u += nowpack[7];
470 if (!stralloc_cats(config_data(&suser),"-")) nomem();
471 if (!stralloc_catulong0(config_data(&suser),u,0)) nomem();
472 u = getpid();
473 if (!stralloc_cats(config_data(&suser),".")) nomem();
474 if (!stralloc_catulong0(config_data(&suser),u,0)) nomem();
475 }
476 if (flagverprecip)
477 if (!stralloc_cats(config_data(&suser),"-")) nomem();
478 if (!stralloc_cats(config_data(&suser),"@")) nomem();
479 if (!stralloc_cat(config_data(&suser),config_data(&shost))) nomem();
480
481 if (!stralloc_cats(config_data(&user),"@")) nomem();
482 if (!stralloc_cat(config_data(&user),config_data(&host))) nomem();
483
484
485 if (!mess822_begin(&h,a)) nomem();
486 for (;;) {
487 if (getln(buffer_0,&line,&match,'\n') == -1)
488 logmsg(WHO,111,FATAL,"unable to read input: ");
489 if (!match && !line.len) break;
490 if (!match)
491 if (!stralloc_append(&line,"\n")) nomem();
492 if (flagheader)
493 if (!mess822_ok(&line)) {
494 finishheader();
495 flagheader = 0;
496 if (line.len != 1) put("\n",1);
497 }
498 if (!flagheader)
499 put(line.s,line.len);
500 else
501 if (!mess822_line(&h,&line)) nomem();
502 if (!match) break;
503 }
504 if (flagheader)
505 finishheader();
506
507 finishmessage();
508}
int config_copy(config_str *c, config_str *d)
Definition: config.c:19
int config_env(config_str *c, char *s)
Definition: config.c:28
int config_default(config_str *c, char *s)
Definition: config.c:10
int config_readfile(config_str *c, char *fn)
Definition: config.c:84
int main()
Definition: 822print.c:351
#define config(c)
Definition: config.h:13
#define CONFIG_STR
Definition: config.h:11
#define config_data(c)
Definition: config.h:14
int rewritehost_list(stralloc *, char *, unsigned int, stralloc *)
Definition: rewritehost.c:76
int rewritehost_addr(stralloc *, char *, unsigned int, stralloc *)
Definition: rewritehost.c:70
int leapsecs_init(void)
Definition: leapsecs_init.c:5
char auto_qmail[]
int mess822_quote(stralloc *, char *, char *)
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_fold(stralloc *, stralloc *, char *, int)
Definition: mess822_fold.c:3
int mess822_date(stralloc *, mess822_time *)
Definition: mess822_date.c:8
int mess822_begin(mess822_header *, mess822_action *)
Definition: mess822_line.c:5
int mess822_quotelist(stralloc *, stralloc *)
int rwhconfig(config_str *, stralloc *)
Definition: rwhconfig.c:25
void qmail_to(struct qmail *, char *)
Definition: qmail.c:83
void qmail_from(struct qmail *, char *)
Definition: qmail.c:73
void qmail_put(struct qmail *, char *, int)
Definition: qmail.c:63
char * qmail_close(struct qmail *)
Definition: qmail.c:90
int qmail_open(struct qmail *)
Definition: qmail.c:21
stralloc tmp2
Definition: new-inject.c:49
stralloc envelopesender
Definition: new-inject.c:126
stralloc bcc
Definition: new-inject.c:129
mess822_action a[]
Definition: new-inject.c:143
config_str shost
Definition: new-inject.c:36
int flagqueue
Definition: new-inject.c:100
int recipstrategy
Definition: new-inject.c:57
char * argsender
Definition: new-inject.c:358
int flagkillreturnpath
Definition: new-inject.c:60
stralloc headersender
Definition: new-inject.c:133
stralloc recipients
Definition: new-inject.c:65
config_str host
Definition: new-inject.c:34
stralloc bottom
Definition: new-inject.c:140
stralloc nrudt
Definition: new-inject.c:130
stralloc sender
Definition: new-inject.c:64
config_str fnmft
Definition: new-inject.c:38
stralloc msgid
Definition: new-inject.c:138
stralloc replyto
Definition: new-inject.c:134
stralloc idappend
Definition: new-inject.c:44
int flagkillfrom
Definition: new-inject.c:58
config_str qmailinject
Definition: new-inject.c:30
struct tai start
Definition: new-inject.c:46
mess822_header h
Definition: new-inject.c:142
stralloc followupto
Definition: new-inject.c:136
config_str fnrewrite
Definition: new-inject.c:42
mess822_time date
Definition: new-inject.c:124
stralloc from
Definition: new-inject.c:132
stralloc tmp
Definition: new-inject.c:48
int flagkillmsgid
Definition: new-inject.c:59
int flagenvelopesender
Definition: new-inject.c:126
config_str rewrite
Definition: new-inject.c:43
int flagverprecip
Definition: new-inject.c:62
stralloc line
Definition: new-inject.c:360
config_str user
Definition: new-inject.c:33
config_str mft
Definition: new-inject.c:39
stralloc returnpath
Definition: new-inject.c:131
int match
Definition: new-inject.c:361
config_str name
Definition: new-inject.c:32
stralloc cc
Definition: new-inject.c:128
int flagenveloperecipients
Definition: new-inject.c:125
#define WHO
Definition: new-inject.c:23
stralloc enveloperecipients
Definition: new-inject.c:125
int flagverpmess
Definition: new-inject.c:61
config_str suser
Definition: new-inject.c:35
struct constmap mapmft
Definition: new-inject.c:40
stralloc top
Definition: new-inject.c:139
stralloc to
Definition: new-inject.c:127
struct qmail qq
Definition: new-inject.c:101
stralloc mailreplyto
Definition: new-inject.c:135
void caltime_utc(struct caltime *ct, struct tai *t, int *pwday, int *pyday)
Definition: caltime_utc.c:8
int day
Definition: caldate.h:7
long year
Definition: caldate.h:5
int month
Definition: caldate.h:6
int hour
Definition: caltime.h:9
struct caldate date
Definition: caltime.h:8
int minute
Definition: caltime.h:10
int second
Definition: caltime.h:11
int known
Definition: mess822.h:9
struct caltime ct
Definition: mess822.h:8
Definition: qmail.h:6
char buf[1024]
Definition: qmail.h:12