static int optoutall(int filterstate) { Link *l; switch(filterstate){ case ACCEPT: case TRUSTED: return filterstate; } for(l = rcvers.first; l; l = l->next) if(!optoutofspamfilter(s_to_c(l->p))) return filterstate; return ACCEPT; }
void main(int argc, char *argv[]) { int i, n, nolines, optout; char **args, **a, *cp, *buf; char body[Bodysize+2]; Resub match[1]; Biobuf *bp; optout = 1; a = args = Malloc((argc+1)*sizeof(char*)); sprint(patfile, "%s/patterns", UPASLIB); sprint(linefile, "%s/lines", UPASLOG); sprint(holdqueue, "%s/queue.hold", SPOOL); sprint(copydir, "%s/copy", SPOOL); *a++ = argv[0]; for(argc--, argv++; argv[0] && argv[0][0] == '-'; argc--, argv++) { switch(argv[0][1]) { case 'c': /* save copy of message */ cflag = 1; break; case 'd': /* debug */ debug++; *a++ = argv[0]; break; case 'h': /* queue held messages by sender domain */ hflag = 1; /* -q flag must be set also */ break; case 'n': /* NOHOLD mode */ nflag = 1; break; case 'p': /* pattern file */ if(argv[0][2] || argv[1] == 0) usage(); argc--; argv++; strecpy(patfile, patfile+sizeof patfile, *argv); break; case 'q': /* queue name */ if(argv[0][2] || argv[1] == 0) usage(); *a++ = argv[0]; argc--; argv++; qname = a; *a++ = argv[0]; break; case 's': /* save copy of dumped message */ sflag = 1; break; case 't': /* test mode - don't log match * and write message to /dev/null */ tflag = 1; break; case 'v': /* vebose - print matches */ vflag = 1; break; default: *a++ = argv[0]; break; } } if(argc < 3) usage(); Binit(&bin, 0, OREAD); bp = Bopen(patfile, OREAD); if(bp) { parsepats(bp); Bterm(bp); } qdir = a; sender = argv[2]; /* copy the rest of argv, acummulating the recipients as we go */ for(i = 0; argv[i]; i++) { *a++ = argv[i]; if(i < 4) /* skip queue, 'mail', sender, dest sys */ continue; /* recipients and smtp flags - skip the latter*/ if(strcmp(argv[i], "-g") == 0) { *a++ = argv[++i]; continue; } if(recips) s_append(recips, ", "); else recips = s_new(); s_append(recips, argv[i]); if(optout && !optoutofspamfilter(argv[i])) optout = 0; } *a = 0; /* construct a command string for matching */ snprint(cmd, sizeof(cmd)-1, "%s %s", sender, s_to_c(recips)); cmd[sizeof(cmd)-1] = 0; for(cp = cmd; *cp; cp++) *cp = tolower(*cp); /* canonicalize a copy of the header and body. * buf points to orginal message and n contains * number of bytes of original message read during * canonicalization. */ *body = 0; *header = 0; buf = canon(&bin, header+1, body+1, &n); if (buf == 0) exits("read"); /* if all users opt out, don't try matches */ if(optout) { if(cflag) cout = opencopy(sender); exits(qmail(args, buf, n, cout)); } /* Turn off line logging, if command line matches */ nolines = matchaction(Lineoff, cmd, match); for(i = 0; patterns[i].action; i++) { /* Lineoff patterns were already done above */ if(i == Lineoff) continue; /* don't apply "Line" patterns if excluded above */ if(nolines && i == SaveLine) continue; /* apply patterns to the sender/recips, header and body */ if(matchaction(i, cmd, match)) break; if(matchaction(i, header+1, match)) break; if(i == HoldHeader) continue; if(matchaction(i, body+1, match)) break; } if(cflag && patterns[i].action == 0) /* no match found - save msg */ cout = opencopy(sender); exits(qmail(args, buf, n, cout)); }