Blame


1 5cdb1798 2005-10-29 devnull #include <u.h>
2 5cdb1798 2005-10-29 devnull #include <libc.h>
3 5cdb1798 2005-10-29 devnull #include <regexp.h>
4 5cdb1798 2005-10-29 devnull #include <libsec.h>
5 b5f65921 2006-02-11 devnull #include <libString.h>
6 5cdb1798 2005-10-29 devnull #include <bio.h>
7 5cdb1798 2005-10-29 devnull #include "dat.h"
8 5cdb1798 2005-10-29 devnull
9 5cdb1798 2005-10-29 devnull int debug;
10 5cdb1798 2005-10-29 devnull
11 5cdb1798 2005-10-29 devnull enum
12 5cdb1798 2005-10-29 devnull {
13 5cdb1798 2005-10-29 devnull Tregexp= (1<<0), /* ~ */
14 5cdb1798 2005-10-29 devnull Texact= (1<<1), /* = */
15 5cdb1798 2005-10-29 devnull };
16 5cdb1798 2005-10-29 devnull
17 5cdb1798 2005-10-29 devnull typedef struct Pattern Pattern;
18 5cdb1798 2005-10-29 devnull struct Pattern
19 5cdb1798 2005-10-29 devnull {
20 5cdb1798 2005-10-29 devnull Pattern *next;
21 5cdb1798 2005-10-29 devnull int type;
22 5cdb1798 2005-10-29 devnull char *arg;
23 5cdb1798 2005-10-29 devnull int bang;
24 5cdb1798 2005-10-29 devnull };
25 5cdb1798 2005-10-29 devnull
26 5cdb1798 2005-10-29 devnull String *patternpath;
27 5cdb1798 2005-10-29 devnull Pattern *patterns;
28 5cdb1798 2005-10-29 devnull String *mbox;
29 5cdb1798 2005-10-29 devnull
30 5cdb1798 2005-10-29 devnull static void
31 5cdb1798 2005-10-29 devnull usage(void)
32 5cdb1798 2005-10-29 devnull {
33 5cdb1798 2005-10-29 devnull fprint(2, "usage: %s 'check|add' patternfile addr [addr*]\n", argv0);
34 5cdb1798 2005-10-29 devnull exits("usage");
35 5cdb1798 2005-10-29 devnull }
36 5cdb1798 2005-10-29 devnull
37 5cdb1798 2005-10-29 devnull /*
38 5cdb1798 2005-10-29 devnull * convert string to lower case
39 5cdb1798 2005-10-29 devnull */
40 5cdb1798 2005-10-29 devnull static void
41 5cdb1798 2005-10-29 devnull mklower(char *p)
42 5cdb1798 2005-10-29 devnull {
43 5cdb1798 2005-10-29 devnull int c;
44 5cdb1798 2005-10-29 devnull
45 5cdb1798 2005-10-29 devnull for(; *p; p++){
46 5cdb1798 2005-10-29 devnull c = *p;
47 5cdb1798 2005-10-29 devnull if(c <= 'Z' && c >= 'A')
48 5cdb1798 2005-10-29 devnull *p = c - 'A' + 'a';
49 5cdb1798 2005-10-29 devnull }
50 5cdb1798 2005-10-29 devnull }
51 5cdb1798 2005-10-29 devnull
52 5cdb1798 2005-10-29 devnull /*
53 5cdb1798 2005-10-29 devnull * simplify an address, reduce to a domain
54 5cdb1798 2005-10-29 devnull */
55 5cdb1798 2005-10-29 devnull static String*
56 5cdb1798 2005-10-29 devnull simplify(char *addr)
57 5cdb1798 2005-10-29 devnull {
58 5cdb1798 2005-10-29 devnull int dots;
59 5cdb1798 2005-10-29 devnull char *p, *at;
60 5cdb1798 2005-10-29 devnull String *s;
61 5cdb1798 2005-10-29 devnull
62 5cdb1798 2005-10-29 devnull mklower(addr);
63 5cdb1798 2005-10-29 devnull at = strchr(addr, '@');
64 5cdb1798 2005-10-29 devnull if(at == nil){
65 5cdb1798 2005-10-29 devnull /* local address, make it an exact match */
66 5cdb1798 2005-10-29 devnull s = s_copy("=");
67 5cdb1798 2005-10-29 devnull s_append(s, addr);
68 5cdb1798 2005-10-29 devnull return s;
69 5cdb1798 2005-10-29 devnull }
70 5cdb1798 2005-10-29 devnull
71 5cdb1798 2005-10-29 devnull /* copy up to the '@' sign */
72 5cdb1798 2005-10-29 devnull at++;
73 5cdb1798 2005-10-29 devnull s = s_copy("~");
74 5cdb1798 2005-10-29 devnull for(p = addr; p < at; p++){
75 5cdb1798 2005-10-29 devnull if(strchr(".*+?(|)\\[]^$", *p))
76 5cdb1798 2005-10-29 devnull s_putc(s, '\\');
77 5cdb1798 2005-10-29 devnull s_putc(s, *p);
78 5cdb1798 2005-10-29 devnull }
79 5cdb1798 2005-10-29 devnull
80 5cdb1798 2005-10-29 devnull /* just any address matching the two most significant domain elements */
81 5cdb1798 2005-10-29 devnull s_append(s, "(.*\\.)?");
82 5cdb1798 2005-10-29 devnull p = addr+strlen(addr);
83 5cdb1798 2005-10-29 devnull dots = 0;
84 5cdb1798 2005-10-29 devnull for(; p > at; p--){
85 5cdb1798 2005-10-29 devnull if(*p != '.')
86 5cdb1798 2005-10-29 devnull continue;
87 5cdb1798 2005-10-29 devnull if(dots++ > 0){
88 5cdb1798 2005-10-29 devnull p++;
89 5cdb1798 2005-10-29 devnull break;
90 5cdb1798 2005-10-29 devnull }
91 5cdb1798 2005-10-29 devnull }
92 5cdb1798 2005-10-29 devnull for(; *p; p++){
93 5cdb1798 2005-10-29 devnull if(strchr(".*+?(|)\\[]^$", *p) != 0)
94 5cdb1798 2005-10-29 devnull s_putc(s, '\\');
95 5cdb1798 2005-10-29 devnull s_putc(s, *p);
96 5cdb1798 2005-10-29 devnull }
97 5cdb1798 2005-10-29 devnull s_terminate(s);
98 5cdb1798 2005-10-29 devnull
99 5cdb1798 2005-10-29 devnull return s;
100 5cdb1798 2005-10-29 devnull }
101 5cdb1798 2005-10-29 devnull
102 5cdb1798 2005-10-29 devnull /*
103 5cdb1798 2005-10-29 devnull * link patterns in order
104 5cdb1798 2005-10-29 devnull */
105 5cdb1798 2005-10-29 devnull static int
106 5cdb1798 2005-10-29 devnull newpattern(int type, char *arg, int bang)
107 5cdb1798 2005-10-29 devnull {
108 5cdb1798 2005-10-29 devnull Pattern *p;
109 5cdb1798 2005-10-29 devnull static Pattern *last;
110 5cdb1798 2005-10-29 devnull
111 5cdb1798 2005-10-29 devnull mklower(arg);
112 5cdb1798 2005-10-29 devnull
113 5cdb1798 2005-10-29 devnull p = mallocz(sizeof *p, 1);
114 5cdb1798 2005-10-29 devnull if(p == nil)
115 5cdb1798 2005-10-29 devnull return -1;
116 5cdb1798 2005-10-29 devnull if(type == Tregexp){
117 5cdb1798 2005-10-29 devnull p->arg = malloc(strlen(arg)+3);
118 5cdb1798 2005-10-29 devnull if(p->arg == nil){
119 5cdb1798 2005-10-29 devnull free(p);
120 5cdb1798 2005-10-29 devnull return -1;
121 5cdb1798 2005-10-29 devnull }
122 5cdb1798 2005-10-29 devnull p->arg[0] = 0;
123 5cdb1798 2005-10-29 devnull strcat(p->arg, "^");
124 5cdb1798 2005-10-29 devnull strcat(p->arg, arg);
125 5cdb1798 2005-10-29 devnull strcat(p->arg, "$");
126 5cdb1798 2005-10-29 devnull } else {
127 5cdb1798 2005-10-29 devnull p->arg = strdup(arg);
128 5cdb1798 2005-10-29 devnull if(p->arg == nil){
129 5cdb1798 2005-10-29 devnull free(p);
130 5cdb1798 2005-10-29 devnull return -1;
131 5cdb1798 2005-10-29 devnull }
132 5cdb1798 2005-10-29 devnull }
133 5cdb1798 2005-10-29 devnull p->type = type;
134 5cdb1798 2005-10-29 devnull p->bang = bang;
135 5cdb1798 2005-10-29 devnull if(last == nil)
136 5cdb1798 2005-10-29 devnull patterns = p;
137 5cdb1798 2005-10-29 devnull else
138 5cdb1798 2005-10-29 devnull last->next = p;
139 5cdb1798 2005-10-29 devnull last = p;
140 5cdb1798 2005-10-29 devnull
141 5cdb1798 2005-10-29 devnull return 0;
142 5cdb1798 2005-10-29 devnull }
143 5cdb1798 2005-10-29 devnull
144 5cdb1798 2005-10-29 devnull /*
145 5cdb1798 2005-10-29 devnull * patterns are either
146 5cdb1798 2005-10-29 devnull * ~ regular expression
147 5cdb1798 2005-10-29 devnull * = exact match string
148 5cdb1798 2005-10-29 devnull *
149 5cdb1798 2005-10-29 devnull * all comparisons are case insensitive
150 5cdb1798 2005-10-29 devnull */
151 5cdb1798 2005-10-29 devnull static int
152 5cdb1798 2005-10-29 devnull readpatterns(char *path)
153 5cdb1798 2005-10-29 devnull {
154 5cdb1798 2005-10-29 devnull Biobuf *b;
155 5cdb1798 2005-10-29 devnull char *p;
156 5cdb1798 2005-10-29 devnull char *token[2];
157 5cdb1798 2005-10-29 devnull int n;
158 5cdb1798 2005-10-29 devnull int bang;
159 5cdb1798 2005-10-29 devnull
160 5cdb1798 2005-10-29 devnull b = Bopen(path, OREAD);
161 5cdb1798 2005-10-29 devnull if(b == nil)
162 5cdb1798 2005-10-29 devnull return -1;
163 5cdb1798 2005-10-29 devnull while((p = Brdline(b, '\n')) != nil){
164 5cdb1798 2005-10-29 devnull p[Blinelen(b)-1] = 0;
165 5cdb1798 2005-10-29 devnull n = tokenize(p, token, 2);
166 5cdb1798 2005-10-29 devnull if(n == 0)
167 5cdb1798 2005-10-29 devnull continue;
168 5cdb1798 2005-10-29 devnull
169 5cdb1798 2005-10-29 devnull mklower(token[0]);
170 5cdb1798 2005-10-29 devnull p = token[0];
171 5cdb1798 2005-10-29 devnull if(*p == '!'){
172 5cdb1798 2005-10-29 devnull p++;
173 5cdb1798 2005-10-29 devnull bang = 1;
174 5cdb1798 2005-10-29 devnull } else
175 5cdb1798 2005-10-29 devnull bang = 0;
176 5cdb1798 2005-10-29 devnull
177 5cdb1798 2005-10-29 devnull if(*p == '='){
178 5cdb1798 2005-10-29 devnull if(newpattern(Texact, p+1, bang) < 0)
179 5cdb1798 2005-10-29 devnull return -1;
180 5cdb1798 2005-10-29 devnull } else if(*p == '~'){
181 5cdb1798 2005-10-29 devnull if(newpattern(Tregexp, p+1, bang) < 0)
182 5cdb1798 2005-10-29 devnull return -1;
183 5cdb1798 2005-10-29 devnull } else if(strcmp(token[0], "#include") == 0 && n == 2)
184 5cdb1798 2005-10-29 devnull readpatterns(token[1]);
185 5cdb1798 2005-10-29 devnull }
186 5cdb1798 2005-10-29 devnull Bterm(b);
187 5cdb1798 2005-10-29 devnull return 0;
188 5cdb1798 2005-10-29 devnull }
189 5cdb1798 2005-10-29 devnull
190 5cdb1798 2005-10-29 devnull /* fuck, shit, bugger, damn */
191 b5f65921 2006-02-11 devnull void regerror(char *err)
192 5cdb1798 2005-10-29 devnull {
193 b5f65921 2006-02-11 devnull USED(err);
194 5cdb1798 2005-10-29 devnull }
195 5cdb1798 2005-10-29 devnull
196 5cdb1798 2005-10-29 devnull /*
197 5cdb1798 2005-10-29 devnull * check lower case version of address agains patterns
198 5cdb1798 2005-10-29 devnull */
199 5cdb1798 2005-10-29 devnull static Pattern*
200 5cdb1798 2005-10-29 devnull checkaddr(char *arg)
201 5cdb1798 2005-10-29 devnull {
202 5cdb1798 2005-10-29 devnull Pattern *p;
203 5cdb1798 2005-10-29 devnull Reprog *rp;
204 5cdb1798 2005-10-29 devnull String *s;
205 5cdb1798 2005-10-29 devnull
206 5cdb1798 2005-10-29 devnull s = s_copy(arg);
207 5cdb1798 2005-10-29 devnull mklower(s_to_c(s));
208 5cdb1798 2005-10-29 devnull
209 5cdb1798 2005-10-29 devnull for(p = patterns; p != nil; p = p->next)
210 5cdb1798 2005-10-29 devnull switch(p->type){
211 5cdb1798 2005-10-29 devnull case Texact:
212 5cdb1798 2005-10-29 devnull if(strcmp(p->arg, s_to_c(s)) == 0){
213 5cdb1798 2005-10-29 devnull free(s);
214 5cdb1798 2005-10-29 devnull return p;
215 5cdb1798 2005-10-29 devnull }
216 5cdb1798 2005-10-29 devnull break;
217 5cdb1798 2005-10-29 devnull case Tregexp:
218 5cdb1798 2005-10-29 devnull rp = regcomp(p->arg);
219 5cdb1798 2005-10-29 devnull if(rp == nil)
220 5cdb1798 2005-10-29 devnull continue;
221 5cdb1798 2005-10-29 devnull if(regexec(rp, s_to_c(s), nil, 0)){
222 5cdb1798 2005-10-29 devnull free(rp);
223 5cdb1798 2005-10-29 devnull free(s);
224 5cdb1798 2005-10-29 devnull return p;
225 5cdb1798 2005-10-29 devnull }
226 5cdb1798 2005-10-29 devnull free(rp);
227 5cdb1798 2005-10-29 devnull break;
228 5cdb1798 2005-10-29 devnull }
229 5cdb1798 2005-10-29 devnull s_free(s);
230 5cdb1798 2005-10-29 devnull return 0;
231 5cdb1798 2005-10-29 devnull }
232 5cdb1798 2005-10-29 devnull static char*
233 5cdb1798 2005-10-29 devnull check(int argc, char **argv)
234 5cdb1798 2005-10-29 devnull {
235 5cdb1798 2005-10-29 devnull int i;
236 5cdb1798 2005-10-29 devnull Addr *a;
237 5cdb1798 2005-10-29 devnull Pattern *p;
238 5cdb1798 2005-10-29 devnull int matchedbang;
239 5cdb1798 2005-10-29 devnull
240 5cdb1798 2005-10-29 devnull matchedbang = 0;
241 5cdb1798 2005-10-29 devnull for(i = 0; i < argc; i++){
242 5cdb1798 2005-10-29 devnull a = readaddrs(argv[i], nil);
243 5cdb1798 2005-10-29 devnull for(; a != nil; a = a->next){
244 5cdb1798 2005-10-29 devnull p = checkaddr(a->val);
245 5cdb1798 2005-10-29 devnull if(p == nil)
246 5cdb1798 2005-10-29 devnull continue;
247 5cdb1798 2005-10-29 devnull if(p->bang)
248 5cdb1798 2005-10-29 devnull matchedbang = 1;
249 5cdb1798 2005-10-29 devnull else
250 5cdb1798 2005-10-29 devnull return nil;
251 5cdb1798 2005-10-29 devnull }
252 5cdb1798 2005-10-29 devnull }
253 5cdb1798 2005-10-29 devnull if(matchedbang)
254 5cdb1798 2005-10-29 devnull return "!match";
255 5cdb1798 2005-10-29 devnull else
256 5cdb1798 2005-10-29 devnull return "no match";
257 5cdb1798 2005-10-29 devnull }
258 5cdb1798 2005-10-29 devnull
259 5cdb1798 2005-10-29 devnull /*
260 5cdb1798 2005-10-29 devnull * add anything that isn't already matched, all matches are lower case
261 5cdb1798 2005-10-29 devnull */
262 5cdb1798 2005-10-29 devnull static char*
263 5cdb1798 2005-10-29 devnull add(char *pp, int argc, char **argv)
264 5cdb1798 2005-10-29 devnull {
265 5cdb1798 2005-10-29 devnull int fd, i;
266 5cdb1798 2005-10-29 devnull String *s;
267 5cdb1798 2005-10-29 devnull char *cp;
268 5cdb1798 2005-10-29 devnull Addr *a;
269 5cdb1798 2005-10-29 devnull
270 5cdb1798 2005-10-29 devnull a = nil;
271 5cdb1798 2005-10-29 devnull for(i = 0; i < argc; i++)
272 5cdb1798 2005-10-29 devnull a = readaddrs(argv[i], a);
273 5cdb1798 2005-10-29 devnull
274 5cdb1798 2005-10-29 devnull fd = open(pp, OWRITE);
275 5cdb1798 2005-10-29 devnull seek(fd, 0, 2);
276 5cdb1798 2005-10-29 devnull for(; a != nil; a = a->next){
277 5cdb1798 2005-10-29 devnull if(checkaddr(a->val))
278 5cdb1798 2005-10-29 devnull continue;
279 5cdb1798 2005-10-29 devnull s = simplify(a->val);
280 5cdb1798 2005-10-29 devnull cp = s_to_c(s);
281 5cdb1798 2005-10-29 devnull fprint(fd, "%q\t%q\n", cp, a->val);
282 5cdb1798 2005-10-29 devnull if(*cp == '=')
283 5cdb1798 2005-10-29 devnull newpattern(Texact, cp+1, 0);
284 5cdb1798 2005-10-29 devnull else if(*cp == '~')
285 5cdb1798 2005-10-29 devnull newpattern(Tregexp, cp+1, 0);
286 5cdb1798 2005-10-29 devnull s_free(s);
287 5cdb1798 2005-10-29 devnull }
288 5cdb1798 2005-10-29 devnull close(fd);
289 fa325e9b 2020-01-10 cross return nil;
290 5cdb1798 2005-10-29 devnull }
291 5cdb1798 2005-10-29 devnull
292 5cdb1798 2005-10-29 devnull void
293 5cdb1798 2005-10-29 devnull main(int argc, char **argv)
294 5cdb1798 2005-10-29 devnull {
295 5cdb1798 2005-10-29 devnull char *patternpath;
296 5cdb1798 2005-10-29 devnull
297 5cdb1798 2005-10-29 devnull ARGBEGIN {
298 5cdb1798 2005-10-29 devnull case 'd':
299 5cdb1798 2005-10-29 devnull debug++;
300 5cdb1798 2005-10-29 devnull break;
301 5cdb1798 2005-10-29 devnull } ARGEND;
302 5cdb1798 2005-10-29 devnull
303 5cdb1798 2005-10-29 devnull quotefmtinstall();
304 5cdb1798 2005-10-29 devnull
305 5cdb1798 2005-10-29 devnull if(argc < 3)
306 5cdb1798 2005-10-29 devnull usage();
307 5cdb1798 2005-10-29 devnull
308 5cdb1798 2005-10-29 devnull patternpath = argv[1];
309 5cdb1798 2005-10-29 devnull readpatterns(patternpath);
310 5cdb1798 2005-10-29 devnull if(strcmp(argv[0], "add") == 0)
311 5cdb1798 2005-10-29 devnull exits(add(patternpath, argc-2, argv+2));
312 5cdb1798 2005-10-29 devnull else if(strcmp(argv[0], "check") == 0)
313 5cdb1798 2005-10-29 devnull exits(check(argc-2, argv+2));
314 5cdb1798 2005-10-29 devnull else
315 5cdb1798 2005-10-29 devnull usage();
316 5cdb1798 2005-10-29 devnull }