#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;
}
|