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