Changeset 40458b9 for filter.c


Ignore:
Timestamp:
Dec 24, 2003, 7:35:21 PM (17 years ago)
Author:
James M. Kretchmar <kretch@mit.edu>
Branches:
master, barnowl_perlaim, debian, owl, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
5c1393d
Parents:
dad943e
Message:
Filters of filters now work
File:
1 edited

Legend:

Unmodified
Added
Removed
  • filter.c

    r12c35df r40458b9  
    33
    44static const char fileIdent[] = "$Id$";
     5
     6#define OWL_FILTER_MAXRECURSE 20
     7
     8int filter_depth;
    59
    610int owl_filter_init_fromstring(owl_filter *f, char *name, char *string)
     
    1721int owl_filter_init(owl_filter *f, char *name, int argc, char **argv)
    1822{
    19   int i, error;
     23  int i, j, error;
    2024  owl_filterelement *fe;
    2125  char *regexstr;
     26  owl_list list;
    2227   
    2328  f->name=owl_strdup(name);
     
    6065      owl_filterelement_create_false(fe);
    6166     
    62     } else if (i==argc-1) {
     67    } else if (i==argc-1) { /* we need more than one arg at this point */
    6368      error=1;
    6469    } else {
     
    7883        owl_free(regexstr);
    7984        i++;
     85      } else if (!strcasecmp(argv[i], "filter")) {
     86        owl_filterelement_create_filter(fe, argv[i+1]);
     87        i++;
    8088      } else {
    8189        error=1;
     
    9098      return(-1);
    9199    }
    92 
    93   }
     100  }
     101 
     102  /* Are we trying to use the filter we're creating?  Bad. */
     103  owl_list_create(&list);
     104  _owl_filter_get_subfilter_names(f, &list);
     105  j=owl_list_get_size(&list);
     106  for (i=0; i<j; i++) {
     107    if (!strcasecmp(name, owl_list_get_element(&list, i))) {
     108      owl_function_error("Filter loop.");
     109      owl_filter_free(f);
     110      owl_list_free_all(&list, owl_free);
     111      return(-1);
     112    }
     113  }
     114  owl_list_free_all(&list, owl_free);
     115
     116  /* Now check for more subtle recursion. */
     117  if (owl_filter_is_toodeep(f)) {
     118    owl_function_error("Filter loop or exceeds recursion depth");
     119    owl_filter_free(f);
     120    return(-1);
     121  }
     122 
    94123  return(0);
    95124}
     
    188217      }
    189218    }
    190    
     219
    191220    tmp=owl_regex_compare(owl_filterelement_get_re(fe), match);
    192221    if (!tmp) {
     222      owl_list_replace_element(&work_fes, i, owl_global_get_filterelement_true(&g));
     223    } else {
     224      owl_list_replace_element(&work_fes, i, owl_global_get_filterelement_false(&g));
     225    }
     226  }
     227
     228  /* now subfilters */
     229  for (i=0; i<j; i++) {
     230    owl_filter *subfilter;
     231                           
     232    fe=owl_list_get_element(&work_fes, i);
     233    if (!owl_filterelement_is_filter(fe)) continue;
     234
     235    subfilter=owl_global_get_filter(&g, owl_filterelement_get_filtername(fe));
     236    if (!subfilter) {
     237      /* the filter does not exist, maybe because it was deleted.
     238       * Default to not matching
     239       */
     240      owl_list_replace_element(&work_fes, i, owl_global_get_filterelement_false(&g));
     241    } else if (owl_filter_message_match(subfilter, m)) {
    193242      owl_list_replace_element(&work_fes, i, owl_global_get_filterelement_true(&g));
    194243    } else {
     
    400449}
    401450
     451/* Return 1 if the filters 'a' and 'b' are equivalent, 0 otherwise */
    402452int owl_filter_equiv(owl_filter *a, owl_filter *b)
    403453{
     
    408458
    409459  if (!strcmp(buff, buff2)) return(1);
     460  return(0);
     461}
     462
     463/* Private
     464 * 'list' should already be allocated and initialized
     465 * This function places into list the string names of all filters
     466 * used in the filter expression for 'f'.
     467 * Caller must do a full free on 'list', including elements.
     468 */
     469void _owl_filter_get_subfilter_names(owl_filter *f, owl_list *list)
     470{
     471  int i, j;
     472  owl_filterelement *fe;
     473
     474  j=owl_list_get_size(&(f->fes));
     475  for (i=0; i<j; i++) {
     476    fe=owl_list_get_element(&(f->fes), i);
     477    if (owl_filterelement_is_filter(fe)) {
     478      owl_list_append_element(list, owl_strdup(owl_filterelement_get_filtername(fe)));
     479    }
     480  }
     481}
     482
     483int owl_filter_is_toodeep(owl_filter *f)
     484{
     485  owl_list seen, tocheck, tmp;
     486  int i, j, x, y;
     487  owl_filter *subfilter;
     488
     489  owl_list_create(&seen);
     490  owl_list_create(&tocheck);
     491  owl_list_create(&tmp);
     492
     493  /* seed 'tocheck' with the first set of filters */
     494  _owl_filter_get_subfilter_names(f, &tmp);
     495  j=owl_list_get_size(&tmp);
     496  for (i=0; i<j; i++) {
     497    owl_util_list_add_unique_string(&tocheck, owl_list_get_element(&tmp, i));
     498  }
     499  owl_list_free_all(&tmp, owl_free);
     500  owl_list_create(&tmp);
     501
     502  /* add this list to the 'seen' list */
     503  owl_list_append_element(&seen, owl_strdup(owl_filter_get_name(f)));
     504
     505  for (i=0; i<OWL_FILTER_MAXRECURSE; i++) {
     506    /* if anything in 'tocheck' is in 'seen' we have a loop */
     507    if (owl_util_common_strings_in_lists(&tocheck, &seen)) {
     508      owl_list_free_all(&tmp, owl_free);
     509      owl_list_free_all(&tocheck, owl_free);
     510      owl_list_free_all(&seen, owl_free);
     511      return(1);
     512    }
     513
     514    /* if there's nothing to check, we're done */
     515    y=owl_list_get_size(&tocheck);
     516    if (y==0) {
     517      owl_list_free_all(&tmp, owl_free);
     518      owl_list_free_all(&tocheck, owl_free);
     519      owl_list_free_all(&seen, owl_free);
     520      return(0);
     521    }
     522
     523    /* add everything in 'tocheck' to the 'seen' list */
     524    /* y=owl_list_get_size(&tocheck); */
     525    for (x=0; x<y; x++) {
     526      owl_list_append_element(&seen, owl_strdup(owl_list_get_element(&tocheck, x)));
     527    }
     528
     529    /* make a new list into 'tmp' with the children of 'tocheck' */
     530    /* y=owl_list_get_size(&tocheck); */
     531    for (x=0; x<y; x++) {
     532      subfilter=owl_global_get_filter(&g, owl_list_get_element(&tocheck, x));
     533      if (!subfilter) return(0);
     534      _owl_filter_get_subfilter_names(subfilter, &tmp);
     535    }
     536
     537    /* clean out 'tocheck' */
     538    owl_list_free_all(&tocheck, owl_free);
     539    owl_list_create(&tocheck);
     540
     541    /* put 'tmp' into 'tocheck' */
     542    y=owl_list_get_size(&tmp);
     543    for (x=0; x<y; x++) {
     544      owl_util_list_add_unique_string(&tocheck, owl_list_get_element(&tmp, x));
     545    }
     546
     547    /* clean out 'tmp' */
     548    owl_list_free_all(&tmp, owl_free);
     549    owl_list_create(&tmp);
     550  }
     551
     552  owl_list_free_all(&tmp, owl_free);
     553  owl_list_free_all(&tocheck, owl_free);
     554  owl_list_free_all(&seen, owl_free);
     555
     556  return(1);
     557}
     558
     559/* If the filter exceeds the max recursion depth, due to filters of
     560 * filters with possible loops, return 1.  Otherwise, return 0.
     561 */
     562int owl_filter_is_toodeep_old(owl_filter *f)
     563{
     564  int ret;
     565
     566  owl_function_debugmsg("owl_filter_is_toodeep: checking depth");
     567  filter_depth=0;
     568  ret=_owl_filter_toodeep_recurse(f);
     569  if (ret || (filter_depth>OWL_FILTER_MAXRECURSE)) {
     570    owl_function_debugmsg("owl_filter_is_toodeep: too deep");
     571    return(1);
     572  }
     573  owl_function_debugmsg("owl_filter_is_toodeep: ok");
     574  return(0);
     575}
     576
     577int _owl_filter_toodeep_recurse(owl_filter *f)
     578{
     579  owl_list list;
     580  owl_filter *subfilter;
     581  int i, j;
     582
     583  owl_function_debugmsg("_owl_filter_toodeep_recurse: filter_depth on entrance is  %i", filter_depth);
     584
     585  owl_list_create(&list);
     586  _owl_filter_get_subfilter_names(f, &list);
     587  j=owl_list_get_size(&list);
     588  if (j>0) {
     589    filter_depth++;
     590    if (filter_depth>OWL_FILTER_MAXRECURSE) {
     591      owl_list_free_all(&list, owl_free);
     592      return(1);
     593    }
     594    for (i=0; i<j; i++) {
     595      subfilter=owl_global_get_filter(&g, owl_list_get_element(&list, i));
     596      if (!subfilter) {
     597        owl_function_error("_owl_filter_toodeep_recurse: subfilter %s does not exist",
     598                           owl_list_get_element(&list, i));
     599        return(1);
     600      }
     601      return(_owl_filter_toodeep_recurse(subfilter));
     602    }
     603  }
     604  owl_list_free_all(&list, owl_free);
    410605  return(0);
    411606}
Note: See TracChangeset for help on using the changeset viewer.