|
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("ed,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 } |