xref: /plan9/sys/src/cmd/upas/scanmail/testscan.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
180ee5cbfSDavid du Colombier #include "sys.h"
280ee5cbfSDavid du Colombier #include "spam.h"
37dd7cddfSDavid du Colombier 
47dd7cddfSDavid du Colombier int 	debug;
580ee5cbfSDavid du Colombier Biobuf	bin;
680ee5cbfSDavid du Colombier char	patfile[128], header[Hdrsize+2];
780ee5cbfSDavid du Colombier char	cmd[1024];
87dd7cddfSDavid du Colombier 
97dd7cddfSDavid du Colombier char*	canon(Biobuf*, char*, char*, int*);
1080ee5cbfSDavid du Colombier int	matcher(char *, Pattern*, char*, Resub*);
1180ee5cbfSDavid du Colombier int	matchaction(Patterns*, char*);
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier void
usage(void)147dd7cddfSDavid du Colombier usage(void)
157dd7cddfSDavid du Colombier {
167dd7cddfSDavid du Colombier 	fprint(2, "missing or bad arguments to qer\n");
177dd7cddfSDavid du Colombier 	exits("usage");
187dd7cddfSDavid du Colombier }
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier void *
Malloc(long n)217dd7cddfSDavid du Colombier Malloc(long n)
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier 	void *p;
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	p = malloc(n);
2680ee5cbfSDavid du Colombier 	if(p == 0){
2780ee5cbfSDavid du Colombier 		fprint(2, "malloc error");
287dd7cddfSDavid du Colombier 		exits("malloc");
2980ee5cbfSDavid du Colombier 	}
3080ee5cbfSDavid du Colombier 	return p;
3180ee5cbfSDavid du Colombier }
3280ee5cbfSDavid du Colombier 
3380ee5cbfSDavid du Colombier void*
Realloc(void * p,ulong n)3480ee5cbfSDavid du Colombier Realloc(void *p, ulong n)
3580ee5cbfSDavid du Colombier {
3680ee5cbfSDavid du Colombier 	p = realloc(p, n);
3780ee5cbfSDavid du Colombier 	if(p == 0){
3880ee5cbfSDavid du Colombier 		fprint(2, "realloc error");
3980ee5cbfSDavid du Colombier 		exits("realloc");
4080ee5cbfSDavid du Colombier 	}
417dd7cddfSDavid du Colombier 	return p;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier 
447dd7cddfSDavid du Colombier void
dumppats(void)457dd7cddfSDavid du Colombier dumppats(void)
467dd7cddfSDavid du Colombier {
4780ee5cbfSDavid du Colombier 	int i, j;
487dd7cddfSDavid du Colombier 	Pattern *p;
497dd7cddfSDavid du Colombier 	Spat *s, *q;
507dd7cddfSDavid du Colombier 
5180ee5cbfSDavid du Colombier 	for(i = 0; patterns[i].action; i++){
5280ee5cbfSDavid du Colombier 		for(p = patterns[i].regexps; p; p = p->next){
5380ee5cbfSDavid du Colombier 			print("%s <REGEXP>\n", patterns[i].action);
5480ee5cbfSDavid du Colombier 			if(p->alt)
5580ee5cbfSDavid du Colombier 				print("Alt:");
567dd7cddfSDavid du Colombier 			for(s = p->alt; s; s = s->next)
577dd7cddfSDavid du Colombier 				print("\t%s\n", s->string);
5880ee5cbfSDavid du Colombier 		}
5980ee5cbfSDavid du Colombier 		p = patterns[i].strings;
6080ee5cbfSDavid du Colombier 		if(p == 0)
6180ee5cbfSDavid du Colombier 			continue;
6280ee5cbfSDavid du Colombier 
6380ee5cbfSDavid du Colombier 		for(j = 0; j < Nhash; j++){
6480ee5cbfSDavid du Colombier 			for(s = p->spat[j]; s; s = s->next){
6580ee5cbfSDavid du Colombier 				print("%s %s\n", patterns[i].action, s->string);
6680ee5cbfSDavid du Colombier 				if(s->alt)
6780ee5cbfSDavid du Colombier 					print("Alt:");
687dd7cddfSDavid du Colombier 				for(q = s->alt; q; q = q->next)
697dd7cddfSDavid du Colombier 					print("\t%s\n", q->string);
707dd7cddfSDavid du Colombier 			}
717dd7cddfSDavid du Colombier 		}
727dd7cddfSDavid du Colombier 	}
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier void
main(int argc,char * argv[])767dd7cddfSDavid du Colombier main(int argc, char *argv[])
777dd7cddfSDavid du Colombier {
7880ee5cbfSDavid du Colombier 	int i, fd, n, aflag, vflag;
7980ee5cbfSDavid du Colombier 	char body[Bodysize+2], *raw, *ret;
807dd7cddfSDavid du Colombier 	Biobuf *bp;
817dd7cddfSDavid du Colombier 
827dd7cddfSDavid du Colombier 	sprint(patfile, "%s/patterns", UPASLIB);
837dd7cddfSDavid du Colombier 	aflag = -1;
847dd7cddfSDavid du Colombier 	vflag = 0;
857dd7cddfSDavid du Colombier 	ARGBEGIN {
867dd7cddfSDavid du Colombier 	case 'a':
877dd7cddfSDavid du Colombier 		aflag = 1;
887dd7cddfSDavid du Colombier 		break;
897dd7cddfSDavid du Colombier 	case 'v':
907dd7cddfSDavid du Colombier 		vflag = 1;
917dd7cddfSDavid du Colombier 		break;
927dd7cddfSDavid du Colombier 	case 'd':
937dd7cddfSDavid du Colombier 		debug++;
947dd7cddfSDavid du Colombier 		break;
957dd7cddfSDavid du Colombier 	case 'p':
967dd7cddfSDavid du Colombier 		strcpy(patfile,ARGF());
977dd7cddfSDavid du Colombier 		break;
987dd7cddfSDavid du Colombier 	} ARGEND
997dd7cddfSDavid du Colombier 
1007dd7cddfSDavid du Colombier 	bp = Bopen(patfile, OREAD);
1017dd7cddfSDavid du Colombier 	if(bp){
1027dd7cddfSDavid du Colombier 		parsepats(bp);
1037dd7cddfSDavid du Colombier 		Bterm(bp);
1047dd7cddfSDavid du Colombier 	}
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	if(argc >= 1){
1077dd7cddfSDavid du Colombier 		fd = open(*argv, OREAD);
1087dd7cddfSDavid du Colombier 		if(fd < 0){
1097dd7cddfSDavid du Colombier 			fprint(2, "can't open %s\n", *argv);
1107dd7cddfSDavid du Colombier 			exits("open");
1117dd7cddfSDavid du Colombier 		}
1127dd7cddfSDavid du Colombier 		Binit(&bin, fd, OREAD);
1137dd7cddfSDavid du Colombier 	} else
1147dd7cddfSDavid du Colombier 		Binit(&bin, 0, OREAD);
1157dd7cddfSDavid du Colombier 
1167dd7cddfSDavid du Colombier 	*body = 0;
1177dd7cddfSDavid du Colombier 	*header = 0;
11880ee5cbfSDavid du Colombier 	ret = 0;
1197dd7cddfSDavid du Colombier 	for(;;){
1207dd7cddfSDavid du Colombier 		raw = canon(&bin, header+1, body+1, &n);
1217dd7cddfSDavid du Colombier 		if(raw == 0)
1227dd7cddfSDavid du Colombier 			break;
1237dd7cddfSDavid du Colombier 		if(aflag == 0)
1247dd7cddfSDavid du Colombier 			continue;
1257dd7cddfSDavid du Colombier 		if(aflag < 0)
1267dd7cddfSDavid du Colombier 			aflag = 0;
12780ee5cbfSDavid du Colombier 		if(vflag){
12880ee5cbfSDavid du Colombier 			if(header[1]) {
12980ee5cbfSDavid du Colombier 				fprint(2, "\t**** Header ****\n\n");
13080ee5cbfSDavid du Colombier 				write(2, header+1, strlen(header+1));
13180ee5cbfSDavid du Colombier 				fprint(2, "\n");
13280ee5cbfSDavid du Colombier 			}
13380ee5cbfSDavid du Colombier 			fprint(2, "\t**** Body ****\n\n");
13480ee5cbfSDavid du Colombier 			if(body[1])
13580ee5cbfSDavid du Colombier 				write(2, body+1, strlen(body+1));
13680ee5cbfSDavid du Colombier 			fprint(2, "\n");
13780ee5cbfSDavid du Colombier 		}
1387dd7cddfSDavid du Colombier 
13980ee5cbfSDavid du Colombier 		for(i = 0; patterns[i].action; i++){
14080ee5cbfSDavid du Colombier 			if(matchaction(&patterns[i], header+1))
14180ee5cbfSDavid du Colombier 				ret = patterns[i].action;
14280ee5cbfSDavid du Colombier 			if(i == HoldHeader)
1437dd7cddfSDavid du Colombier 				continue;
14480ee5cbfSDavid du Colombier 			if(matchaction(&patterns[i], body+1))
14580ee5cbfSDavid du Colombier 				ret = patterns[i].action;
1467dd7cddfSDavid du Colombier 		}
1477dd7cddfSDavid du Colombier 	}
14880ee5cbfSDavid du Colombier 	exits(ret);
1497dd7cddfSDavid du Colombier }
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier char*
canon(Biobuf * bp,char * header,char * body,int * n)1527dd7cddfSDavid du Colombier canon(Biobuf *bp, char *header, char *body, int *n)
1537dd7cddfSDavid du Colombier {
154*9a747e4fSDavid du Colombier 	int hsize, base64;
1557dd7cddfSDavid du Colombier 
15680ee5cbfSDavid du Colombier 	static char *raw;
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier 	hsize = 0;
159*9a747e4fSDavid du Colombier 	base64 = 0;
1607dd7cddfSDavid du Colombier 	*header = 0;
1617dd7cddfSDavid du Colombier 	*body = 0;
16280ee5cbfSDavid du Colombier 	if(raw == 0){
16380ee5cbfSDavid du Colombier 		raw = readmsg(bp, &hsize, n);
16480ee5cbfSDavid du Colombier 		if(raw)
165*9a747e4fSDavid du Colombier 			base64 = convert(raw, raw+hsize, header, Hdrsize, 0);
16680ee5cbfSDavid du Colombier 	} else {
16780ee5cbfSDavid du Colombier 		free(raw);
16880ee5cbfSDavid du Colombier 		raw = readmsg(bp, 0, n);
1697dd7cddfSDavid du Colombier 	}
170*9a747e4fSDavid du Colombier 	if(raw){
171*9a747e4fSDavid du Colombier 		if(base64)
172*9a747e4fSDavid du Colombier 			conv64(raw+hsize, raw+*n, body, Bodysize);
173*9a747e4fSDavid du Colombier 		else
17480ee5cbfSDavid du Colombier 			convert(raw+hsize, raw+*n, body, Bodysize, 1);
175*9a747e4fSDavid du Colombier 	}
17680ee5cbfSDavid du Colombier 	return raw;
1777dd7cddfSDavid du Colombier }
1787dd7cddfSDavid du Colombier 
1797dd7cddfSDavid du Colombier int
matchaction(Patterns * pp,char * message)18080ee5cbfSDavid du Colombier matchaction(Patterns *pp, char *message)
1817dd7cddfSDavid du Colombier {
18280ee5cbfSDavid du Colombier 	char *name, *cp;
18380ee5cbfSDavid du Colombier 	int ret;
18480ee5cbfSDavid du Colombier 	Pattern *p;
18580ee5cbfSDavid du Colombier 	Resub m[1];
1867dd7cddfSDavid du Colombier 
18780ee5cbfSDavid du Colombier 	if(message == 0 || *message == 0)
18880ee5cbfSDavid du Colombier 		return 0;
18980ee5cbfSDavid du Colombier 
19080ee5cbfSDavid du Colombier 	name = pp->action;
19180ee5cbfSDavid du Colombier 	p = pp->strings;
19280ee5cbfSDavid du Colombier 	ret = 0;
19380ee5cbfSDavid du Colombier 	if(p)
19480ee5cbfSDavid du Colombier 		for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
19580ee5cbfSDavid du Colombier 				ret++;
19680ee5cbfSDavid du Colombier 
19780ee5cbfSDavid du Colombier 	for(p = pp->regexps; p; p = p->next)
19880ee5cbfSDavid du Colombier 		for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
19980ee5cbfSDavid du Colombier 				ret++;
20080ee5cbfSDavid du Colombier 	return ret;
2017dd7cddfSDavid du Colombier }
2027dd7cddfSDavid du Colombier 
20380ee5cbfSDavid du Colombier int
matcher(char * action,Pattern * p,char * message,Resub * m)20480ee5cbfSDavid du Colombier matcher(char *action, Pattern *p, char *message, Resub *m)
2057dd7cddfSDavid du Colombier {
20680ee5cbfSDavid du Colombier 	if(matchpat(p, message, m)){
20780ee5cbfSDavid du Colombier 		if(p->action != Lineoff)
20880ee5cbfSDavid du Colombier 			xprint(1, action, m);
20980ee5cbfSDavid du Colombier 		return 1;
21080ee5cbfSDavid du Colombier 	}
21180ee5cbfSDavid du Colombier 	return 0;
2127dd7cddfSDavid du Colombier }
213