17dd7cddfSDavid du Colombier #include "common.h"
280ee5cbfSDavid du Colombier #include "spam.h"
37dd7cddfSDavid du Colombier
47dd7cddfSDavid du Colombier int cflag;
57dd7cddfSDavid du Colombier int debug;
67dd7cddfSDavid du Colombier int hflag;
77dd7cddfSDavid du Colombier int nflag;
87dd7cddfSDavid du Colombier int sflag;
97dd7cddfSDavid du Colombier int tflag;
107dd7cddfSDavid du Colombier int vflag;
117dd7cddfSDavid du Colombier Biobuf bin, bout, *cout;
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier /* file names */
147dd7cddfSDavid du Colombier char patfile[128];
157dd7cddfSDavid du Colombier char linefile[128];
167dd7cddfSDavid du Colombier char holdqueue[128];
177dd7cddfSDavid du Colombier char copydir[128];
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier char header[Hdrsize+2];
20223a736eSDavid du Colombier char cmd[1024];
217dd7cddfSDavid du Colombier char **qname;
227dd7cddfSDavid du Colombier char **qdir;
237dd7cddfSDavid du Colombier char *sender;
247dd7cddfSDavid du Colombier String *recips;
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier char* canon(Biobuf*, char*, char*, int*);
2780ee5cbfSDavid du Colombier int matcher(char*, Pattern*, char*, Resub*);
2880ee5cbfSDavid du Colombier int matchaction(int, char*, Resub*);
297dd7cddfSDavid du Colombier Biobuf *opencopy(char*);
307dd7cddfSDavid du Colombier Biobuf *opendump(char*);
317dd7cddfSDavid du Colombier char *qmail(char**, char*, int, Biobuf*);
327dd7cddfSDavid du Colombier void saveline(char*, char*, Resub*);
336b6b9ac8SDavid du Colombier int optoutofspamfilter(char*);
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier void
usage(void)367dd7cddfSDavid du Colombier usage(void)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier fprint(2, "missing or bad arguments to qer\n");
397dd7cddfSDavid du Colombier exits("usage");
407dd7cddfSDavid du Colombier }
417dd7cddfSDavid du Colombier
42fb7f0c93SDavid du Colombier void
regerror(char * s)43fb7f0c93SDavid du Colombier regerror(char *s)
44fb7f0c93SDavid du Colombier {
45fb7f0c93SDavid du Colombier fprint(2, "scanmail: %s\n", s);
46fb7f0c93SDavid du Colombier }
47fb7f0c93SDavid du Colombier
487dd7cddfSDavid du Colombier void *
Malloc(long n)497dd7cddfSDavid du Colombier Malloc(long n)
507dd7cddfSDavid du Colombier {
517dd7cddfSDavid du Colombier void *p;
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier p = malloc(n);
547dd7cddfSDavid du Colombier if(p == 0)
557dd7cddfSDavid du Colombier exits("malloc");
567dd7cddfSDavid du Colombier return p;
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier
5980ee5cbfSDavid du Colombier void*
Realloc(void * p,ulong n)6080ee5cbfSDavid du Colombier Realloc(void *p, ulong n)
6180ee5cbfSDavid du Colombier {
6280ee5cbfSDavid du Colombier p = realloc(p, n);
6380ee5cbfSDavid du Colombier if(p == 0)
6480ee5cbfSDavid du Colombier exits("realloc");
6580ee5cbfSDavid du Colombier return p;
6680ee5cbfSDavid du Colombier }
6780ee5cbfSDavid du Colombier
687dd7cddfSDavid du Colombier void
main(int argc,char * argv[])697dd7cddfSDavid du Colombier main(int argc, char *argv[])
707dd7cddfSDavid du Colombier {
716b6b9ac8SDavid du Colombier int i, n, nolines, optout;
727dd7cddfSDavid du Colombier char **args, **a, *cp, *buf;
7380ee5cbfSDavid du Colombier char body[Bodysize+2];
747dd7cddfSDavid du Colombier Resub match[1];
757dd7cddfSDavid du Colombier Biobuf *bp;
767dd7cddfSDavid du Colombier
776b6b9ac8SDavid du Colombier optout = 1;
787dd7cddfSDavid du Colombier a = args = Malloc((argc+1)*sizeof(char*));
797dd7cddfSDavid du Colombier sprint(patfile, "%s/patterns", UPASLIB);
807dd7cddfSDavid du Colombier sprint(linefile, "%s/lines", UPASLOG);
817dd7cddfSDavid du Colombier sprint(holdqueue, "%s/queue.hold", SPOOL);
827dd7cddfSDavid du Colombier sprint(copydir, "%s/copy", SPOOL);
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier *a++ = argv[0];
857dd7cddfSDavid du Colombier for(argc--, argv++; argv[0] && argv[0][0] == '-'; argc--, argv++){
867dd7cddfSDavid du Colombier switch(argv[0][1]){
877dd7cddfSDavid du Colombier case 'c': /* save copy of message */
887dd7cddfSDavid du Colombier cflag = 1;
897dd7cddfSDavid du Colombier break;
907dd7cddfSDavid du Colombier case 'd': /* debug */
917dd7cddfSDavid du Colombier debug++;
927dd7cddfSDavid du Colombier *a++ = argv[0];
937dd7cddfSDavid du Colombier break;
947dd7cddfSDavid du Colombier case 'h': /* queue held messages by sender domain */
957dd7cddfSDavid du Colombier hflag = 1; /* -q flag must be set also */
967dd7cddfSDavid du Colombier break;
977dd7cddfSDavid du Colombier case 'n': /* NOHOLD mode */
987dd7cddfSDavid du Colombier nflag = 1;
997dd7cddfSDavid du Colombier break;
1007dd7cddfSDavid du Colombier case 'p': /* pattern file */
1017dd7cddfSDavid du Colombier if(argv[0][2] || argv[1] == 0)
1027dd7cddfSDavid du Colombier usage();
1037dd7cddfSDavid du Colombier argc--;
1047dd7cddfSDavid du Colombier argv++;
105*4d44ba9bSDavid du Colombier strecpy(patfile, patfile+sizeof patfile, *argv);
1067dd7cddfSDavid du Colombier break;
1077dd7cddfSDavid du Colombier case 'q': /* queue name */
1087dd7cddfSDavid du Colombier if(argv[0][2] || argv[1] == 0)
1097dd7cddfSDavid du Colombier usage();
1107dd7cddfSDavid du Colombier *a++ = argv[0];
1117dd7cddfSDavid du Colombier argc--;
1127dd7cddfSDavid du Colombier argv++;
1137dd7cddfSDavid du Colombier qname = a;
1147dd7cddfSDavid du Colombier *a++ = argv[0];
1157dd7cddfSDavid du Colombier break;
1167dd7cddfSDavid du Colombier case 's': /* save copy of dumped message */
1177dd7cddfSDavid du Colombier sflag = 1;
1187dd7cddfSDavid du Colombier break;
1197dd7cddfSDavid du Colombier case 't': /* test mode - don't log match
1207dd7cddfSDavid du Colombier * and write message to /dev/null
1217dd7cddfSDavid du Colombier */
1227dd7cddfSDavid du Colombier tflag = 1;
1237dd7cddfSDavid du Colombier break;
1247dd7cddfSDavid du Colombier case 'v': /* vebose - print matches */
1257dd7cddfSDavid du Colombier vflag = 1;
1267dd7cddfSDavid du Colombier break;
1277dd7cddfSDavid du Colombier default:
1287dd7cddfSDavid du Colombier *a++ = argv[0];
1297dd7cddfSDavid du Colombier break;
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier }
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier if(argc < 3)
1347dd7cddfSDavid du Colombier usage();
1357dd7cddfSDavid du Colombier
1367dd7cddfSDavid du Colombier Binit(&bin, 0, OREAD);
1377dd7cddfSDavid du Colombier bp = Bopen(patfile, OREAD);
1387dd7cddfSDavid du Colombier if(bp){
1397dd7cddfSDavid du Colombier parsepats(bp);
1407dd7cddfSDavid du Colombier Bterm(bp);
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier qdir = a;
1437dd7cddfSDavid du Colombier sender = argv[2];
1447dd7cddfSDavid du Colombier
1457dd7cddfSDavid du Colombier /* copy the rest of argv, acummulating the recipients as we go */
1467dd7cddfSDavid du Colombier for(i = 0; argv[i]; i++){
1477dd7cddfSDavid du Colombier *a++ = argv[i];
1487dd7cddfSDavid du Colombier if(i < 4) /* skip queue, 'mail', sender, dest sys */
1497dd7cddfSDavid du Colombier continue;
1507dd7cddfSDavid du Colombier /* recipients and smtp flags - skip the latter*/
1517dd7cddfSDavid du Colombier if(strcmp(argv[i], "-g") == 0){
1527dd7cddfSDavid du Colombier *a++ = argv[++i];
1537dd7cddfSDavid du Colombier continue;
1547dd7cddfSDavid du Colombier }
1557dd7cddfSDavid du Colombier if(recips)
1567dd7cddfSDavid du Colombier s_append(recips, ", ");
1577dd7cddfSDavid du Colombier else
1587dd7cddfSDavid du Colombier recips = s_new();
1597dd7cddfSDavid du Colombier s_append(recips, argv[i]);
1606b6b9ac8SDavid du Colombier if(optout && !optoutofspamfilter(argv[i]))
1616b6b9ac8SDavid du Colombier optout = 0;
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier *a = 0;
1647dd7cddfSDavid du Colombier /* construct a command string for matching */
1657dd7cddfSDavid du Colombier snprint(cmd, sizeof(cmd)-1, "%s %s", sender, s_to_c(recips));
1667dd7cddfSDavid du Colombier cmd[sizeof(cmd)-1] = 0;
1677dd7cddfSDavid du Colombier for(cp = cmd; *cp; cp++)
1687dd7cddfSDavid du Colombier *cp = tolower(*cp);
1697dd7cddfSDavid du Colombier
1707dd7cddfSDavid du Colombier /* canonicalize a copy of the header and body.
1717dd7cddfSDavid du Colombier * buf points to orginal message and n contains
1727dd7cddfSDavid du Colombier * number of bytes of original message read during
1737dd7cddfSDavid du Colombier * canonicalization.
1747dd7cddfSDavid du Colombier */
1757dd7cddfSDavid du Colombier *body = 0;
1767dd7cddfSDavid du Colombier *header = 0;
1777dd7cddfSDavid du Colombier buf = canon(&bin, header+1, body+1, &n);
1787dd7cddfSDavid du Colombier if (buf == 0)
1797dd7cddfSDavid du Colombier exits("read");
1807dd7cddfSDavid du Colombier
1816b6b9ac8SDavid du Colombier /* if all users opt out, don't try matches */
1826b6b9ac8SDavid du Colombier if(optout){
1836b6b9ac8SDavid du Colombier if(cflag)
1846b6b9ac8SDavid du Colombier cout = opencopy(sender);
1856b6b9ac8SDavid du Colombier exits(qmail(args, buf, n, cout));
1866b6b9ac8SDavid du Colombier }
1876b6b9ac8SDavid du Colombier
18880ee5cbfSDavid du Colombier /* Turn off line logging, if command line matches */
18980ee5cbfSDavid du Colombier nolines = matchaction(Lineoff, cmd, match);
1907dd7cddfSDavid du Colombier
19180ee5cbfSDavid du Colombier for(i = 0; patterns[i].action; i++){
19280ee5cbfSDavid du Colombier /* Lineoff patterns were already done above */
19380ee5cbfSDavid du Colombier if(i == Lineoff)
1947dd7cddfSDavid du Colombier continue;
19580ee5cbfSDavid du Colombier /* don't apply "Line" patterns if excluded above */
19680ee5cbfSDavid du Colombier if(nolines && i == SaveLine)
1977dd7cddfSDavid du Colombier continue;
19880ee5cbfSDavid du Colombier /* apply patterns to the sender/recips, header and body */
19980ee5cbfSDavid du Colombier if(matchaction(i, cmd, match))
20080ee5cbfSDavid du Colombier break;
20180ee5cbfSDavid du Colombier if(matchaction(i, header+1, match))
20280ee5cbfSDavid du Colombier break;
20380ee5cbfSDavid du Colombier if(i == HoldHeader)
20480ee5cbfSDavid du Colombier continue;
20580ee5cbfSDavid du Colombier if(matchaction(i, body+1, match))
20680ee5cbfSDavid du Colombier break;
2077dd7cddfSDavid du Colombier }
20880ee5cbfSDavid du Colombier if(cflag && patterns[i].action == 0) /* no match found - save msg */
2097dd7cddfSDavid du Colombier cout = opencopy(sender);
21080ee5cbfSDavid du Colombier
2117dd7cddfSDavid du Colombier exits(qmail(args, buf, n, cout));
2127dd7cddfSDavid du Colombier }
2137dd7cddfSDavid du Colombier
2147dd7cddfSDavid du Colombier char*
qmail(char ** argv,char * buf,int n,Biobuf * cout)2157dd7cddfSDavid du Colombier qmail(char **argv, char *buf, int n, Biobuf *cout)
2167dd7cddfSDavid du Colombier {
2179a747e4fSDavid du Colombier Waitmsg *status;
2189a747e4fSDavid du Colombier int i, pid, pipefd[2];
2197dd7cddfSDavid du Colombier char path[512];
2207dd7cddfSDavid du Colombier Biobuf *bp;
2217dd7cddfSDavid du Colombier
2227dd7cddfSDavid du Colombier pid = 0;
2237dd7cddfSDavid du Colombier if(tflag == 0){
2247dd7cddfSDavid du Colombier if(pipe(pipefd) < 0)
2257dd7cddfSDavid du Colombier exits("pipe");
2267dd7cddfSDavid du Colombier pid = fork();
2277dd7cddfSDavid du Colombier if(pid == 0){
2287dd7cddfSDavid du Colombier dup(pipefd[0], 0);
2297dd7cddfSDavid du Colombier for(i = sysfiles(); i >= 3; i--)
2307dd7cddfSDavid du Colombier close(i);
2317dd7cddfSDavid du Colombier snprint(path, sizeof(path), "%s/qer", UPASBIN);
2327dd7cddfSDavid du Colombier *argv=path;
2337dd7cddfSDavid du Colombier exec(path, argv);
2347dd7cddfSDavid du Colombier exits("exec");
2357dd7cddfSDavid du Colombier }
2367dd7cddfSDavid du Colombier Binit(&bout, pipefd[1], OWRITE);
2377dd7cddfSDavid du Colombier bp = &bout;
2387dd7cddfSDavid du Colombier } else
2397dd7cddfSDavid du Colombier bp = Bopen("/dev/null", OWRITE);
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier while(n > 0){
2427dd7cddfSDavid du Colombier Bwrite(bp, buf, n);
2437dd7cddfSDavid du Colombier if(cout)
2447dd7cddfSDavid du Colombier Bwrite(cout, buf, n);
2457dd7cddfSDavid du Colombier n = Bread(&bin, buf, sizeof(buf)-1);
2467dd7cddfSDavid du Colombier }
2477dd7cddfSDavid du Colombier Bterm(bp);
2487dd7cddfSDavid du Colombier if(cout)
2497dd7cddfSDavid du Colombier Bterm(cout);
2507dd7cddfSDavid du Colombier if(tflag)
2517dd7cddfSDavid du Colombier return 0;
2527dd7cddfSDavid du Colombier
2537dd7cddfSDavid du Colombier close(pipefd[1]);
2547dd7cddfSDavid du Colombier close(pipefd[0]);
2557dd7cddfSDavid du Colombier for(;;){
2569a747e4fSDavid du Colombier status = wait();
2579a747e4fSDavid du Colombier if(status == nil || status->pid == pid)
2587dd7cddfSDavid du Colombier break;
2599a747e4fSDavid du Colombier free(status);
2607dd7cddfSDavid du Colombier }
2619a747e4fSDavid du Colombier if(status == nil)
2629a747e4fSDavid du Colombier strcpy(buf, "wait failed");
2639a747e4fSDavid du Colombier else{
2649a747e4fSDavid du Colombier strcpy(buf, status->msg);
2659a747e4fSDavid du Colombier free(status);
2669a747e4fSDavid du Colombier }
2677dd7cddfSDavid du Colombier return buf;
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier
27080ee5cbfSDavid du Colombier char*
canon(Biobuf * bp,char * header,char * body,int * n)27180ee5cbfSDavid du Colombier canon(Biobuf *bp, char *header, char *body, int *n)
2727dd7cddfSDavid du Colombier {
27380ee5cbfSDavid du Colombier int hsize;
27480ee5cbfSDavid du Colombier char *raw;
27580ee5cbfSDavid du Colombier
27680ee5cbfSDavid du Colombier hsize = 0;
27780ee5cbfSDavid du Colombier *header = 0;
27880ee5cbfSDavid du Colombier *body = 0;
27980ee5cbfSDavid du Colombier raw = readmsg(bp, &hsize, n);
28080ee5cbfSDavid du Colombier if(raw){
2819a747e4fSDavid du Colombier if(convert(raw, raw+hsize, header, Hdrsize, 0))
2829a747e4fSDavid du Colombier conv64(raw+hsize, raw+*n, body, Bodysize); /* base64 */
2839a747e4fSDavid du Colombier else
2849a747e4fSDavid du Colombier convert(raw+hsize, raw+*n, body, Bodysize, 1); /* text */
28580ee5cbfSDavid du Colombier }
28680ee5cbfSDavid du Colombier return raw;
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier
2897dd7cddfSDavid du Colombier int
matchaction(int action,char * message,Resub * m)29080ee5cbfSDavid du Colombier matchaction(int action, char *message, Resub *m)
29180ee5cbfSDavid du Colombier {
29280ee5cbfSDavid du Colombier char *name;
29380ee5cbfSDavid du Colombier Pattern *p;
29480ee5cbfSDavid du Colombier
29580ee5cbfSDavid du Colombier if(message == 0 || *message == 0)
29680ee5cbfSDavid du Colombier return 0;
29780ee5cbfSDavid du Colombier
29880ee5cbfSDavid du Colombier name = patterns[action].action;
29980ee5cbfSDavid du Colombier p = patterns[action].strings;
30080ee5cbfSDavid du Colombier if(p)
30180ee5cbfSDavid du Colombier if(matcher(name, p, message, m))
30280ee5cbfSDavid du Colombier return 1;
30380ee5cbfSDavid du Colombier
30480ee5cbfSDavid du Colombier for(p = patterns[action].regexps; p; p = p->next)
30580ee5cbfSDavid du Colombier if(matcher(name, p, message, m))
30680ee5cbfSDavid du Colombier return 1;
30780ee5cbfSDavid du Colombier return 0;
30880ee5cbfSDavid du Colombier }
30980ee5cbfSDavid du Colombier
31080ee5cbfSDavid du Colombier int
matcher(char * action,Pattern * p,char * message,Resub * m)31180ee5cbfSDavid du Colombier matcher(char *action, Pattern *p, char *message, Resub *m)
3127dd7cddfSDavid du Colombier {
3137dd7cddfSDavid du Colombier char *cp;
3147dd7cddfSDavid du Colombier String *s;
3157dd7cddfSDavid du Colombier
3167dd7cddfSDavid du Colombier for(cp = message; matchpat(p, cp, m); cp = m->ep){
31780ee5cbfSDavid du Colombier switch(p->action){
3187dd7cddfSDavid du Colombier case SaveLine:
3197dd7cddfSDavid du Colombier if(vflag)
32080ee5cbfSDavid du Colombier xprint(2, action, m);
3217dd7cddfSDavid du Colombier saveline(linefile, sender, m);
3227dd7cddfSDavid du Colombier break;
3237dd7cddfSDavid du Colombier case HoldHeader:
3247dd7cddfSDavid du Colombier case Hold:
3257dd7cddfSDavid du Colombier if(nflag)
3267dd7cddfSDavid du Colombier continue;
3277dd7cddfSDavid du Colombier if(vflag)
32880ee5cbfSDavid du Colombier xprint(2, action, m);
3297dd7cddfSDavid du Colombier *qdir = holdqueue;
3307dd7cddfSDavid du Colombier if(hflag && qname){
3317dd7cddfSDavid du Colombier cp = strchr(sender, '!');
3327dd7cddfSDavid du Colombier if(cp){
3337dd7cddfSDavid du Colombier *cp = 0;
3347dd7cddfSDavid du Colombier *qname = strdup(sender);
3357dd7cddfSDavid du Colombier *cp = '!';
3367dd7cddfSDavid du Colombier } else
3377dd7cddfSDavid du Colombier *qname = strdup(sender);
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier return 1;
3407dd7cddfSDavid du Colombier case Dump:
3417dd7cddfSDavid du Colombier if(vflag)
34280ee5cbfSDavid du Colombier xprint(2, action, m);
3437dd7cddfSDavid du Colombier *(m->ep) = 0;
3447dd7cddfSDavid du Colombier if(!tflag){
3457dd7cddfSDavid du Colombier s = s_new();
3467dd7cddfSDavid du Colombier s_append(s, sender);
3477dd7cddfSDavid du Colombier s = unescapespecial(s);
3487dd7cddfSDavid du Colombier syslog(0, "smtpd", "Dumped %s [%s] to %s", s_to_c(s), m->sp,
3497dd7cddfSDavid du Colombier s_to_c(s_restart(recips)));
3507dd7cddfSDavid du Colombier s_free(s);
3517dd7cddfSDavid du Colombier }
3527dd7cddfSDavid du Colombier tflag = 1;
3537dd7cddfSDavid du Colombier if(sflag)
3547dd7cddfSDavid du Colombier cout = opendump(sender);
3557dd7cddfSDavid du Colombier return 1;
3567dd7cddfSDavid du Colombier default:
3577dd7cddfSDavid du Colombier break;
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier }
3607dd7cddfSDavid du Colombier return 0;
3617dd7cddfSDavid du Colombier }
3627dd7cddfSDavid du Colombier
3637dd7cddfSDavid du Colombier void
saveline(char * file,char * sender,Resub * rp)3647dd7cddfSDavid du Colombier saveline(char *file, char *sender, Resub *rp)
3657dd7cddfSDavid du Colombier {
3667dd7cddfSDavid du Colombier char *p, *q;
3677dd7cddfSDavid du Colombier int i, c;
3687dd7cddfSDavid du Colombier Biobuf *bp;
3697dd7cddfSDavid du Colombier
3707dd7cddfSDavid du Colombier if(rp->sp == 0 || rp->ep == 0)
3717dd7cddfSDavid du Colombier return;
3727dd7cddfSDavid du Colombier /* back up approx 20 characters to whitespace */
3737dd7cddfSDavid du Colombier for(p = rp->sp, i = 0; *p && i < 20; i++, p--)
3747dd7cddfSDavid du Colombier ;
3757dd7cddfSDavid du Colombier while(*p && *p != ' ')
3767dd7cddfSDavid du Colombier p--;
3777dd7cddfSDavid du Colombier p++;
3787dd7cddfSDavid du Colombier
3797dd7cddfSDavid du Colombier /* grab about 20 more chars beyond the end of the match */
3807dd7cddfSDavid du Colombier for(q = rp->ep, i = 0; *q && i < 20; i++, q++)
3817dd7cddfSDavid du Colombier ;
3827dd7cddfSDavid du Colombier while(*q && *q != ' ')
3837dd7cddfSDavid du Colombier q++;
3847dd7cddfSDavid du Colombier
3857dd7cddfSDavid du Colombier c = *q;
3867dd7cddfSDavid du Colombier *q = 0;
3877dd7cddfSDavid du Colombier bp = sysopen(file, "al", 0644);
3887dd7cddfSDavid du Colombier if(bp){
3897dd7cddfSDavid du Colombier Bprint(bp, "%s-> %s\n", sender, p);
3907dd7cddfSDavid du Colombier Bterm(bp);
3917dd7cddfSDavid du Colombier }
3927dd7cddfSDavid du Colombier else if(debug)
3937dd7cddfSDavid du Colombier fprint(2, "can't save line: (%s) %s\n", sender, p);
3947dd7cddfSDavid du Colombier *q = c;
3957dd7cddfSDavid du Colombier }
3967dd7cddfSDavid du Colombier
3977dd7cddfSDavid du Colombier Biobuf*
opendump(char * sender)3987dd7cddfSDavid du Colombier opendump(char *sender)
3997dd7cddfSDavid du Colombier {
4007dd7cddfSDavid du Colombier int i;
4017dd7cddfSDavid du Colombier ulong h;
4027dd7cddfSDavid du Colombier char buf[512];
4037dd7cddfSDavid du Colombier Biobuf *b;
4047dd7cddfSDavid du Colombier char *cp;
4057dd7cddfSDavid du Colombier
4067dd7cddfSDavid du Colombier cp = ctime(time(0));
4077dd7cddfSDavid du Colombier cp[7] = 0;
4087dd7cddfSDavid du Colombier cp[10] = 0;
4097dd7cddfSDavid du Colombier if(cp[8] == ' ')
4107dd7cddfSDavid du Colombier sprint(buf, "%s/queue.dump/%s%c", SPOOL, cp+4, cp[9]);
4117dd7cddfSDavid du Colombier else
4127dd7cddfSDavid du Colombier sprint(buf, "%s/queue.dump/%s%c%c", SPOOL, cp+4, cp[8], cp[9]);
4137dd7cddfSDavid du Colombier cp = buf+strlen(buf);
4149a747e4fSDavid du Colombier if(access(buf, 0) < 0 && sysmkdir(buf, 0777) < 0){
4159a747e4fSDavid du Colombier syslog(0, "smtpd", "couldn't dump mail from %s: %r", sender);
4167dd7cddfSDavid du Colombier return 0;
4179a747e4fSDavid du Colombier }
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier h = 0;
4207dd7cddfSDavid du Colombier while(*sender)
4217dd7cddfSDavid du Colombier h = h*257 + *sender++;
4227dd7cddfSDavid du Colombier for(i = 0; i < 50; i++){
4237dd7cddfSDavid du Colombier h += lrand();
4247dd7cddfSDavid du Colombier sprint(cp, "/%lud", h);
42580ee5cbfSDavid du Colombier b = sysopen(buf, "wlc", 0644);
4267dd7cddfSDavid du Colombier if(b){
4277dd7cddfSDavid du Colombier if(vflag)
4287dd7cddfSDavid du Colombier fprint(2, "saving in %s\n", buf);
4297dd7cddfSDavid du Colombier return b;
4307dd7cddfSDavid du Colombier }
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier return 0;
4337dd7cddfSDavid du Colombier }
4347dd7cddfSDavid du Colombier
4357dd7cddfSDavid du Colombier Biobuf*
opencopy(char * sender)4367dd7cddfSDavid du Colombier opencopy(char *sender)
4377dd7cddfSDavid du Colombier {
4387dd7cddfSDavid du Colombier int i;
4397dd7cddfSDavid du Colombier ulong h;
4407dd7cddfSDavid du Colombier char buf[512];
4417dd7cddfSDavid du Colombier Biobuf *b;
4427dd7cddfSDavid du Colombier
4437dd7cddfSDavid du Colombier h = 0;
4447dd7cddfSDavid du Colombier while(*sender)
4457dd7cddfSDavid du Colombier h = h*257 + *sender++;
4467dd7cddfSDavid du Colombier for(i = 0; i < 50; i++){
4477dd7cddfSDavid du Colombier h += lrand();
4487dd7cddfSDavid du Colombier sprint(buf, "%s/%lud", copydir, h);
4497dd7cddfSDavid du Colombier b = sysopen(buf, "wlc", 0600);
4507dd7cddfSDavid du Colombier if(b)
4517dd7cddfSDavid du Colombier return b;
4527dd7cddfSDavid du Colombier }
4537dd7cddfSDavid du Colombier return 0;
4547dd7cddfSDavid du Colombier }
4556b6b9ac8SDavid du Colombier
4566b6b9ac8SDavid du Colombier int
optoutofspamfilter(char * addr)4576b6b9ac8SDavid du Colombier optoutofspamfilter(char *addr)
4586b6b9ac8SDavid du Colombier {
4596b6b9ac8SDavid du Colombier char *p, *f;
4606b6b9ac8SDavid du Colombier int rv;
4616b6b9ac8SDavid du Colombier
4626b6b9ac8SDavid du Colombier p = strchr(addr, '!');
4636b6b9ac8SDavid du Colombier if(p)
4646b6b9ac8SDavid du Colombier p++;
4656b6b9ac8SDavid du Colombier else
4666b6b9ac8SDavid du Colombier p = addr;
4676b6b9ac8SDavid du Colombier
4686b6b9ac8SDavid du Colombier rv = 0;
4696b6b9ac8SDavid du Colombier f = smprint("/mail/box/%s/nospamfiltering", p);
4706b6b9ac8SDavid du Colombier if(f != nil){
4716b6b9ac8SDavid du Colombier rv = access(f, 0)==0;
4726b6b9ac8SDavid du Colombier free(f);
4736b6b9ac8SDavid du Colombier }
4746b6b9ac8SDavid du Colombier
4756b6b9ac8SDavid du Colombier return rv;
4766b6b9ac8SDavid du Colombier }
477