source: filterelement.c @ f3c1aba

barnowl_perlaimdebianrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since f3c1aba was cb769bb, checked in by Nelson Elhage <nelhage@mit.edu>, 18 years ago
r15874@phanatique: nelhage | 2006-12-24 18:25:33 -0500 Don't quit if we can't contact the hostmaster. r15884@phanatique: nelhage | 2006-12-24 18:56:03 -0500 Respect the displayoutgoing variable r15885@phanatique: nelhage | 2006-12-24 20:10:44 -0500 You can now write filters based off arbitrary message attributes r15887@phanatique: nelhage | 2006-12-24 22:59:39 -0500 r15886@phanatique (orig r476): nelhage | 2006-12-24 22:59:10 -0500 r24493@heretique: nelhage | 2006-12-24 22:59:02 -0500 Moving zephyr initialization later, so that zephyr works again r15891@phanatique: nelhage | 2006-12-25 14:40:08 -0500 * perl messages hashes use `private', not `isprivate' * get rid of a perl warning if login fails r15900@phanatique: nelhage | 2006-12-25 21:04:15 -0500 Merging in filter regression tests from my local branch. r15926@phanatique: nelhage | 2006-12-26 00:57:07 -0500 r15901@phanatique: nelhage | 2006-12-25 21:08:47 -0500 Base framework for the filter rewrite system. Only understands regexes and true/false so far. r15927@phanatique: nelhage | 2006-12-26 00:57:08 -0500 r15902@phanatique: nelhage | 2006-12-25 23:03:33 -0500 support for negation and parentheses r15928@phanatique: nelhage | 2006-12-26 00:57:08 -0500 r15924@phanatique: nelhage | 2006-12-26 00:16:30 -0500 Now passing all tests except for recursion detection r15929@phanatique: nelhage | 2006-12-26 00:57:08 -0500 r15925@phanatique: nelhage | 2006-12-26 00:52:09 -0500 Checking for filter recursion loops
  • Property mode set to 100644
