ref: 1132d1b9df4c9ea2b857fa9778fe6762cd81ded8
dir: /sys/src/cmd/upas/scanmail/testscan.c/
#include "common.h" #include <regexp.h> #include "spam.h" int debug; Biobuf bin; char patfile[128], header[Hdrsize+2]; char cmd[1024]; char* canon(Biobuf*, char*, char*, int*); int matcher(char *, Pattern*, char*, Resub*); int matchaction(Patterns*, char*); void usage(void) { fprint(2, "usage: testscan -avd [-p pattern] ...\n"); exits("usage"); } void * Malloc(long n) { void *p; p = malloc(n); if(p == nil) sysfatal("malloc: %r"); setmalloctag(p, getcallerpc(&n)); return p; } void* Realloc(void *p, ulong n) { p = realloc(p, n); if(p == nil) sysfatal("malloc: %r"); setrealloctag(p, getcallerpc(&p)); return p; } void dumppats(void) { int i, j; Pattern *p; Spat *s, *q; for(i = 0; patterns[i].action; i++){ for(p = patterns[i].regexps; p; p = p->next){ print("%s <REGEXP>\n", patterns[i].action); if(p->alt) print("Alt:"); for(s = p->alt; s; s = s->next) print("\t%s\n", s->string); } p = patterns[i].strings; if(p == 0) continue; for(j = 0; j < Nhash; j++){ for(s = p->spat[j]; s; s = s->next){ print("%s %s\n", patterns[i].action, s->string); if(s->alt) print("Alt:"); for(q = s->alt; q; q = q->next) print("\t%s\n", q->string); } } } } void main(int argc, char *argv[]) { int i, fd, n, aflag, vflag; char body[Bodysize+2], *raw, *ret; Biobuf *bp; snprint(patfile, sizeof patfile, "%s/patterns", UPASLIB); aflag = -1; vflag = 0; ARGBEGIN { case 'a': aflag = 1; break; case 'v': vflag = 1; break; case 'd': debug++; break; case 'p': snprint(patfile, sizeof patfile, "%s", EARGF(usage())); break; } ARGEND bp = Bopen(patfile, OREAD); if(bp){ parsepats(bp); Bterm(bp); } if(argc >= 1){ fd = open(*argv, OREAD); if(fd < 0){ fprint(2, "can't open %s\n", *argv); exits("open"); } Binit(&bin, fd, OREAD); } else Binit(&bin, 0, OREAD); *body = 0; *header = 0; ret = 0; for(;;){ raw = canon(&bin, header+1, body+1, &n); if(raw == 0) break; if(aflag == 0) continue; if(aflag < 0) aflag = 0; if(vflag){ if(header[1]) { fprint(2, "\t**** Header ****\n\n"); write(2, header+1, strlen(header+1)); fprint(2, "\n"); } fprint(2, "\t**** Body ****\n\n"); if(body[1]) write(2, body+1, strlen(body+1)); fprint(2, "\n"); } for(i = 0; patterns[i].action; i++){ if(matchaction(&patterns[i], header+1)) ret = patterns[i].action; if(i == HoldHeader) continue; if(matchaction(&patterns[i], body+1)) ret = patterns[i].action; } } exits(ret); } char* canon(Biobuf *bp, char *header, char *body, int *n) { int hsize, base64; static char *raw; hsize = 0; base64 = 0; *header = 0; *body = 0; if(raw == 0){ raw = readmsg(bp, &hsize, n); if(raw) base64 = convert(raw, raw+hsize, header, Hdrsize, 0); } else { free(raw); raw = readmsg(bp, 0, n); } if(raw){ if(base64) conv64(raw+hsize, raw+*n, body, Bodysize); else convert(raw+hsize, raw+*n, body, Bodysize, 1); } return raw; } int matchaction(Patterns *pp, char *message) { char *name, *cp; int ret; Pattern *p; Resub m[1]; if(message == 0 || *message == 0) return 0; name = pp->action; p = pp->strings; ret = 0; if(p) for(cp = message; matcher(name, p, cp, m); cp = m[0].ep) ret++; for(p = pp->regexps; p; p = p->next) for(cp = message; matcher(name, p, cp, m); cp = m[0].ep) ret++; return ret; } int matcher(char *action, Pattern *p, char *message, Resub *m) { if(matchpat(p, message, m)){ if(p->action != Lineoff) xprint(1, action, m); return 1; } return 0; }