/* * 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 #include #include #include #include #include #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; }