Changeset cb769bb for filterelement.c


Ignore:
Timestamp:
Dec 26, 2006, 1:05:26 AM (14 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, barnowl_perlaim, debian, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
446aa2b
Parents:
20eb22c
Message:
 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
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • filterelement.c

    r32eed98 rcb769bb  
    33static const char fileIdent[] = "$Id$";
    44
    5 #define OWL_FILTERELEMENT_NULL        0
    6 #define OWL_FILTERELEMENT_TRUE        1
    7 #define OWL_FILTERELEMENT_FALSE       2
    8 #define OWL_FILTERELEMENT_OPENBRACE   3
    9 #define OWL_FILTERELEMENT_CLOSEBRACE  4
    10 #define OWL_FILTERELEMENT_AND         5
    11 #define OWL_FILTERELEMENT_OR          6
    12 #define OWL_FILTERELEMENT_NOT         7
    13 #define OWL_FILTERELEMENT_RE          8
    14 #define OWL_FILTERELEMENT_FILTER      9
    15 #define OWL_FILTERELEMENT_PERL       10
    16 
    17 void owl_filterelement_create_null(owl_filterelement *fe)
    18 {
    19   fe->type=OWL_FILTERELEMENT_NULL;
    20   fe->field=NULL;
    21   fe->filtername=NULL;
    22 }
    23 
    24 void owl_filterelement_create_openbrace(owl_filterelement *fe)
    25 {
    26   owl_filterelement_create_null(fe);
    27   fe->type=OWL_FILTERELEMENT_OPENBRACE;
    28 }
    29 
    30 void owl_filterelement_create_closebrace(owl_filterelement *fe)
    31 {
    32   owl_filterelement_create_null(fe);
    33   fe->type=OWL_FILTERELEMENT_CLOSEBRACE;
    34 }
    35 
    36 void owl_filterelement_create_and(owl_filterelement *fe)
    37 {
    38   owl_filterelement_create_null(fe);
    39   fe->type=OWL_FILTERELEMENT_AND;
    40 }
    41 
    42 void owl_filterelement_create_or(owl_filterelement *fe)
    43 {
    44   owl_filterelement_create_null(fe);
    45   fe->type=OWL_FILTERELEMENT_OR;
    46 }
    47 
    48 void owl_filterelement_create_not(owl_filterelement *fe)
    49 {
    50   owl_filterelement_create_null(fe);
    51   fe->type=OWL_FILTERELEMENT_NOT;
    52 }
     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
    53194
    54195void owl_filterelement_create_true(owl_filterelement *fe)
    55196{
    56   owl_filterelement_create_null(fe);
    57   fe->type=OWL_FILTERELEMENT_TRUE;
     197  owl_filterelement_create(fe);
     198  fe->match_message = owl_filterelement_match_true;
     199  fe->print_elt = owl_filterelement_print_true;
    58200}
    59201
    60202void owl_filterelement_create_false(owl_filterelement *fe)
    61203{
    62   owl_filterelement_create_null(fe);
    63   fe->type=OWL_FILTERELEMENT_FALSE;
     204  owl_filterelement_create(fe);
     205  fe->match_message = owl_filterelement_match_false;
     206  fe->print_elt = owl_filterelement_print_false;
    64207}
    65208
    66209void owl_filterelement_create_re(owl_filterelement *fe, char *field, char *re)
    67210{
    68   owl_filterelement_create_null(fe);
    69   fe->type=OWL_FILTERELEMENT_RE;
     211  owl_filterelement_create(fe);
    70212  fe->field=owl_strdup(field);
    71213  owl_regex_create(&(fe->re), re);
     214  fe->match_message = owl_filterelement_match_re;
     215  fe->print_elt = owl_filterelement_print_re;
    72216}
    73217
    74218void owl_filterelement_create_filter(owl_filterelement *fe, char *name)
    75219{
    76   owl_filterelement_create_null(fe);
    77   fe->type=OWL_FILTERELEMENT_FILTER;
    78   fe->filtername=owl_strdup(name);
     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;
    79224}
    80225
    81226void owl_filterelement_create_perl(owl_filterelement *fe, char *name)
    82227{
    83   owl_filterelement_create_null(fe);
    84   fe->type=OWL_FILTERELEMENT_PERL;
    85   fe->filtername=owl_strdup(name);
     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;
    86301}
    87302
     
    89304{
    90305  if (fe->field) owl_free(fe->field);
    91   if (fe->filtername) owl_free(fe->filtername);
    92 }
    93 
    94 int owl_filterelement_is_null(owl_filterelement *fe)
    95 {
    96   if (fe->type==OWL_FILTERELEMENT_NULL) return(1);
    97   return(0);
    98 }
    99 
    100 int owl_filterelement_is_openbrace(owl_filterelement *fe)
    101 {
    102   if (fe->type==OWL_FILTERELEMENT_OPENBRACE) return(1);
    103   return(0);
    104 }
    105 
    106 int owl_filterelement_is_closebrace(owl_filterelement *fe)
    107 {
    108   if (fe->type==OWL_FILTERELEMENT_CLOSEBRACE) return(1);
    109   return(0);
    110 }
    111 
    112 int owl_filterelement_is_and(owl_filterelement *fe)
    113 {
    114   if (fe->type==OWL_FILTERELEMENT_AND) return(1);
    115   return(0);
    116 }
    117 
    118 int owl_filterelement_is_or(owl_filterelement *fe)
    119 {
    120   if (fe->type==OWL_FILTERELEMENT_OR) return(1);
    121   return(0);
    122 }
    123 
    124 int owl_filterelement_is_not(owl_filterelement *fe)
    125 {
    126   if (fe->type==OWL_FILTERELEMENT_NOT) return(1);
    127   return(0);
    128 }
    129 
    130 int owl_filterelement_is_true(owl_filterelement *fe)
    131 {
    132   if (fe->type==OWL_FILTERELEMENT_TRUE) return(1);
    133   return(0);
    134 }
    135 
    136 int owl_filterelement_is_false(owl_filterelement *fe)
    137 {
    138   if (fe->type==OWL_FILTERELEMENT_FALSE) return(1);
    139   return(0);
    140 }
    141 
    142 int owl_filterelement_is_re(owl_filterelement *fe)
    143 {
    144   if (fe->type==OWL_FILTERELEMENT_RE) return(1);
    145   return(0);
    146 }
    147 
    148 int owl_filterelement_is_perl(owl_filterelement *fe)
    149 {
    150   if (fe->type==OWL_FILTERELEMENT_PERL) return(1);
    151   return(0);
    152 }
    153 
    154 owl_regex *owl_filterelement_get_re(owl_filterelement *fe)
    155 {
    156   return(&(fe->re));
    157 }
    158 
    159 int owl_filterelement_is_filter(owl_filterelement *fe)
    160 {
    161   if (fe->type==OWL_FILTERELEMENT_FILTER) return(1);
    162   return(0);
    163 }
    164 
    165 char *owl_filterelement_get_field(owl_filterelement *fe)
    166 {
    167   if (fe->field) return(fe->field);
    168   return("unknown-field");
    169 }
    170 
    171 char *owl_filterelement_get_filtername(owl_filterelement *fe)
    172 {
    173   if (fe->filtername) return(fe->filtername);
    174   return("unknown-filter");
    175 }
    176 
    177 int owl_filterelement_is_value(owl_filterelement *fe)
    178 {
    179   if ( (fe->type==OWL_FILTERELEMENT_TRUE) ||
    180        (fe->type==OWL_FILTERELEMENT_FALSE) ||
    181        (fe->type==OWL_FILTERELEMENT_RE) ||
    182        (fe->type==OWL_FILTERELEMENT_PERL) ||
    183        (fe->type==OWL_FILTERELEMENT_FILTER)) {
    184     return(1);
    185   }
    186   return(0);
    187 }
    188 
    189 /* caller must free the return */
    190 char *owl_filterelement_to_string(owl_filterelement *fe)
    191 {
    192   if (owl_filterelement_is_openbrace(fe)) {
    193     return(owl_strdup("( "));
    194   } else if (owl_filterelement_is_closebrace(fe)) {
    195     return(owl_strdup(") "));
    196   } else if (owl_filterelement_is_and(fe)) {
    197     return(owl_strdup("and "));
    198   } else if (owl_filterelement_is_or(fe)) {
    199     return(owl_strdup("or "));
    200   } else if (owl_filterelement_is_not(fe)) {
    201     return(owl_strdup("not "));
    202   } else if (owl_filterelement_is_true(fe)) {
    203     return(owl_strdup("true "));
    204   } else if (owl_filterelement_is_false(fe)) {
    205     return(owl_strdup("false "));
    206   } else if (owl_filterelement_is_re(fe)) {
    207     return(owl_sprintf("%s %s ", fe->field, owl_regex_get_string(&(fe->re))));
    208   } else if (owl_filterelement_is_filter(fe)) {
    209     return(owl_sprintf("filter %s ", fe->filtername));
    210   } else if (owl_filterelement_is_perl(fe)) {
    211     return(owl_sprintf("perl %s ", fe->filtername));
    212   }
    213 
    214   return(owl_strdup("?"));
    215 }
     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 TracChangeset for help on using the changeset viewer.