Blame


1 5cdb1798 2005-10-29 devnull #include "common.h"
2 5cdb1798 2005-10-29 devnull #include "spam.h"
3 5cdb1798 2005-10-29 devnull
4 5cdb1798 2005-10-29 devnull int cflag;
5 5cdb1798 2005-10-29 devnull int debug;
6 5cdb1798 2005-10-29 devnull int hflag;
7 5cdb1798 2005-10-29 devnull int nflag;
8 5cdb1798 2005-10-29 devnull int sflag;
9 5cdb1798 2005-10-29 devnull int tflag;
10 5cdb1798 2005-10-29 devnull int vflag;
11 5cdb1798 2005-10-29 devnull Biobuf bin, bout, *cout;
12 5cdb1798 2005-10-29 devnull
13 5cdb1798 2005-10-29 devnull /* file names */
14 5cdb1798 2005-10-29 devnull char patfile[128];
15 5cdb1798 2005-10-29 devnull char linefile[128];
16 5cdb1798 2005-10-29 devnull char holdqueue[128];
17 5cdb1798 2005-10-29 devnull char copydir[128];
18 5cdb1798 2005-10-29 devnull
19 5cdb1798 2005-10-29 devnull char header[Hdrsize+2];
20 5cdb1798 2005-10-29 devnull char cmd[1024];
21 5cdb1798 2005-10-29 devnull char **qname;
22 5cdb1798 2005-10-29 devnull char **qdir;
23 5cdb1798 2005-10-29 devnull char *sender;
24 5cdb1798 2005-10-29 devnull String *recips;
25 5cdb1798 2005-10-29 devnull
26 5cdb1798 2005-10-29 devnull char* canon(Biobuf*, char*, char*, int*);
27 5cdb1798 2005-10-29 devnull int matcher(char*, Pattern*, char*, Resub*);
28 5cdb1798 2005-10-29 devnull int matchaction(int, char*, Resub*);
29 5cdb1798 2005-10-29 devnull Biobuf *opencopy(char*);
30 5cdb1798 2005-10-29 devnull Biobuf *opendump(char*);
31 5cdb1798 2005-10-29 devnull char *qmail(char**, char*, int, Biobuf*);
32 5cdb1798 2005-10-29 devnull void saveline(char*, char*, Resub*);
33 5cdb1798 2005-10-29 devnull int optoutofspamfilter(char*);
34 5cdb1798 2005-10-29 devnull
35 5cdb1798 2005-10-29 devnull void
36 5cdb1798 2005-10-29 devnull usage(void)
37 5cdb1798 2005-10-29 devnull {
38 5cdb1798 2005-10-29 devnull fprint(2, "missing or bad arguments to qer\n");
39 5cdb1798 2005-10-29 devnull exits("usage");
40 5cdb1798 2005-10-29 devnull }
41 5cdb1798 2005-10-29 devnull
42 5cdb1798 2005-10-29 devnull void
43 5cdb1798 2005-10-29 devnull regerror(char *s)
44 5cdb1798 2005-10-29 devnull {
45 5cdb1798 2005-10-29 devnull fprint(2, "scanmail: %s\n", s);
46 5cdb1798 2005-10-29 devnull }
47 5cdb1798 2005-10-29 devnull
48 5cdb1798 2005-10-29 devnull void *
49 5cdb1798 2005-10-29 devnull Malloc(long n)
50 5cdb1798 2005-10-29 devnull {
51 5cdb1798 2005-10-29 devnull void *p;
52 5cdb1798 2005-10-29 devnull
53 5cdb1798 2005-10-29 devnull p = malloc(n);
54 5cdb1798 2005-10-29 devnull if(p == 0)
55 5cdb1798 2005-10-29 devnull exits("malloc");
56 5cdb1798 2005-10-29 devnull return p;
57 5cdb1798 2005-10-29 devnull }
58 5cdb1798 2005-10-29 devnull
59 5cdb1798 2005-10-29 devnull void*
60 5cdb1798 2005-10-29 devnull Realloc(void *p, ulong n)
61 5cdb1798 2005-10-29 devnull {
62 5cdb1798 2005-10-29 devnull p = realloc(p, n);
63 5cdb1798 2005-10-29 devnull if(p == 0)
64 5cdb1798 2005-10-29 devnull exits("realloc");
65 5cdb1798 2005-10-29 devnull return p;
66 5cdb1798 2005-10-29 devnull }
67 5cdb1798 2005-10-29 devnull
68 5cdb1798 2005-10-29 devnull void
69 5cdb1798 2005-10-29 devnull main(int argc, char *argv[])
70 5cdb1798 2005-10-29 devnull {
71 5cdb1798 2005-10-29 devnull int i, n, nolines, optout;
72 5cdb1798 2005-10-29 devnull char **args, **a, *cp, *buf;
73 5cdb1798 2005-10-29 devnull char body[Bodysize+2];
74 5cdb1798 2005-10-29 devnull Resub match[1];
75 5cdb1798 2005-10-29 devnull Biobuf *bp;
76 5cdb1798 2005-10-29 devnull
77 5cdb1798 2005-10-29 devnull optout = 1;
78 5cdb1798 2005-10-29 devnull a = args = Malloc((argc+1)*sizeof(char*));
79 5cdb1798 2005-10-29 devnull sprint(patfile, "%s/patterns", UPASLIB);
80 5cdb1798 2005-10-29 devnull sprint(linefile, "%s/lines", UPASLOG);
81 5cdb1798 2005-10-29 devnull sprint(holdqueue, "%s/queue.hold", SPOOL);
82 5cdb1798 2005-10-29 devnull sprint(copydir, "%s/copy", SPOOL);
83 5cdb1798 2005-10-29 devnull
84 5cdb1798 2005-10-29 devnull *a++ = argv[0];
85 5cdb1798 2005-10-29 devnull for(argc--, argv++; argv[0] && argv[0][0] == '-'; argc--, argv++){
86 5cdb1798 2005-10-29 devnull switch(argv[0][1]){
87 5cdb1798 2005-10-29 devnull case 'c': /* save copy of message */
88 5cdb1798 2005-10-29 devnull cflag = 1;
89 5cdb1798 2005-10-29 devnull break;
90 5cdb1798 2005-10-29 devnull case 'd': /* debug */
91 5cdb1798 2005-10-29 devnull debug++;
92 5cdb1798 2005-10-29 devnull *a++ = argv[0];
93 5cdb1798 2005-10-29 devnull break;
94 5cdb1798 2005-10-29 devnull case 'h': /* queue held messages by sender domain */
95 5cdb1798 2005-10-29 devnull hflag = 1; /* -q flag must be set also */
96 5cdb1798 2005-10-29 devnull break;
97 5cdb1798 2005-10-29 devnull case 'n': /* NOHOLD mode */
98 5cdb1798 2005-10-29 devnull nflag = 1;
99 5cdb1798 2005-10-29 devnull break;
100 5cdb1798 2005-10-29 devnull case 'p': /* pattern file */
101 5cdb1798 2005-10-29 devnull if(argv[0][2] || argv[1] == 0)
102 5cdb1798 2005-10-29 devnull usage();
103 5cdb1798 2005-10-29 devnull argc--;
104 5cdb1798 2005-10-29 devnull argv++;
105 5cdb1798 2005-10-29 devnull strecpy(patfile, patfile+sizeof patfile, *argv);
106 5cdb1798 2005-10-29 devnull break;
107 5cdb1798 2005-10-29 devnull case 'q': /* queue name */
108 5cdb1798 2005-10-29 devnull if(argv[0][2] || argv[1] == 0)
109 5cdb1798 2005-10-29 devnull usage();
110 5cdb1798 2005-10-29 devnull *a++ = argv[0];
111 5cdb1798 2005-10-29 devnull argc--;
112 5cdb1798 2005-10-29 devnull argv++;
113 5cdb1798 2005-10-29 devnull qname = a;
114 5cdb1798 2005-10-29 devnull *a++ = argv[0];
115 5cdb1798 2005-10-29 devnull break;
116 5cdb1798 2005-10-29 devnull case 's': /* save copy of dumped message */
117 5cdb1798 2005-10-29 devnull sflag = 1;
118 5cdb1798 2005-10-29 devnull break;
119 5cdb1798 2005-10-29 devnull case 't': /* test mode - don't log match
120 5cdb1798 2005-10-29 devnull * and write message to /dev/null
121 5cdb1798 2005-10-29 devnull */
122 5cdb1798 2005-10-29 devnull tflag = 1;
123 5cdb1798 2005-10-29 devnull break;
124 5cdb1798 2005-10-29 devnull case 'v': /* vebose - print matches */
125 5cdb1798 2005-10-29 devnull vflag = 1;
126 5cdb1798 2005-10-29 devnull break;
127 5cdb1798 2005-10-29 devnull default:
128 5cdb1798 2005-10-29 devnull *a++ = argv[0];
129 5cdb1798 2005-10-29 devnull break;
130 5cdb1798 2005-10-29 devnull }
131 5cdb1798 2005-10-29 devnull }
132 5cdb1798 2005-10-29 devnull
133 5cdb1798 2005-10-29 devnull if(argc < 3)
134 5cdb1798 2005-10-29 devnull usage();
135 5cdb1798 2005-10-29 devnull
136 5cdb1798 2005-10-29 devnull Binit(&bin, 0, OREAD);
137 5cdb1798 2005-10-29 devnull bp = Bopen(patfile, OREAD);
138 5cdb1798 2005-10-29 devnull if(bp){
139 5cdb1798 2005-10-29 devnull parsepats(bp);
140 5cdb1798 2005-10-29 devnull Bterm(bp);
141 5cdb1798 2005-10-29 devnull }
142 5cdb1798 2005-10-29 devnull qdir = a;
143 5cdb1798 2005-10-29 devnull sender = argv[2];
144 5cdb1798 2005-10-29 devnull
145 5cdb1798 2005-10-29 devnull /* copy the rest of argv, acummulating the recipients as we go */
146 5cdb1798 2005-10-29 devnull for(i = 0; argv[i]; i++){
147 5cdb1798 2005-10-29 devnull *a++ = argv[i];
148 5cdb1798 2005-10-29 devnull if(i < 4) /* skip queue, 'mail', sender, dest sys */
149 5cdb1798 2005-10-29 devnull continue;
150 5cdb1798 2005-10-29 devnull /* recipients and smtp flags - skip the latter*/
151 5cdb1798 2005-10-29 devnull if(strcmp(argv[i], "-g") == 0){
152 5cdb1798 2005-10-29 devnull *a++ = argv[++i];
153 5cdb1798 2005-10-29 devnull continue;
154 5cdb1798 2005-10-29 devnull }
155 5cdb1798 2005-10-29 devnull if(recips)
156 5cdb1798 2005-10-29 devnull s_append(recips, ", ");
157 5cdb1798 2005-10-29 devnull else
158 5cdb1798 2005-10-29 devnull recips = s_new();
159 5cdb1798 2005-10-29 devnull s_append(recips, argv[i]);
160 5cdb1798 2005-10-29 devnull if(optout && !optoutofspamfilter(argv[i]))
161 5cdb1798 2005-10-29 devnull optout = 0;
162 5cdb1798 2005-10-29 devnull }
163 5cdb1798 2005-10-29 devnull *a = 0;
164 5cdb1798 2005-10-29 devnull /* construct a command string for matching */
165 5cdb1798 2005-10-29 devnull snprint(cmd, sizeof(cmd)-1, "%s %s", sender, s_to_c(recips));
166 5cdb1798 2005-10-29 devnull cmd[sizeof(cmd)-1] = 0;
167 5cdb1798 2005-10-29 devnull for(cp = cmd; *cp; cp++)
168 5cdb1798 2005-10-29 devnull *cp = tolower(*cp);
169 5cdb1798 2005-10-29 devnull
170 5cdb1798 2005-10-29 devnull /* canonicalize a copy of the header and body.
171 5cdb1798 2005-10-29 devnull * buf points to orginal message and n contains
172 5cdb1798 2005-10-29 devnull * number of bytes of original message read during
173 5cdb1798 2005-10-29 devnull * canonicalization.
174 5cdb1798 2005-10-29 devnull */
175 5cdb1798 2005-10-29 devnull *body = 0;
176 5cdb1798 2005-10-29 devnull *header = 0;
177 5cdb1798 2005-10-29 devnull buf = canon(&bin, header+1, body+1, &n);
178 5cdb1798 2005-10-29 devnull if (buf == 0)
179 5cdb1798 2005-10-29 devnull exits("read");
180 5cdb1798 2005-10-29 devnull
181 5cdb1798 2005-10-29 devnull /* if all users opt out, don't try matches */
182 5cdb1798 2005-10-29 devnull if(optout){
183 5cdb1798 2005-10-29 devnull if(cflag)
184 5cdb1798 2005-10-29 devnull cout = opencopy(sender);
185 5cdb1798 2005-10-29 devnull exits(qmail(args, buf, n, cout));
186 5cdb1798 2005-10-29 devnull }
187 5cdb1798 2005-10-29 devnull
188 5cdb1798 2005-10-29 devnull /* Turn off line logging, if command line matches */
189 5cdb1798 2005-10-29 devnull nolines = matchaction(Lineoff, cmd, match);
190 5cdb1798 2005-10-29 devnull
191 5cdb1798 2005-10-29 devnull for(i = 0; patterns[i].action; i++){
192 5cdb1798 2005-10-29 devnull /* Lineoff patterns were already done above */
193 5cdb1798 2005-10-29 devnull if(i == Lineoff)
194 5cdb1798 2005-10-29 devnull continue;
195 5cdb1798 2005-10-29 devnull /* don't apply "Line" patterns if excluded above */
196 5cdb1798 2005-10-29 devnull if(nolines && i == SaveLine)
197 5cdb1798 2005-10-29 devnull continue;
198 5cdb1798 2005-10-29 devnull /* apply patterns to the sender/recips, header and body */
199 5cdb1798 2005-10-29 devnull if(matchaction(i, cmd, match))
200 5cdb1798 2005-10-29 devnull break;
201 5cdb1798 2005-10-29 devnull if(matchaction(i, header+1, match))
202 5cdb1798 2005-10-29 devnull break;
203 5cdb1798 2005-10-29 devnull if(i == HoldHeader)
204 5cdb1798 2005-10-29 devnull continue;
205 5cdb1798 2005-10-29 devnull if(matchaction(i, body+1, match))
206 5cdb1798 2005-10-29 devnull break;
207 5cdb1798 2005-10-29 devnull }
208 5cdb1798 2005-10-29 devnull if(cflag && patterns[i].action == 0) /* no match found - save msg */
209 5cdb1798 2005-10-29 devnull cout = opencopy(sender);
210 5cdb1798 2005-10-29 devnull
211 5cdb1798 2005-10-29 devnull exits(qmail(args, buf, n, cout));
212 5cdb1798 2005-10-29 devnull }
213 5cdb1798 2005-10-29 devnull
214 5cdb1798 2005-10-29 devnull char*
215 5cdb1798 2005-10-29 devnull qmail(char **argv, char *buf, int n, Biobuf *cout)
216 5cdb1798 2005-10-29 devnull {
217 5cdb1798 2005-10-29 devnull Waitmsg *status;
218 5cdb1798 2005-10-29 devnull int i, pid, pipefd[2];
219 5cdb1798 2005-10-29 devnull char path[512];
220 5cdb1798 2005-10-29 devnull Biobuf *bp;
221 5cdb1798 2005-10-29 devnull
222 5cdb1798 2005-10-29 devnull pid = 0;
223 5cdb1798 2005-10-29 devnull if(tflag == 0){
224 5cdb1798 2005-10-29 devnull if(pipe(pipefd) < 0)
225 5cdb1798 2005-10-29 devnull exits("pipe");
226 5cdb1798 2005-10-29 devnull pid = fork();
227 5cdb1798 2005-10-29 devnull if(pid == 0){
228 5cdb1798 2005-10-29 devnull dup(pipefd[0], 0);
229 5cdb1798 2005-10-29 devnull for(i = sysfiles(); i >= 3; i--)
230 5cdb1798 2005-10-29 devnull close(i);
231 5cdb1798 2005-10-29 devnull snprint(path, sizeof(path), "%s/qer", UPASBIN);
232 5cdb1798 2005-10-29 devnull *argv=path;
233 5cdb1798 2005-10-29 devnull exec(path, argv);
234 5cdb1798 2005-10-29 devnull exits("exec");
235 5cdb1798 2005-10-29 devnull }
236 5cdb1798 2005-10-29 devnull Binit(&bout, pipefd[1], OWRITE);
237 5cdb1798 2005-10-29 devnull bp = &bout;
238 5cdb1798 2005-10-29 devnull } else
239 5cdb1798 2005-10-29 devnull bp = Bopen("/dev/null", OWRITE);
240 5cdb1798 2005-10-29 devnull
241 5cdb1798 2005-10-29 devnull while(n > 0){
242 5cdb1798 2005-10-29 devnull Bwrite(bp, buf, n);
243 5cdb1798 2005-10-29 devnull if(cout)
244 5cdb1798 2005-10-29 devnull Bwrite(cout, buf, n);
245 5cdb1798 2005-10-29 devnull n = Bread(&bin, buf, sizeof(buf)-1);
246 5cdb1798 2005-10-29 devnull }
247 5cdb1798 2005-10-29 devnull Bterm(bp);
248 5cdb1798 2005-10-29 devnull if(cout)
249 5cdb1798 2005-10-29 devnull Bterm(cout);
250 5cdb1798 2005-10-29 devnull if(tflag)
251 5cdb1798 2005-10-29 devnull return 0;
252 5cdb1798 2005-10-29 devnull
253 5cdb1798 2005-10-29 devnull close(pipefd[1]);
254 5cdb1798 2005-10-29 devnull close(pipefd[0]);
255 5cdb1798 2005-10-29 devnull for(;;){
256 5cdb1798 2005-10-29 devnull status = wait();
257 5cdb1798 2005-10-29 devnull if(status == nil || status->pid == pid)
258 5cdb1798 2005-10-29 devnull break;
259 5cdb1798 2005-10-29 devnull free(status);
260 5cdb1798 2005-10-29 devnull }
261 5cdb1798 2005-10-29 devnull if(status == nil)
262 5cdb1798 2005-10-29 devnull strcpy(buf, "wait failed");
263 5cdb1798 2005-10-29 devnull else{
264 5cdb1798 2005-10-29 devnull strcpy(buf, status->msg);
265 5cdb1798 2005-10-29 devnull free(status);
266 5cdb1798 2005-10-29 devnull }
267 5cdb1798 2005-10-29 devnull return buf;
268 5cdb1798 2005-10-29 devnull }
269 5cdb1798 2005-10-29 devnull
270 5cdb1798 2005-10-29 devnull char*
271 5cdb1798 2005-10-29 devnull canon(Biobuf *bp, char *header, char *body, int *n)
272 5cdb1798 2005-10-29 devnull {
273 5cdb1798 2005-10-29 devnull int hsize;
274 5cdb1798 2005-10-29 devnull char *raw;
275 5cdb1798 2005-10-29 devnull
276 5cdb1798 2005-10-29 devnull hsize = 0;
277 5cdb1798 2005-10-29 devnull *header = 0;
278 5cdb1798 2005-10-29 devnull *body = 0;
279 5cdb1798 2005-10-29 devnull raw = readmsg(bp, &hsize, n);
280 5cdb1798 2005-10-29 devnull if(raw){
281 5cdb1798 2005-10-29 devnull if(convert(raw, raw+hsize, header, Hdrsize, 0))
282 5cdb1798 2005-10-29 devnull conv64(raw+hsize, raw+*n, body, Bodysize); /* base64 */
283 5cdb1798 2005-10-29 devnull else
284 5cdb1798 2005-10-29 devnull convert(raw+hsize, raw+*n, body, Bodysize, 1); /* text */
285 5cdb1798 2005-10-29 devnull }
286 5cdb1798 2005-10-29 devnull return raw;
287 5cdb1798 2005-10-29 devnull }
288 5cdb1798 2005-10-29 devnull
289 5cdb1798 2005-10-29 devnull int
290 5cdb1798 2005-10-29 devnull matchaction(int action, char *message, Resub *m)
291 5cdb1798 2005-10-29 devnull {
292 5cdb1798 2005-10-29 devnull char *name;
293 5cdb1798 2005-10-29 devnull Pattern *p;
294 5cdb1798 2005-10-29 devnull
295 5cdb1798 2005-10-29 devnull if(message == 0 || *message == 0)
296 5cdb1798 2005-10-29 devnull return 0;
297 5cdb1798 2005-10-29 devnull
298 5cdb1798 2005-10-29 devnull name = patterns[action].action;
299 5cdb1798 2005-10-29 devnull p = patterns[action].strings;
300 5cdb1798 2005-10-29 devnull if(p)
301 5cdb1798 2005-10-29 devnull if(matcher(name, p, message, m))
302 5cdb1798 2005-10-29 devnull return 1;
303 5cdb1798 2005-10-29 devnull
304 5cdb1798 2005-10-29 devnull for(p = patterns[action].regexps; p; p = p->next)
305 5cdb1798 2005-10-29 devnull if(matcher(name, p, message, m))
306 5cdb1798 2005-10-29 devnull return 1;
307 5cdb1798 2005-10-29 devnull return 0;
308 5cdb1798 2005-10-29 devnull }
309 5cdb1798 2005-10-29 devnull
310 5cdb1798 2005-10-29 devnull int
311 5cdb1798 2005-10-29 devnull matcher(char *action, Pattern *p, char *message, Resub *m)
312 5cdb1798 2005-10-29 devnull {
313 5cdb1798 2005-10-29 devnull char *cp;
314 5cdb1798 2005-10-29 devnull String *s;
315 5cdb1798 2005-10-29 devnull
316 b5f65921 2006-02-11 devnull for(cp = message; matchpat(p, cp, m); cp = m->e.ep){
317 5cdb1798 2005-10-29 devnull switch(p->action){
318 5cdb1798 2005-10-29 devnull case SaveLine:
319 5cdb1798 2005-10-29 devnull if(vflag)
320 5cdb1798 2005-10-29 devnull xprint(2, action, m);
321 5cdb1798 2005-10-29 devnull saveline(linefile, sender, m);
322 5cdb1798 2005-10-29 devnull break;
323 5cdb1798 2005-10-29 devnull case HoldHeader:
324 5cdb1798 2005-10-29 devnull case Hold:
325 5cdb1798 2005-10-29 devnull if(nflag)
326 5cdb1798 2005-10-29 devnull continue;
327 5cdb1798 2005-10-29 devnull if(vflag)
328 5cdb1798 2005-10-29 devnull xprint(2, action, m);
329 5cdb1798 2005-10-29 devnull *qdir = holdqueue;
330 5cdb1798 2005-10-29 devnull if(hflag && qname){
331 5cdb1798 2005-10-29 devnull cp = strchr(sender, '!');
332 5cdb1798 2005-10-29 devnull if(cp){
333 5cdb1798 2005-10-29 devnull *cp = 0;
334 5cdb1798 2005-10-29 devnull *qname = strdup(sender);
335 5cdb1798 2005-10-29 devnull *cp = '!';
336 5cdb1798 2005-10-29 devnull } else
337 5cdb1798 2005-10-29 devnull *qname = strdup(sender);
338 5cdb1798 2005-10-29 devnull }
339 5cdb1798 2005-10-29 devnull return 1;
340 5cdb1798 2005-10-29 devnull case Dump:
341 5cdb1798 2005-10-29 devnull if(vflag)
342 5cdb1798 2005-10-29 devnull xprint(2, action, m);
343 b5f65921 2006-02-11 devnull *m->e.ep = 0;
344 5cdb1798 2005-10-29 devnull if(!tflag){
345 5cdb1798 2005-10-29 devnull s = s_new();
346 5cdb1798 2005-10-29 devnull s_append(s, sender);
347 5cdb1798 2005-10-29 devnull s = unescapespecial(s);
348 b5f65921 2006-02-11 devnull syslog(0, "smtpd", "Dumped %s [%s] to %s", s_to_c(s), m->s.sp,
349 5cdb1798 2005-10-29 devnull s_to_c(s_restart(recips)));
350 5cdb1798 2005-10-29 devnull s_free(s);
351 5cdb1798 2005-10-29 devnull }
352 5cdb1798 2005-10-29 devnull tflag = 1;
353 5cdb1798 2005-10-29 devnull if(sflag)
354 5cdb1798 2005-10-29 devnull cout = opendump(sender);
355 5cdb1798 2005-10-29 devnull return 1;
356 5cdb1798 2005-10-29 devnull default:
357 5cdb1798 2005-10-29 devnull break;
358 5cdb1798 2005-10-29 devnull }
359 5cdb1798 2005-10-29 devnull }
360 5cdb1798 2005-10-29 devnull return 0;
361 5cdb1798 2005-10-29 devnull }
362 5cdb1798 2005-10-29 devnull
363 5cdb1798 2005-10-29 devnull void
364 5cdb1798 2005-10-29 devnull saveline(char *file, char *sender, Resub *rp)
365 5cdb1798 2005-10-29 devnull {
366 5cdb1798 2005-10-29 devnull char *p, *q;
367 5cdb1798 2005-10-29 devnull int i, c;
368 5cdb1798 2005-10-29 devnull Biobuf *bp;
369 5cdb1798 2005-10-29 devnull
370 b5f65921 2006-02-11 devnull if(rp->s.sp == 0 || rp->e.ep == 0)
371 5cdb1798 2005-10-29 devnull return;
372 5cdb1798 2005-10-29 devnull /* back up approx 20 characters to whitespace */
373 b5f65921 2006-02-11 devnull for(p = rp->s.sp, i = 0; *p && i < 20; i++, p--)
374 5cdb1798 2005-10-29 devnull ;
375 5cdb1798 2005-10-29 devnull while(*p && *p != ' ')
376 5cdb1798 2005-10-29 devnull p--;
377 5cdb1798 2005-10-29 devnull p++;
378 5cdb1798 2005-10-29 devnull
379 5cdb1798 2005-10-29 devnull /* grab about 20 more chars beyond the end of the match */
380 b5f65921 2006-02-11 devnull for(q = rp->e.ep, i = 0; *q && i < 20; i++, q++)
381 5cdb1798 2005-10-29 devnull ;
382 5cdb1798 2005-10-29 devnull while(*q && *q != ' ')
383 5cdb1798 2005-10-29 devnull q++;
384 5cdb1798 2005-10-29 devnull
385 5cdb1798 2005-10-29 devnull c = *q;
386 5cdb1798 2005-10-29 devnull *q = 0;
387 5cdb1798 2005-10-29 devnull bp = sysopen(file, "al", 0644);
388 5cdb1798 2005-10-29 devnull if(bp){
389 5cdb1798 2005-10-29 devnull Bprint(bp, "%s-> %s\n", sender, p);
390 5cdb1798 2005-10-29 devnull Bterm(bp);
391 5cdb1798 2005-10-29 devnull }
392 5cdb1798 2005-10-29 devnull else if(debug)
393 5cdb1798 2005-10-29 devnull fprint(2, "can't save line: (%s) %s\n", sender, p);
394 5cdb1798 2005-10-29 devnull *q = c;
395 5cdb1798 2005-10-29 devnull }
396 5cdb1798 2005-10-29 devnull
397 5cdb1798 2005-10-29 devnull Biobuf*
398 5cdb1798 2005-10-29 devnull opendump(char *sender)
399 5cdb1798 2005-10-29 devnull {
400 5cdb1798 2005-10-29 devnull int i;
401 5cdb1798 2005-10-29 devnull ulong h;
402 5cdb1798 2005-10-29 devnull char buf[512];
403 5cdb1798 2005-10-29 devnull Biobuf *b;
404 5cdb1798 2005-10-29 devnull char *cp;
405 5cdb1798 2005-10-29 devnull
406 5cdb1798 2005-10-29 devnull cp = ctime(time(0));
407 5cdb1798 2005-10-29 devnull cp[7] = 0;
408 5cdb1798 2005-10-29 devnull cp[10] = 0;
409 5cdb1798 2005-10-29 devnull if(cp[8] == ' ')
410 5cdb1798 2005-10-29 devnull sprint(buf, "%s/queue.dump/%s%c", SPOOL, cp+4, cp[9]);
411 5cdb1798 2005-10-29 devnull else
412 5cdb1798 2005-10-29 devnull sprint(buf, "%s/queue.dump/%s%c%c", SPOOL, cp+4, cp[8], cp[9]);
413 5cdb1798 2005-10-29 devnull cp = buf+strlen(buf);
414 5cdb1798 2005-10-29 devnull if(access(buf, 0) < 0 && sysmkdir(buf, 0777) < 0){
415 5cdb1798 2005-10-29 devnull syslog(0, "smtpd", "couldn't dump mail from %s: %r", sender);
416 5cdb1798 2005-10-29 devnull return 0;
417 5cdb1798 2005-10-29 devnull }
418 5cdb1798 2005-10-29 devnull
419 5cdb1798 2005-10-29 devnull h = 0;
420 5cdb1798 2005-10-29 devnull while(*sender)
421 5cdb1798 2005-10-29 devnull h = h*257 + *sender++;
422 5cdb1798 2005-10-29 devnull for(i = 0; i < 50; i++){
423 5cdb1798 2005-10-29 devnull h += lrand();
424 5cdb1798 2005-10-29 devnull sprint(cp, "/%lud", h);
425 5cdb1798 2005-10-29 devnull b = sysopen(buf, "wlc", 0644);
426 5cdb1798 2005-10-29 devnull if(b){
427 5cdb1798 2005-10-29 devnull if(vflag)
428 5cdb1798 2005-10-29 devnull fprint(2, "saving in %s\n", buf);
429 5cdb1798 2005-10-29 devnull return b;
430 5cdb1798 2005-10-29 devnull }
431 5cdb1798 2005-10-29 devnull }
432 5cdb1798 2005-10-29 devnull return 0;
433 5cdb1798 2005-10-29 devnull }
434 5cdb1798 2005-10-29 devnull
435 5cdb1798 2005-10-29 devnull Biobuf*
436 5cdb1798 2005-10-29 devnull opencopy(char *sender)
437 5cdb1798 2005-10-29 devnull {
438 5cdb1798 2005-10-29 devnull int i;
439 5cdb1798 2005-10-29 devnull ulong h;
440 5cdb1798 2005-10-29 devnull char buf[512];
441 5cdb1798 2005-10-29 devnull Biobuf *b;
442 5cdb1798 2005-10-29 devnull
443 5cdb1798 2005-10-29 devnull h = 0;
444 5cdb1798 2005-10-29 devnull while(*sender)
445 5cdb1798 2005-10-29 devnull h = h*257 + *sender++;
446 5cdb1798 2005-10-29 devnull for(i = 0; i < 50; i++){
447 5cdb1798 2005-10-29 devnull h += lrand();
448 5cdb1798 2005-10-29 devnull sprint(buf, "%s/%lud", copydir, h);
449 5cdb1798 2005-10-29 devnull b = sysopen(buf, "wlc", 0600);
450 5cdb1798 2005-10-29 devnull if(b)
451 5cdb1798 2005-10-29 devnull return b;
452 5cdb1798 2005-10-29 devnull }
453 5cdb1798 2005-10-29 devnull return 0;
454 5cdb1798 2005-10-29 devnull }
455 5cdb1798 2005-10-29 devnull
456 5cdb1798 2005-10-29 devnull int
457 5cdb1798 2005-10-29 devnull optoutofspamfilter(char *addr)
458 5cdb1798 2005-10-29 devnull {
459 5cdb1798 2005-10-29 devnull char *p, *f;
460 5cdb1798 2005-10-29 devnull int rv;
461 5cdb1798 2005-10-29 devnull
462 5cdb1798 2005-10-29 devnull p = strchr(addr, '!');
463 5cdb1798 2005-10-29 devnull if(p)
464 5cdb1798 2005-10-29 devnull p++;
465 5cdb1798 2005-10-29 devnull else
466 5cdb1798 2005-10-29 devnull p = addr;
467 5cdb1798 2005-10-29 devnull
468 5cdb1798 2005-10-29 devnull rv = 0;
469 5cdb1798 2005-10-29 devnull f = smprint("/mail/box/%s/nospamfiltering", p);
470 5cdb1798 2005-10-29 devnull if(f != nil){
471 5cdb1798 2005-10-29 devnull rv = access(f, 0)==0;
472 5cdb1798 2005-10-29 devnull free(f);
473 5cdb1798 2005-10-29 devnull }
474 5cdb1798 2005-10-29 devnull
475 5cdb1798 2005-10-29 devnull return rv;
476 5cdb1798 2005-10-29 devnull }