source: filterelement.c @ cd5adec

barnowl_perlaimdebianrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since cd5adec was cd5adec, checked in by Nelson Elhage <nelhage@mit.edu>, 17 years ago
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.
  • Property mode set to 100644
File size: 8.4 KB
RevLine 
[7d4fbcd]1#include "owl.h"
2
[1aee7d9]3static const char fileIdent[] = "$Id$";
4
[cb769bb]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}
[7d4fbcd]51
[cb769bb]52static int owl_filterelement_match_false(owl_filterelement *fe, owl_message *m)
[e187445]53{
[cb769bb]54  return 0;
[7d4fbcd]55}
56
[cb769bb]57static int owl_filterelement_match_true(owl_filterelement *fe, owl_message *m)
[e187445]58{
[cb769bb]59  return 1;
[7d4fbcd]60}
61
[cb769bb]62static int owl_filterelement_match_re(owl_filterelement *fe, owl_message *m)
[e187445]63{
[cb769bb]64  char * val = owl_filterelement_get_field(m, fe->field);
65  return !owl_regex_compare(&(fe->re), val);
[7d4fbcd]66}
67
[cb769bb]68static int owl_filterelement_match_filter(owl_filterelement *fe, owl_message *m)
[e187445]69{
[cb769bb]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);
[7d4fbcd]79}
80
[cb769bb]81static int owl_filterelement_match_perl(owl_filterelement *fe, owl_message *m)
[e187445]82{
[cb769bb]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;
[7d4fbcd]98}
99
[cb769bb]100static int owl_filterelement_match_group(owl_filterelement *fe, owl_message *m)
[e187445]101{
[cb769bb]102  return owl_filterelement_match(fe->left, m);
[7d4fbcd]103}
104
[cb769bb]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)
[e187445]110{
[cb769bb]111  return owl_filterelement_match(fe->left, m) &&
112    owl_filterelement_match(fe->right, m);
[7d4fbcd]113}
114
[cb769bb]115static int owl_filterelement_match_or(owl_filterelement *fe, owl_message *m)
[e187445]116{
[cb769bb]117  return owl_filterelement_match(fe->left, m) ||
118    owl_filterelement_match(fe->right, m);
[7d4fbcd]119}
120
[cb769bb]121static int owl_filterelement_match_not(owl_filterelement *fe, owl_message *m)
[e187445]122{
[cb769bb]123  return !owl_filterelement_match(fe->left, m);
[cd5adec]124  fe->match_message = owl_filterelement_match_re;
125  fe->print_elt = owl_filterelement_print_re;
[7d4fbcd]126}
[cd5adec]127/*
[cb769bb]128// Print methods
129
130static void owl_filterelement_print_true(owl_filterelement *fe, char *buf)
[40458b9]131{
[cb769bb]132  strcat(buf, "true");
[40458b9]133}
134
[cb769bb]135static void owl_filterelement_print_false(owl_filterelement *fe, char *buf)
[32eed98]136{
[cb769bb]137  strcat(buf, "false");
[32eed98]138}
[cd5adec]139*/
[32eed98]140
[cb769bb]141static void owl_filterelement_print_re(owl_filterelement *fe, char *buf)
[e187445]142{
[cb769bb]143  strcat(buf, fe->field);
144  strcat(buf, " ");
145  strcat(buf, owl_regex_get_string(&(fe->re)));
146}
147
148static void owl_filterelement_print_filter(owl_filterelement *fe, char *buf)
149{
150  strcat(buf, "filter ");
151  strcat(buf, fe->field);
152}
153
154static void owl_filterelement_print_perl(owl_filterelement *fe, char *buf)
155{
156  strcat(buf, "perl ");
157  strcat(buf, fe->field);
[7d4fbcd]158}
159
[cb769bb]160static void owl_filterelement_print_group(owl_filterelement *fe, char *buf)
[e187445]161{
[cb769bb]162  strcat(buf, "( ");
163  owl_filterelement_print(fe->left, buf) ;
164  strcat(buf, " )");
[7d4fbcd]165}
166
[cb769bb]167static void owl_filterelement_print_or(owl_filterelement *fe, char *buf)
[e187445]168{
[cb769bb]169  owl_filterelement_print(fe->left, buf);
170  strcat(buf, " or ");
171  owl_filterelement_print(fe->right, buf);
[7d4fbcd]172}
173
[cb769bb]174static void owl_filterelement_print_and(owl_filterelement *fe, char *buf)
[e187445]175{
[cb769bb]176  owl_filterelement_print(fe->left, buf);
177  strcat(buf, " and ");
178  owl_filterelement_print(fe->right, buf);
[7d4fbcd]179}
180
[cb769bb]181static void owl_filterelement_print_not(owl_filterelement *fe, char *buf)
[e187445]182{
[cb769bb]183  strcat(buf, " not ");
184  owl_filterelement_print(fe->left, buf);
185}
186
187// Constructors
188
189void owl_filterelement_create(owl_filterelement *fe) {
190  fe->field = NULL;
191  fe->left = fe->right = NULL;
192  fe->match_message = NULL;
193  fe->print_elt = NULL;
194  owl_regex_init(&(fe->re));
[7d4fbcd]195}
196
[cb769bb]197
198void owl_filterelement_create_true(owl_filterelement *fe)
199{
200  owl_filterelement_create(fe);
201  fe->match_message = owl_filterelement_match_true;
202  fe->print_elt = owl_filterelement_print_true;
203}
204
205void owl_filterelement_create_false(owl_filterelement *fe)
[e187445]206{
[cb769bb]207  owl_filterelement_create(fe);
208  fe->match_message = owl_filterelement_match_false;
209  fe->print_elt = owl_filterelement_print_false;
[7d4fbcd]210}
211
[cb769bb]212void owl_filterelement_create_re(owl_filterelement *fe, char *field, char *re)
[e187445]213{
[cb769bb]214  owl_filterelement_create(fe);
215  fe->field=owl_strdup(field);
216  owl_regex_create(&(fe->re), re);
217  fe->match_message = owl_filterelement_match_re;
218  fe->print_elt = owl_filterelement_print_re;
[7d4fbcd]219}
220
[cb769bb]221void owl_filterelement_create_filter(owl_filterelement *fe, char *name)
[e187445]222{
[cb769bb]223  owl_filterelement_create(fe);
224  fe->field=owl_strdup(name);
225  fe->match_message = owl_filterelement_match_filter;
226  fe->print_elt = owl_filterelement_print_filter;
[7d4fbcd]227}
228
[cb769bb]229void owl_filterelement_create_perl(owl_filterelement *fe, char *name)
[e187445]230{
[cb769bb]231  owl_filterelement_create(fe);
232  fe->field=owl_strdup(name);
233  fe->match_message = owl_filterelement_match_perl;
234  fe->print_elt = owl_filterelement_print_perl;
[7d4fbcd]235}
236
[cb769bb]237void owl_filterelement_create_group(owl_filterelement *fe, owl_filterelement *in)
[e187445]238{
[cb769bb]239  owl_filterelement_create(fe);
240  fe->left = in;
241  fe->match_message = owl_filterelement_match_group;
242  fe->print_elt = owl_filterelement_print_group;
[7d4fbcd]243}
244
[cb769bb]245void owl_filterelement_create_not(owl_filterelement *fe, owl_filterelement *in)
[32eed98]246{
[cb769bb]247  owl_filterelement_create(fe);
248  fe->left = in;
249  fe->match_message = owl_filterelement_match_not;
250  fe->print_elt = owl_filterelement_print_not;
[32eed98]251}
252
[cb769bb]253void owl_filterelement_create_and(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
[e187445]254{
[cb769bb]255  owl_filterelement_create(fe);
256  fe->left = lhs;
257  fe->right = rhs;
258  fe->match_message = owl_filterelement_match_and;
259  fe->print_elt = owl_filterelement_print_and;
[7d4fbcd]260}
261
[cb769bb]262void owl_filterelement_create_or(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
[40458b9]263{
[cb769bb]264  owl_filterelement_create(fe);
265  fe->left = lhs;
266  fe->right = rhs;
267  fe->match_message = owl_filterelement_match_or;
268  fe->print_elt = owl_filterelement_print_or;
[40458b9]269}
270
[cb769bb]271int owl_filterelement_match(owl_filterelement *fe, owl_message *m)
[e187445]272{
[cb769bb]273  if(!fe) return 0;
274  if(!fe->match_message) return 0;
275  return fe->match_message(fe, m);
[40458b9]276}
277
[cb769bb]278int owl_filterelement_is_toodeep(owl_filter *f, owl_filterelement *fe)
[40458b9]279{
[cb769bb]280  int one = 1;
281  owl_list nodes;
282  owl_dict filters;
283  owl_list_create(&nodes);
284  owl_dict_create(&filters);
285 
286  owl_list_append_element(&nodes, fe);
287  owl_dict_insert_element(&filters, f->name, &one, NULL);
288  while(owl_list_get_size(&nodes)) {
289    fe = owl_list_get_element(&nodes, 0);
290    owl_list_remove_element(&nodes, 0);
291    if(fe->left) owl_list_append_element(&nodes, fe->left);
292    if(fe->right) owl_list_append_element(&nodes, fe->right);
293    if(fe->match_message == owl_filterelement_match_filter) {
294      if(owl_dict_find_element(&filters, fe->field)) return 1;
295      owl_dict_insert_element(&filters, fe->field, &one, NULL);
296      f = owl_global_get_filter(&g, fe->field);
297      if(f) owl_list_append_element(&nodes, f->root);
298    }
299  }
300
301  owl_list_free_simple(&nodes);
302  owl_dict_free_simple(&filters);
303  return 0;
[7d4fbcd]304}
305
[cb769bb]306void owl_filterelement_free(owl_filterelement *fe)
[e187445]307{
[cb769bb]308  if (fe->field) owl_free(fe->field);
309  if (fe->left) {
310    owl_filterelement_free(fe->left);
311    owl_free(fe->left);
[7d4fbcd]312  }
[cb769bb]313  if (fe->right) {
314    owl_filterelement_free(fe->right);
315    owl_free(fe->right);
[7d4fbcd]316  }
[cb769bb]317  owl_regex_free(&(fe->re));
318}
[40458b9]319
[cb769bb]320void owl_filterelement_print(owl_filterelement *fe, char *buf)
321{
322  if(!fe || !fe->print_elt) return;
323  fe->print_elt(fe, buf);
[7d4fbcd]324}
Note: See TracBrowser for help on using the repository browser.