File size: 8.3 KB
Line 
1#include "owl.h"
2
3static const char fileIdent[] = "$Id$";
4
5static char * owl_filterelement_get_field(owl_message *m, char * field)
6{
7  char *match;
8  if (!strcasecmp(field, "class")) {
9    match=owl_message_get_class(m);
10  } else if (!strcasecmp(field, "instance")) {
11    match=owl_message_get_instance(m);
12  } else if (!strcasecmp(field, "sender")) {
13    match=owl_message_get_sender(m);
14  } else if (!strcasecmp(field, "recipient")) {
15    match=owl_message_get_recipient(m);
16  } else if (!strcasecmp(field, "body")) {
17    match=owl_message_get_body(m);
18  } else if (!strcasecmp(field, "opcode")) {
19    match=owl_message_get_opcode(m);
20  } else if (!strcasecmp(field, "realm")) {
21    match=owl_message_get_realm(m);
22  } else if (!strcasecmp(field, "type")) {
23    match=owl_message_get_type(m);
24  } else if (!strcasecmp(field, "hostname")) {
25    match=owl_message_get_hostname(m);
26  } else if (!strcasecmp(field, "direction")) {
27    if (owl_message_is_direction_out(m)) {
28      match="out";
29    } else if (owl_message_is_direction_in(m)) {
30      match="in";
31    } else if (owl_message_is_direction_none(m)) {
32      match="none";
33    } else {
34      match="";
35    }
36  } else if (!strcasecmp(field, "login")) {
37    if (owl_message_is_login(m)) {
38      match="login";
39    } else if (owl_message_is_logout(m)) {
40      match="logout";
41    } else {
42      match="none";
43    }
44  } else {
45    match = owl_message_get_attribute_value(m,field);
46    if(match == NULL) match = "";
47  }
48
49  return match;
50}
51
52static int owl_filterelement_match_false(owl_filterelement *fe, owl_message *m)
53{
54  return 0;
55}
56
57static int owl_filterelement_match_true(owl_filterelement *fe, owl_message *m)
58{
59  return 1;
60}
61
62static int owl_filterelement_match_re(owl_filterelement *fe, owl_message *m)
63{
64  char * val = owl_filterelement_get_field(m, fe->field);
65  return !owl_regex_compare(&(fe->re), val);
66}
67
68static int owl_filterelement_match_filter(owl_filterelement *fe, owl_message *m)
69{
70  owl_filter *subfilter;
71  subfilter=owl_global_get_filter(&g, fe->field);
72  if (!subfilter) {
73    /* the filter does not exist, maybe because it was deleted.
74     * Default to not matching
75     */
76    return 0;
77  } 
78  return owl_filter_message_match(subfilter, m);
79}
80
81static int owl_filterelement_match_perl(owl_filterelement *fe, owl_message *m)
82{
83  char *subname, *perlrv;
84  int   tf=0;
85
86  subname = fe->field;
87  if (!owl_perlconfig_is_function(subname)) {
88    return 0;
89  }
90  perlrv = owl_perlconfig_call_with_message(subname, m);
91  if (perlrv) {
92    if (0 == strcmp(perlrv, "1")) {
93      tf=1;
94    }
95    owl_free(perlrv);
96  }
97  return tf;
98}
99
100static int owl_filterelement_match_group(owl_filterelement *fe, owl_message *m)
101{
102  return owl_filterelement_match(fe->left, m);
103}
104
105/* XXX: Our boolea operators short-circuit here. The original owl did
106   not. Do we care?
107*/
108
109static int owl_filterelement_match_and(owl_filterelement *fe, owl_message *m)
110{
111  return owl_filterelement_match(fe->left, m) &&
112    owl_filterelement_match(fe->right, m);
113}
114
115static int owl_filterelement_match_or(owl_filterelement *fe, owl_message *m)
116{
117  return owl_filterelement_match(fe->left, m) ||
118    owl_filterelement_match(fe->right, m);
119}
120
121static int owl_filterelement_match_not(owl_filterelement *fe, owl_message *m)
122{
123  return !owl_filterelement_match(fe->left, m);
124}
125
126// Print methods
127
128static void owl_filterelement_print_true(owl_filterelement *fe, char *buf)
129{
130  strcat(buf, "true");
131}
132
133static void owl_filterelement_print_false(owl_filterelement *fe, char *buf)
134{
135  strcat(buf, "false");
136}
137
138static void owl_filterelement_print_re(owl_filterelement *fe, char *buf)
139{
140  strcat(buf, fe->field);
141  strcat(buf, " ");
142  strcat(buf, owl_regex_get_string(&(fe->re)));
143}
144
145static void owl_filterelement_print_filter(owl_filterelement *fe, char *buf)
146{
147  strcat(buf, "filter ");
148  strcat(buf, fe->field);
149}
150
151static void owl_filterelement_print_perl(owl_filterelement *fe, char *buf)
152{
153  strcat(buf, "perl ");
154  strcat(buf, fe->field);
155}
156
157static void owl_filterelement_print_group(owl_filterelement *fe, char *buf)
158{
159  strcat(buf, "( ");
160  owl_filterelement_print(fe->left, buf) ;
161  strcat(buf, " )");
162}
163
164static void owl_filterelement_print_or(owl_filterelement *fe, char *buf)
165{
166  owl_filterelement_print(fe->left, buf);
167  strcat(buf, " or ");
168  owl_filterelement_print(fe->right, buf);
169}
170
171static void owl_filterelement_print_and(owl_filterelement *fe, char *buf)
172{
173  owl_filterelement_print(fe->left, buf);
174  strcat(buf, " and ");
175  owl_filterelement_print(fe->right, buf);
176}
177
178static void owl_filterelement_print_not(owl_filterelement *fe, char *buf)
179{
180  strcat(buf, " not ");
181  owl_filterelement_print(fe->left, buf);
182}
183
184// Constructors
185
186void owl_filterelement_create(owl_filterelement *fe) {
187  fe->field = NULL;
188  fe->left = fe->right = NULL;
189  fe->match_message = NULL;
190  fe->print_elt = NULL;
191  owl_regex_init(&(fe->re));
192}
193
194
195void owl_filterelement_create_true(owl_filterelement *fe)
196{
197  owl_filterelement_create(fe);
198  fe->match_message = owl_filterelement_match_true;
199  fe->print_elt = owl_filterelement_print_true;
200}
201
202void owl_filterelement_create_false(owl_filterelement *fe)
203{
204  owl_filterelement_create(fe);
205  fe->match_message = owl_filterelement_match_false;
206  fe->print_elt = owl_filterelement_print_false;
207}
208
209void owl_filterelement_create_re(owl_filterelement *fe, char *field, char *re)
210{
211  owl_filterelement_create(fe);
212  fe->field=owl_strdup(field);
213  owl_regex_create(&(fe->re), re);
214  fe->match_message = owl_filterelement_match_re;
215  fe->print_elt = owl_filterelement_print_re;
216}
217
218void owl_filterelement_create_filter(owl_filterelement *fe, char *name)
219{
220  owl_filterelement_create(fe);
221  fe->field=owl_strdup(name);
222  fe->match_message = owl_filterelement_match_filter;
223  fe->print_elt = owl_filterelement_print_filter;
224}
225
226void owl_filterelement_create_perl(owl_filterelement *fe, char *name)
227{
228  owl_filterelement_create(fe);
229  fe->field=owl_strdup(name);
230  fe->match_message = owl_filterelement_match_perl;
231  fe->print_elt = owl_filterelement_print_perl;
232}
233
234void owl_filterelement_create_group(owl_filterelement *fe, owl_filterelement *in)
235{
236  owl_filterelement_create(fe);
237  fe->left = in;
238  fe->match_message = owl_filterelement_match_group;
239  fe->print_elt = owl_filterelement_print_group;
240}
241
242void owl_filterelement_create_not(owl_filterelement *fe, owl_filterelement *in)
243{
244  owl_filterelement_create(fe);
245  fe->left = in;
246  fe->match_message = owl_filterelement_match_not;
247  fe->print_elt = owl_filterelement_print_not;
248}
249
250void owl_filterelement_create_and(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
251{
252  owl_filterelement_create(fe);
253  fe->left = lhs;
254  fe->right = rhs;
255  fe->match_message = owl_filterelement_match_and;
256  fe->print_elt = owl_filterelement_print_and;
257}
258
259void owl_filterelement_create_or(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
260{
261  owl_filterelement_create(fe);
262  fe->left = lhs;
263  fe->right = rhs;
264  fe->match_message = owl_filterelement_match_or;
265  fe->print_elt = owl_filterelement_print_or;
266}
267
268int owl_filterelement_match(owl_filterelement *fe, owl_message *m)
269{
270  if(!fe) return 0;
271  if(!fe->match_message) return 0;
272  return fe->match_message(fe, m);
273}
274
275int owl_filterelement_is_toodeep(owl_filter *f, owl_filterelement *fe)
276{
277  int one = 1;
278  owl_list nodes;
279  owl_dict filters;
280  owl_list_create(&nodes);
281  owl_dict_create(&filters);
282 
283  owl_list_append_element(&nodes, fe);
284  owl_dict_insert_element(&filters, f->name, &one, NULL);
285  while(owl_list_get_size(&nodes)) {
286    fe = owl_list_get_element(&nodes, 0);
287    owl_list_remove_element(&nodes, 0);
288    if(fe->left) owl_list_append_element(&nodes, fe->left);
289    if(fe->right) owl_list_append_element(&nodes, fe->right);
290    if(fe->match_message == owl_filterelement_match_filter) {
291      if(owl_dict_find_element(&filters, fe->field)) return 1;
292      owl_dict_insert_element(&filters, fe->field, &one, NULL);
293      f = owl_global_get_filter(&g, fe->field);
294      if(f) owl_list_append_element(&nodes, f->root);
295    }
296  }
297
298  owl_list_free_simple(&nodes);
299  owl_dict_free_simple(&filters);
300  return 0;
301}
302
303void owl_filterelement_free(owl_filterelement *fe)
304{
305  if (fe->field) owl_free(fe->field);
306  if (fe->left) {
307    owl_filterelement_free(fe->left);
308    owl_free(fe->left);
309  }
310  if (fe->right) {
311    owl_filterelement_free(fe->right);
312    owl_free(fe->right);
313  }
314  owl_regex_free(&(fe->re));
315}
316
317void owl_filterelement_print(owl_filterelement *fe, char *buf)
318{
319  if(!fe || !fe->print_elt) return;
320  fe->print_elt(fe, buf);
321}
Note: See TracBrowser for help on using the repository browser.