/*
 * This function is recursive..  I wish I knew a nonrecursive way but
 * I dont.  anyway, recursion is fun..  :)
 * DO NOT CALL THIS FUNTION WITH A POINTER TO A NULL POINTER
 * (ie: If *elem is NULL, you're doing it wrong - seg fault)
 */
void crule_free(struct CRuleNode** elem)
{
  int arg, numargs;

  if ((*(elem))->funcptr == crule__not)
  {
    /* type conversions and ()'s are fun! ;)  here have an asprin.. */
    if ((*(elem))->arg[0] != NULL)
      crule_free((struct CRuleNode**) &((*(elem))->arg[0]));
  }
  else if ((*(elem))->funcptr == crule__andor)
  {
    crule_free((struct CRuleNode**) &((*(elem))->arg[0]));
    if ((*(elem))->arg[1] != NULL)
      crule_free((struct CRuleNode**) &((*(elem))->arg[1]));
  }
  else
  {
    numargs = (*(elem))->numargs;
    for (arg = 0; arg < numargs; arg++)
      MyFree((*(elem))->arg[arg]);
  }
#ifdef CR_DEBUG
  fprintf(stderr, "freeing element at %ld\n", *elem);
#endif
  MyFree(*elem);
  *elem = 0;
}
/*
 * Grammar
 *   rule:
 *     orexpr END          END is end of input or :
 *   orexpr:
 *     andexpr
 *     andexpr || orexpr
 *   andexpr:
 *     primary
 *     primary && andexpr
 *  primary:
 *    function
 *    ! primary
 *    ( orexpr )
 *  function:
 *    word ( )             word is alphanumeric string, first character
 *    word ( arglist )       must be a letter
 *  arglist:
 *    word
 *    word , arglist
 */
struct CRuleNode* crule_parse(const char *rule)
{
  const char* ruleptr = rule;
  int next_tok;
  struct CRuleNode* ruleroot = 0;
  int errcode = CR_NOERR;

  if ((errcode = crule_gettoken(&next_tok, &ruleptr)) == CR_NOERR) {
    if ((errcode = crule_parseorexpr(&ruleroot, &next_tok, &ruleptr)) == CR_NOERR) {
      if (ruleroot != NULL) {
        if (next_tok == CR_END)
          return (ruleroot);
        else
          errcode = CR_UNEXPCTTOK;
      }
      else
        errcode = CR_EXPCTOR;
    }
  }
  if (ruleroot != NULL)
    crule_free(&ruleroot);
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
  Debug((DEBUG_ERROR, "%s in rule: %s", crule_errstr[errcode], rule));
#else
  fprintf(stderr, "%s in rule: %s\n", crule_errstr[errcode], rule);
#endif
  return 0;
}
示例#3
0
/** Free all CRules from #cruleConfList. */
void conf_erase_crule_list(void)
{
  struct CRuleConf* next;
  struct CRuleConf* p = cruleConfList;

  for ( ; p; p = next) {
    next = p->next;
    crule_free(&p->node);
    MyFree(p->hostmask);
    MyFree(p->rule);
    MyFree(p);
  }
  cruleConfList = 0;
}
int main(void)
{
  char indata[256];
  CRuleNode* rule;

  printf("rule: ");
  while (fgets(indata, 256, stdin) != NULL)
  {
    indata[strlen(indata) - 1] = '\0';  /* lose the newline */
    if ((rule = crule_parse(indata)) != NULL)
    {
      printf("equivalent rule: ");
      print_tree((CRuleNodePtr) rule);
      printf("\n");
      crule_free(&rule);
    }
    printf("\nrule: ");
  }
  printf("\n");

  return 0;
}