| #include "sys.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, "missing or bad arguments to qer\n"); |
| exits("usage"); |
| } |
| |
| void * |
| Malloc(long n) |
| { |
| void *p; |
| |
| p = malloc(n); |
| if(p == 0){ |
| fprint(2, "malloc error"); |
| exits("malloc"); |
| } |
| return p; |
| } |
| |
| void* |
| Realloc(void *p, ulong n) |
| { |
| p = realloc(p, n); |
| if(p == 0){ |
| fprint(2, "realloc error"); |
| exits("realloc"); |
| } |
| 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; |
| |
| sprint(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': |
| strcpy(patfile,ARGF()); |
| 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].e.ep) |
| ret++; |
| |
| for(p = pp->regexps; p; p = p->next) |
| for(cp = message; matcher(name, p, cp, m); cp = m[0].e.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; |
| } |