xref: /plan9/sys/src/cmd/upas/scanmail/testscan.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 #include "sys.h"
2 #include "spam.h"
3 
4 int 	debug;
5 Biobuf	bin;
6 char	patfile[128], header[Hdrsize+2];
7 char	cmd[1024];
8 
9 char*	canon(Biobuf*, char*, char*, int*);
10 int	matcher(char *, Pattern*, char*, Resub*);
11 int	matchaction(Patterns*, char*);
12 
13 void
usage(void)14 usage(void)
15 {
16 	fprint(2, "missing or bad arguments to qer\n");
17 	exits("usage");
18 }
19 
20 void *
Malloc(long n)21 Malloc(long n)
22 {
23 	void *p;
24 
25 	p = malloc(n);
26 	if(p == 0){
27 		fprint(2, "malloc error");
28 		exits("malloc");
29 	}
30 	return p;
31 }
32 
33 void*
Realloc(void * p,ulong n)34 Realloc(void *p, ulong n)
35 {
36 	p = realloc(p, n);
37 	if(p == 0){
38 		fprint(2, "realloc error");
39 		exits("realloc");
40 	}
41 	return p;
42 }
43 
44 void
dumppats(void)45 dumppats(void)
46 {
47 	int i, j;
48 	Pattern *p;
49 	Spat *s, *q;
50 
51 	for(i = 0; patterns[i].action; i++){
52 		for(p = patterns[i].regexps; p; p = p->next){
53 			print("%s <REGEXP>\n", patterns[i].action);
54 			if(p->alt)
55 				print("Alt:");
56 			for(s = p->alt; s; s = s->next)
57 				print("\t%s\n", s->string);
58 		}
59 		p = patterns[i].strings;
60 		if(p == 0)
61 			continue;
62 
63 		for(j = 0; j < Nhash; j++){
64 			for(s = p->spat[j]; s; s = s->next){
65 				print("%s %s\n", patterns[i].action, s->string);
66 				if(s->alt)
67 					print("Alt:");
68 				for(q = s->alt; q; q = q->next)
69 					print("\t%s\n", q->string);
70 			}
71 		}
72 	}
73 }
74 
75 void
main(int argc,char * argv[])76 main(int argc, char *argv[])
77 {
78 	int i, fd, n, aflag, vflag;
79 	char body[Bodysize+2], *raw, *ret;
80 	Biobuf *bp;
81 
82 	sprint(patfile, "%s/patterns", UPASLIB);
83 	aflag = -1;
84 	vflag = 0;
85 	ARGBEGIN {
86 	case 'a':
87 		aflag = 1;
88 		break;
89 	case 'v':
90 		vflag = 1;
91 		break;
92 	case 'd':
93 		debug++;
94 		break;
95 	case 'p':
96 		strcpy(patfile,ARGF());
97 		break;
98 	} ARGEND
99 
100 	bp = Bopen(patfile, OREAD);
101 	if(bp){
102 		parsepats(bp);
103 		Bterm(bp);
104 	}
105 
106 	if(argc >= 1){
107 		fd = open(*argv, OREAD);
108 		if(fd < 0){
109 			fprint(2, "can't open %s\n", *argv);
110 			exits("open");
111 		}
112 		Binit(&bin, fd, OREAD);
113 	} else
114 		Binit(&bin, 0, OREAD);
115 
116 	*body = 0;
117 	*header = 0;
118 	ret = 0;
119 	for(;;){
120 		raw = canon(&bin, header+1, body+1, &n);
121 		if(raw == 0)
122 			break;
123 		if(aflag == 0)
124 			continue;
125 		if(aflag < 0)
126 			aflag = 0;
127 		if(vflag){
128 			if(header[1]) {
129 				fprint(2, "\t**** Header ****\n\n");
130 				write(2, header+1, strlen(header+1));
131 				fprint(2, "\n");
132 			}
133 			fprint(2, "\t**** Body ****\n\n");
134 			if(body[1])
135 				write(2, body+1, strlen(body+1));
136 			fprint(2, "\n");
137 		}
138 
139 		for(i = 0; patterns[i].action; i++){
140 			if(matchaction(&patterns[i], header+1))
141 				ret = patterns[i].action;
142 			if(i == HoldHeader)
143 				continue;
144 			if(matchaction(&patterns[i], body+1))
145 				ret = patterns[i].action;
146 		}
147 	}
148 	exits(ret);
149 }
150 
151 char*
canon(Biobuf * bp,char * header,char * body,int * n)152 canon(Biobuf *bp, char *header, char *body, int *n)
153 {
154 	int hsize, base64;
155 
156 	static char *raw;
157 
158 	hsize = 0;
159 	base64 = 0;
160 	*header = 0;
161 	*body = 0;
162 	if(raw == 0){
163 		raw = readmsg(bp, &hsize, n);
164 		if(raw)
165 			base64 = convert(raw, raw+hsize, header, Hdrsize, 0);
166 	} else {
167 		free(raw);
168 		raw = readmsg(bp, 0, n);
169 	}
170 	if(raw){
171 		if(base64)
172 			conv64(raw+hsize, raw+*n, body, Bodysize);
173 		else
174 			convert(raw+hsize, raw+*n, body, Bodysize, 1);
175 	}
176 	return raw;
177 }
178 
179 int
matchaction(Patterns * pp,char * message)180 matchaction(Patterns *pp, char *message)
181 {
182 	char *name, *cp;
183 	int ret;
184 	Pattern *p;
185 	Resub m[1];
186 
187 	if(message == 0 || *message == 0)
188 		return 0;
189 
190 	name = pp->action;
191 	p = pp->strings;
192 	ret = 0;
193 	if(p)
194 		for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
195 				ret++;
196 
197 	for(p = pp->regexps; p; p = p->next)
198 		for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
199 				ret++;
200 	return ret;
201 }
202 
203 int
matcher(char * action,Pattern * p,char * message,Resub * m)204 matcher(char *action, Pattern *p, char *message, Resub *m)
205 {
206 	if(matchpat(p, message, m)){
207 		if(p->action != Lineoff)
208 			xprint(1, action, m);
209 		return 1;
210 	}
211 	return 0;
212 }
213