213 lines
3.4 KiB
C
213 lines
3.4 KiB
C
#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;
|
|
}
|