Commit | Line | Data |
---|---|---|
5b62e993 MW |
1 | #include "stralloc.h" |
2 | #include "str.h" | |
3 | #include "byte.h" | |
4 | #include "readwrite.h" | |
5 | #include "substdio.h" | |
6 | #include "getln.h" | |
7 | #include "strerr.h" | |
f8beb284 | 8 | #include "errtxt.h" |
5b62e993 MW |
9 | |
10 | char buf0[256]; | |
11 | substdio ss0 = SUBSTDIO_FDBUF(read,0,buf0,sizeof(buf0)); | |
12 | ||
13 | #define FATAL "ezmlm-weed: fatal: " | |
14 | ||
f8beb284 MW |
15 | void die_nomem() |
16 | { | |
17 | strerr_die2x(111,FATAL,ERR_NOMEM); | |
18 | } | |
19 | ||
5b62e993 MW |
20 | void get(sa) |
21 | stralloc *sa; | |
22 | { | |
23 | int match; | |
24 | if (getln(&ss0,sa,&match,'\n') == -1) | |
f8beb284 | 25 | strerr_die2sys(111,FATAL,ERR_READ_INPUT); |
5b62e993 MW |
26 | if (!match) _exit(0); |
27 | } | |
28 | ||
29 | stralloc line = {0}; | |
30 | stralloc line1 = {0}; | |
31 | stralloc line2 = {0}; | |
32 | stralloc line3 = {0}; | |
33 | stralloc line4 = {0}; | |
34 | stralloc line5 = {0}; | |
35 | stralloc line6 = {0}; | |
36 | stralloc line7 = {0}; | |
37 | stralloc line8 = {0}; | |
38 | ||
f8beb284 MW |
39 | stralloc boundary = {0}; |
40 | stralloc dsnline = {0}; | |
41 | ||
5b62e993 MW |
42 | char warn1[] = " **********************************************"; |
43 | char warn2[] = " ** THIS IS A WARNING MESSAGE ONLY **"; | |
44 | char warn3[] = " ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **"; | |
45 | char warn4[] = " **********************************************"; | |
46 | ||
47 | int flagmds = 0; | |
48 | int flagsw = 0; | |
49 | int flagsr = 0; | |
50 | int flagas = 0; | |
51 | int flagbw = 0; | |
f8beb284 MW |
52 | int flagdsn = 0; |
53 | ||
54 | int isboundary() | |
55 | /* returns 1 if line.len contains the mime bondary, 0 otherwise */ | |
56 | { | |
57 | if (line.s[0] == '-' && line.s[1] == '-' && line.len >= boundary.len + 3) | |
58 | if (!byte_diff(line.s + 2,boundary.len,boundary.s)) /* boundary */ | |
59 | return 1; | |
60 | return 0; | |
61 | } | |
5b62e993 MW |
62 | |
63 | void main() | |
64 | { | |
f8beb284 | 65 | unsigned int i,j; |
5b62e993 MW |
66 | |
67 | for (;;) { | |
68 | get(&line); | |
69 | if (line.len == 1) break; | |
f8beb284 MW |
70 | if (line.s[0] == ' ' || line.s[0] == '\t') { /* continuation */ |
71 | if (flagdsn) { | |
72 | if (!stralloc_catb(&dsnline,line.s,line.len - 1)) die_nomem(); | |
73 | continue; | |
74 | } | |
75 | } | |
76 | flagdsn = 0; | |
5b62e993 MW |
77 | if (stralloc_starts(&line,"Subject: success notice")) |
78 | _exit(99); | |
79 | if (stralloc_starts(&line,"Subject: deferral notice")) | |
80 | _exit(99); | |
f8beb284 MW |
81 | if (stralloc_starts(&line,"Precedence: bulk")) |
82 | _exit(99); | |
83 | if (stralloc_starts(&line,"Precedence: junk")) | |
84 | _exit(99); | |
85 | /* for Novell Groupwise */ | |
86 | if (stralloc_starts(&line,"Subject: Message status - delivered")) | |
87 | _exit(99); | |
88 | if (stralloc_starts(&line,"Subject: Message status - opened")) | |
89 | _exit(99); | |
90 | if (stralloc_starts(&line,"Subject: Out of Office AutoReply:")) | |
91 | _exit(99); | |
5b62e993 MW |
92 | |
93 | if (stralloc_starts(&line,"From: Mail Delivery Subsystem <MAILER-DAEMON@")) | |
94 | flagmds = 1; | |
95 | if (stralloc_starts(&line,"Subject: Warning: could not send message")) | |
96 | flagsw = 1; | |
97 | if (stralloc_starts(&line,"Subject: Returned mail: warning: cannot send message")) | |
98 | flagsr = 1; | |
99 | if (stralloc_starts(&line,"Auto-Submitted: auto-generated (warning")) | |
100 | flagas = 1; | |
f8beb284 MW |
101 | if (case_startb(line.s,line.len,"Content-type: multipart/report")) |
102 | if (!stralloc_copyb(&dsnline,line.s,line.len - 1)) die_nomem(); | |
103 | flagdsn = 1; | |
104 | } /* end of header */ | |
105 | ||
106 | if (flagdsn) { /* always only one recipient/action */ | |
107 | flagdsn = 0; /* will be set for correct report type */ | |
108 | for (i=0; i < dsnline.len; i += 1+byte_chr(dsnline.s+i,dsnline.len-i,';')) { | |
109 | while (dsnline.s[i] == ' ' || dsnline.s[i] == '\t') | |
110 | if (++i >= dsnline.len) break; | |
111 | if (case_startb(dsnline.s + i,dsnline.len - i,"report-type=")) { | |
112 | i += 12; | |
113 | while (dsnline.s[i] ==' ' || dsnline.s[i] =='\t' || dsnline.s[i] =='"') | |
114 | if (++i >= dsnline.len) break; | |
115 | if (case_startb(dsnline.s + i,dsnline.len - i,"delivery-status")) | |
116 | flagdsn = 1; | |
117 | } else if (case_startb(dsnline.s + i,dsnline.len - i,"boundary=")) { | |
118 | i += 9; | |
119 | while (dsnline.s[i] ==' ' || dsnline.s[i] =='\t') | |
120 | if (++i >= dsnline.len) break; | |
121 | if (dsnline.s[i] == '"') { | |
122 | if (++i >= dsnline.len) break; | |
123 | j = i + byte_chr(dsnline.s + i,dsnline.len - i,'"'); | |
124 | if (j >= dsnline.len) break; | |
125 | } else { | |
126 | j = i; | |
127 | while (dsnline.s[j] !=' ' && dsnline.s[j] !='\t' && | |
128 | dsnline.s[j] !=';') | |
129 | if (++j >= dsnline.len) break; | |
130 | } /* got boundary */ | |
131 | if (!stralloc_copyb(&boundary,dsnline.s+i,j-i)) die_nomem(); | |
132 | } | |
133 | } | |
134 | } | |
135 | if (flagdsn && boundary.len) { /* parse DSN message */ | |
136 | get(&line); /* if bad format we exit(0) via get() */ | |
137 | for (;;) { | |
138 | if (isboundary()) { | |
139 | if (line.len == boundary.len + 5 && line.s[line.len - 1] == '-' | |
140 | && line.s[line.len - 2] == '-') | |
141 | _exit(99); /* end: not failure report */ | |
142 | get(&line); /* Content-type */ | |
143 | if (case_startb(line.s,line.len,"content-type:")) { | |
144 | i = 13; | |
145 | while (line.s[i] == ' ' || line.s[i] == '\t') | |
146 | if (++i >= line.len) break; | |
147 | if (case_startb(line.s+i,line.len-i,"message/delivery-status")) { | |
148 | for (;;) { | |
149 | get(&line); | |
150 | if (isboundary()) break; | |
151 | if (case_startb(line.s,line.len,"action:")) { | |
152 | i = 8; | |
153 | while (line.s[i] == ' ' || line.s[i] == '\t') | |
154 | if (++i >= line.len) break; | |
155 | if (case_startb(line.s + i, line.len - i,"failed")) | |
156 | _exit(0); /* failure notice */ | |
157 | else | |
158 | _exit(99); /* there shouldn't be more than 1 action */ | |
159 | } | |
160 | } | |
161 | } | |
162 | } | |
163 | } else | |
164 | get(&line); | |
165 | } | |
5b62e993 MW |
166 | } |
167 | ||
168 | get(&line1); | |
169 | get(&line2); | |
170 | get(&line3); | |
171 | get(&line4); | |
172 | get(&line5); | |
173 | get(&line6); | |
174 | get(&line7); | |
175 | get(&line8); | |
176 | ||
177 | if (stralloc_starts(&line1,"This is a MIME-encapsulated message")) | |
178 | if (stralloc_starts(&line3,"--")) | |
179 | if (stralloc_starts(&line5,warn1)) | |
180 | if (stralloc_starts(&line6,warn2)) | |
181 | if (stralloc_starts(&line7,warn3)) | |
182 | if (stralloc_starts(&line8,warn4)) | |
183 | flagbw = 1; | |
184 | ||
185 | if (stralloc_starts(&line1,warn1)) | |
186 | if (stralloc_starts(&line2,warn2)) | |
187 | if (stralloc_starts(&line3,warn3)) | |
188 | if (stralloc_starts(&line4,warn4)) | |
189 | flagbw = 1; | |
190 | ||
191 | if (flagmds && flagsw && flagas && flagbw) _exit(99); | |
192 | if (flagmds && flagsr && flagbw) _exit(99); | |
193 | ||
194 | _exit(0); | |
195 | } |