Upstream qmail 1.03
[qmail] / qreceipt.c
1 #include "sig.h"
2 #include "env.h"
3 #include "substdio.h"
4 #include "stralloc.h"
5 #include "subfd.h"
6 #include "getln.h"
7 #include "alloc.h"
8 #include "str.h"
9 #include "hfield.h"
10 #include "token822.h"
11 #include "error.h"
12 #include "gen_alloc.h"
13 #include "gen_allocdefs.h"
14 #include "headerbody.h"
15 #include "exit.h"
16 #include "open.h"
17 #include "quote.h"
18 #include "qmail.h"
19
20 void die_noreceipt() { _exit(0); }
21 void die() { _exit(100); }
22 void die_temp() { _exit(111); }
23 void die_nomem() {
24 substdio_putsflush(subfderr,"qreceipt: fatal: out of memory\n"); die_temp(); }
25 void die_fork() {
26 substdio_putsflush(subfderr,"qreceipt: fatal: unable to fork\n"); die_temp(); }
27 void die_qqperm() {
28 substdio_putsflush(subfderr,"qreceipt: fatal: permanent qmail-queue error\n"); die(); }
29 void die_qqtemp() {
30 substdio_putsflush(subfderr,"qreceipt: fatal: temporary qmail-queue error\n"); die_temp(); }
31 void die_usage() {
32 substdio_putsflush(subfderr,
33 "qreceipt: usage: qreceipt deliveryaddress\n"); die(); }
34 void die_read() {
35 if (errno == error_nomem) die_nomem();
36 substdio_putsflush(subfderr,"qreceipt: fatal: read error\n"); die_temp(); }
37 void doordie(sa,r) stralloc *sa; int r; {
38 if (r == 1) return; if (r == -1) die_nomem();
39 substdio_putsflush(subfderr,"qreceipt: fatal: unable to parse this: ");
40 substdio_putflush(subfderr,sa->s,sa->len); die(); }
41
42 char *target;
43
44 int flagreceipt = 0;
45
46 char *returnpath;
47 stralloc messageid = {0};
48 stralloc sanotice = {0};
49
50 int rwnotice(addr) token822_alloc *addr; { token822_reverse(addr);
51 if (token822_unquote(&sanotice,addr) != 1) die_nomem();
52 if (sanotice.len == str_len(target))
53 if (!str_diffn(sanotice.s,target,sanotice.len))
54 flagreceipt = 1;
55 token822_reverse(addr); return 1; }
56
57 struct qmail qqt;
58
59 stralloc quoted = {0};
60
61 void finishheader()
62 {
63 char *qqx;
64
65 if (!flagreceipt) die_noreceipt();
66 if (str_equal(returnpath,"")) die_noreceipt();
67 if (str_equal(returnpath,"#@[]")) die_noreceipt();
68
69 if (!quote2(&quoted,returnpath)) die_nomem();
70
71 if (qmail_open(&qqt) == -1) die_fork();
72
73 qmail_puts(&qqt,"From: DELIVERY NOTICE SYSTEM <");
74 qmail_put(&qqt,quoted.s,quoted.len);
75 qmail_puts(&qqt,">\n");
76 qmail_puts(&qqt,"To: <");
77 qmail_put(&qqt,quoted.s,quoted.len);
78 qmail_puts(&qqt,">\n");
79 qmail_puts(&qqt,"Subject: success notice\n\
80 \n\
81 Hi! This is the qreceipt program. Your message was delivered to the\n\
82 following address: ");
83 qmail_puts(&qqt,target);
84 qmail_puts(&qqt,". Thanks for asking.\n");
85 if (messageid.s)
86 {
87 qmail_puts(&qqt,"Your ");
88 qmail_put(&qqt,messageid.s,messageid.len);
89 }
90
91 qmail_from(&qqt,"");
92 qmail_to(&qqt,returnpath);
93 qqx = qmail_close(&qqt);
94
95 if (*qqx)
96 if (*qqx == 'D') die_qqperm();
97 else die_qqtemp();
98 }
99
100 stralloc hfbuf = {0};
101 token822_alloc hfin = {0};
102 token822_alloc hfrewrite = {0};
103 token822_alloc hfaddr = {0};
104
105 void doheaderfield(h)
106 stralloc *h;
107 {
108 switch(hfield_known(h->s,h->len))
109 {
110 case H_MESSAGEID:
111 if (!stralloc_copy(&messageid,h)) die_nomem();
112 break;
113 case H_NOTICEREQUESTEDUPONDELIVERYTO:
114 doordie(h,token822_parse(&hfin,h,&hfbuf));
115 doordie(h,token822_addrlist(&hfrewrite,&hfaddr,&hfin,rwnotice));
116 break;
117 }
118 }
119
120 void dobody(h) stralloc *h; { ; }
121
122 void main(argc,argv)
123 int argc;
124 char **argv;
125 {
126 sig_pipeignore();
127 if (!(target = argv[1])) die_usage();
128 if (!(returnpath = env_get("SENDER"))) die_usage();
129 if (headerbody(subfdin,doheaderfield,finishheader,dobody) == -1) die_read();
130 die_noreceipt();
131 }