/*
* Program: Synonym
* File: filtering.c
* Author: Ionut Nistor
* Date: 9 Sep 2003
*
* $Id: filtering.c,v 1.4 2004/01/19 09:24:31 diciu Exp $
*
* Licensed under the Modulo Consulting Software License
* (see file license.txt)
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include "synonym.h"
#include "filtering.h"
#include "config.h"
const char filtering_c_objid[]="$Id: filtering.c,v 1.4 2004/01/19 09:24:31 diciu Exp $";
sresult Synonym_Process_Rules(synonym_rule *rules, synonym_header *headers, char *envelope_from, to_list *envelope_to, matched_action **matched_actions)
{
synonym_rule *temp_rule;
synonym_condition *temp_condition;
synonym_header *temp_header;
to_list *temp_to;
matched_action *new_matched_action, *temp_action;
BOOL condition_mismatch; /* Flag used to drop us out of the rule is a condition failed to match */
// if(headers == NULL) /* Just in case - even though it should already have been checked in the calling module */
// {
// syslog(LOG_ERR, "No headers found for rules processing");
// return SYNONYM_RULES_PROCESSING_ERROR;
// }
syslog(LOG_DEBUG, "Begin checking rules");
for(temp_rule=rules; temp_rule != NULL; temp_rule = temp_rule->next) /* Parse all the rules */
{
syslog(LOG_DEBUG, "Processing rule...");
condition_mismatch = FALSE;
if(temp_rule->conditions==NULL) /* Just in case, though we checked in the config parsing */
{
syslog(LOG_ERR, "No conditions in rule while processing the rules");
return SYNONYM_RULES_PROCESSING_ERROR;
}
for(temp_condition=temp_rule->conditions;temp_condition!=NULL;temp_condition=temp_condition->next) /* All the conditions in the current rule */
{
/* Let's look for the condition type */
if(temp_condition->header_field[0] != '\0') /* We have a header condition */
{
syslog(LOG_DEBUG, "Checking condition in rule (look for %s header field)", temp_condition->header_field);
for(temp_header=headers; temp_header != NULL; temp_header = temp_header->next)
if(!strcasecmp(temp_condition->header_field, temp_header->header_name)) /* We found the header to match */
{
syslog(LOG_DEBUG, "Checking %s against header name %s value %s", temp_condition->header_regexp, temp_header->header_name, temp_header->header_value);
if(regexec(&temp_condition->header_compiled_regexp, temp_header->header_value, 0, NULL, 0) == REG_NOMATCH) /* Condition does not match so the rule drops since all conditions are implemented with 'and' between them */
{
syslog(LOG_DEBUG, "Header condition failed to match");
condition_mismatch = TRUE;
break;
}
else /* It matched */
break;
}
if(temp_header == NULL) /* We did not find any header with that name */
condition_mismatch = TRUE;
if(condition_mismatch) /* One condition already failed to match */
break;
}
if(temp_condition->env_to_condition[0] != '\0') /* We have an 'envelope to' condition */
{
syslog(LOG_DEBUG, "Matching an envelope from");
for(temp_to=envelope_to; temp_to!=NULL; temp_to=temp_to->next)
{
if(regexec(&temp_condition->env_to_compiled_regexp, temp_to->email, 0, NULL, 0) == REG_NOMATCH) /* Condition does not match so the rule drops since all conditions are implemented with 'and' between them */
{
syslog(LOG_DEBUG, "'Envelope To' condition failed to match");
condition_mismatch = TRUE;
}
}
}
if(temp_condition->env_from_condition[0] != '\0') /* We have an 'envelope from' condition */
{
syslog(LOG_DEBUG, "Matching an envelope from");
if(regexec(&temp_condition->env_from_compiled_regexp, envelope_from, 0, NULL, 0) == REG_NOMATCH) /* Condition does not match so the rule drops since all conditions are implemented with 'and' between them */
{
syslog(LOG_DEBUG, "'Envelope From' condition failed to match");
condition_mismatch = TRUE;
}
}
}
if(!condition_mismatch) /* All the condition of the rule matched */
{
syslog(LOG_DEBUG, "All conditions matched for the action type %d", temp_rule->action.action_type);
new_matched_action = (matched_action*)malloc(sizeof(matched_action));
if(new_matched_action == NULL) /* Alloc failure */
{
syslog(LOG_CRIT, "CRITICAL ERROR: Failed to allocate memory in rule processing");
return SYNONYM_ALLOC_FAILED;
}
new_matched_action->action.action_type = temp_rule->action.action_type;
if(temp_rule->action.action_custom_field != NULL)
strcpy(new_matched_action->action.action_custom_field, temp_rule->action.action_custom_field);
#ifdef DISCLAIMER_SUPPORT
if(temp_rule->action.action_text_disclaimer != NULL)
strcpy(new_matched_action->action.action_text_disclaimer, temp_rule->action.action_text_disclaimer);
if(temp_rule->action.action_html_disclaimer != NULL)
strcpy(new_matched_action->action.action_html_disclaimer, temp_rule->action.action_html_disclaimer);
#endif
new_matched_action->next = NULL;
if(*matched_actions == NULL) /* None matched until now */
*matched_actions = new_matched_action;
else /* Add at the end of the list */
{
temp_action = *matched_actions;
while(temp_action->next != NULL)
temp_action = temp_action->next;
temp_action->next=new_matched_action;
}
}
}
return SYNONYM_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1