Import ezmlm-idx 0.40
[ezmlm] / ezmlm-weed.c
CommitLineData
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
10char buf0[256];
11substdio ss0 = SUBSTDIO_FDBUF(read,0,buf0,sizeof(buf0));
12
13#define FATAL "ezmlm-weed: fatal: "
14
f8beb284
MW
15void die_nomem()
16{
17 strerr_die2x(111,FATAL,ERR_NOMEM);
18}
19
5b62e993
MW
20void get(sa)
21stralloc *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
29stralloc line = {0};
30stralloc line1 = {0};
31stralloc line2 = {0};
32stralloc line3 = {0};
33stralloc line4 = {0};
34stralloc line5 = {0};
35stralloc line6 = {0};
36stralloc line7 = {0};
37stralloc line8 = {0};
38
f8beb284
MW
39stralloc boundary = {0};
40stralloc dsnline = {0};
41
5b62e993
MW
42char warn1[] = " **********************************************";
43char warn2[] = " ** THIS IS A WARNING MESSAGE ONLY **";
44char warn3[] = " ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **";
45char warn4[] = " **********************************************";
46
47int flagmds = 0;
48int flagsw = 0;
49int flagsr = 0;
50int flagas = 0;
51int flagbw = 0;
f8beb284
MW
52int flagdsn = 0;
53
54int 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
63void 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}