debian/rules: Use `git' potty wrapper.
[qmail] / qreceipt.c
CommitLineData
2117e02e
MW
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
20void die_noreceipt() { _exit(0); }
21void die() { _exit(100); }
22void die_temp() { _exit(111); }
23void die_nomem() {
24 substdio_putsflush(subfderr,"qreceipt: fatal: out of memory\n"); die_temp(); }
25void die_fork() {
26 substdio_putsflush(subfderr,"qreceipt: fatal: unable to fork\n"); die_temp(); }
27void die_qqperm() {
28 substdio_putsflush(subfderr,"qreceipt: fatal: permanent qmail-queue error\n"); die(); }
29void die_qqtemp() {
30 substdio_putsflush(subfderr,"qreceipt: fatal: temporary qmail-queue error\n"); die_temp(); }
31void die_usage() {
32 substdio_putsflush(subfderr,
33 "qreceipt: usage: qreceipt deliveryaddress\n"); die(); }
34void die_read() {
35 if (errno == error_nomem) die_nomem();
36 substdio_putsflush(subfderr,"qreceipt: fatal: read error\n"); die_temp(); }
37void 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
42char *target;
43
44int flagreceipt = 0;
45
46char *returnpath;
47stralloc messageid = {0};
48stralloc sanotice = {0};
49
50int 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
57struct qmail qqt;
58
59stralloc quoted = {0};
60
61void finishheader()
62{
212b6f5d
MW
63 char *qqx;
64
2117e02e
MW
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\
81Hi! This is the qreceipt program. Your message was delivered to the\n\
82following 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);
212b6f5d 93 qqx = qmail_close(&qqt);
2117e02e 94
212b6f5d
MW
95 if (*qqx)
96 if (*qqx == 'D') die_qqperm();
97 else die_qqtemp();
2117e02e
MW
98}
99
100stralloc hfbuf = {0};
101token822_alloc hfin = {0};
102token822_alloc hfrewrite = {0};
103token822_alloc hfaddr = {0};
104
105void doheaderfield(h)
106stralloc *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
120void dobody(h) stralloc *h; { ; }
121
122void main(argc,argv)
123int argc;
124char **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}