new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / rules.c
old mode 100755 (executable)
new mode 100644 (file)
index bf9c651..ee11070
@@ -1,6 +1,3 @@
-/* @(#) $Id: ./src/analysisd/rules.c, 2011/09/08 dcid Exp $
- */
-
 /* Copyright (C) 2009 Trend Micro Inc.
  * All rights reserved.
  *
@@ -8,62 +5,45 @@
  * and/or modify it under the terms of the GNU General Public
  * License (version 2) as published by the FSF - Free Software
  * Foundation.
- *
- * License details at the LICENSE file included with OSSEC or
- * online at: http://www.ossec.net/en/licensing.html
  */
 
-
-
 #include "rules.h"
 #include "config.h"
 #include "eventinfo.h"
 #include "compiled_rules/compiled_rules.h"
 
+/* Global definition */
+RuleInfo *currently_rule;
 
-/* Chaging path for test rule. */
+/* Change path for test rule */
 #ifdef TESTRULE
-  #undef RULEPATH
-  #define RULEPATH "rules/"
+#undef RULEPATH
+#define RULEPATH "rules/"
 #endif
 
-
-
-/* Internal functions */
-int getattributes(char **attributes,
+/* Prototypes */
+static int getattributes(char **attributes,
                   char **values,
                   int *id, int *level,
                   int *maxsize, int *timeframe,
                   int *frequency, int *accuracy,
                   int *noalert, int *ignore_time, int *overwrite);
-int doesRuleExist(int sid, RuleNode *r_node);
+static int doesRuleExist(int sid, RuleNode *r_node);
+static void Rule_AddAR(RuleInfo *config_rule);
+static char *loadmemory(char *at, const char *str);
+static void printRuleinfo(const RuleInfo *rule, int node);
 
-
-void Rule_AddAR(RuleInfo *config_rule);
-char *loadmemory(char *at, char *str);
-int getDecoderfromlist(char *name);
-
-extern int _max_freq;
-
-
-
-/* Rules_OP_ReadRules, v0.1, 2005/07/04
- * Will initialize the rules list
- */
+/* Will initialize the rules list */
 void Rules_OP_CreateRules()
 {
-
-     /* Initializing the rule list */
+    /* Initialize the rule list */
     OS_CreateRuleList();
 
     return;
 }
 
-/* Rules_OP_ReadRules, v0.3, 2005/03/21
- * Read the log rules.
- * v0.3: Fixed many memory problems.
- */
-int Rules_OP_ReadRules(char * rulefile)
+/* Read the log rules */
+int Rules_OP_ReadRules(const char *rulefile)
 {
     OS_XML xml;
     XML_NODE node = NULL;
@@ -71,291 +51,268 @@ int Rules_OP_ReadRules(char * rulefile)
     /* XML variables */
     /* These are the available options for the rule configuration */
 
-    char *xml_group = "group";
-    char *xml_rule = "rule";
-
-    char *xml_regex = "regex";
-    char *xml_match = "match";
-    char *xml_decoded = "decoded_as";
-    char *xml_category = "category";
-    char *xml_cve = "cve";
-    char *xml_info = "info";
-    char *xml_day_time = "time";
-    char *xml_week_day = "weekday";
-    char *xml_comment = "description";
-    char *xml_ignore = "ignore";
-    char *xml_check_if_ignored = "check_if_ignored";
-
-    char *xml_srcip = "srcip";
-    char *xml_srcport = "srcport";
-    char *xml_dstip = "dstip";
-    char *xml_dstport = "dstport";
-    char *xml_user = "user";
-    char *xml_url = "url";
-    char *xml_id = "id";
-    char *xml_data = "extra_data";
-    char *xml_hostname = "hostname";
-    char *xml_program_name = "program_name";
-    char *xml_status = "status";
-    char *xml_action = "action";
-    char *xml_compiled = "compiled_rule";
-
-    char *xml_list = "list";
-    char *xml_list_lookup = "lookup";
-    char *xml_list_field = "field";
-    char *xml_list_cvalue = "check_value";
-    char *xml_match_key = "match_key";
-    char *xml_not_match_key = "not_match_key";
-    char *xml_match_key_value = "match_key_value";
-    char *xml_address_key = "address_match_key";
-    char *xml_not_address_key = "not_address_match_key";
-    char *xml_address_key_value = "address_match_key_value";
-
-    char *xml_if_sid = "if_sid";
-    char *xml_if_group = "if_group";
-    char *xml_if_level = "if_level";
-    char *xml_fts = "if_fts";
-
-    char *xml_if_matched_regex = "if_matched_regex";
-    char *xml_if_matched_group = "if_matched_group";
-    char *xml_if_matched_sid = "if_matched_sid";
-
-    char *xml_same_source_ip = "same_source_ip";
-    char *xml_same_src_port = "same_src_port";
-    char *xml_same_dst_port = "same_dst_port";
-    char *xml_same_user = "same_user";
-    char *xml_same_location = "same_location";
-    char *xml_same_id = "same_id";
-    char *xml_dodiff = "check_diff";
-
-    char *xml_different_url = "different_url";
-
-    char *xml_notsame_source_ip = "not_same_source_ip";
-    char *xml_notsame_user = "not_same_user";
-    char *xml_notsame_agent = "not_same_agent";
-    char *xml_notsame_id = "not_same_id";
-
-    char *xml_options = "options";
+    const char *xml_group = "group";
+    const char *xml_rule = "rule";
+
+    const char *xml_regex = "regex";
+    const char *xml_pcre2 = "pcre2";
+    const char *xml_match = "match";
+    const char *xml_match_pcre2 = "match_pcre2";
+    const char *xml_decoded = "decoded_as";
+    const char *xml_category = "category";
+    const char *xml_cve = "cve";
+    const char *xml_info = "info";
+    const char *xml_day_time = "time";
+    const char *xml_week_day = "weekday";
+    const char *xml_comment = "description";
+    const char *xml_ignore = "ignore";
+    const char *xml_check_if_ignored = "check_if_ignored";
+
+    const char *xml_srcip = "srcip";
+    const char *xml_srcgeoip = "srcgeoip";
+    const char *xml_srcport = "srcport";
+    const char *xml_srcgeoip_pcre2 = "srcgeoip_pcre2";
+    const char *xml_srcport_pcre2 = "srcport_pcre2";
+    const char *xml_dstip = "dstip";
+    const char *xml_dstgeoip = "dstgeoip";
+    const char *xml_dstport = "dstport";
+    const char *xml_user = "user";
+    const char *xml_url = "url";
+    const char *xml_id = "id";
+    const char *xml_data = "extra_data";
+    const char *xml_hostname = "hostname";
+    const char *xml_program_name = "program_name";
+    const char *xml_status = "status";
+    const char *xml_dstgeoip_pcre2 = "dstgeoip_pcre2";
+    const char *xml_dstport_pcre2 = "dstport_pcre2";
+    const char *xml_user_pcre2 = "user_pcre2";
+    const char *xml_url_pcre2 = "url_pcre2";
+    const char *xml_id_pcre2 = "id_pcre2";
+    const char *xml_data_pcre2 = "extra_data_pcre2";
+    const char *xml_hostname_pcre2 = "hostname_pcre2";
+    const char *xml_program_name_pcre2 = "program_name_pcre2";
+    const char *xml_status_pcre2 = "status_pcre2";
+    const char *xml_action = "action";
+    const char *xml_compiled = "compiled_rule";
+    const char *xml_field = "field";
+    const char *xml_name = "name";
+
+
+    const char *xml_list = "list";
+    const char *xml_list_lookup = "lookup";
+    const char *xml_list_field = "field";
+    const char *xml_list_cvalue = "check_value";
+    const char *xml_match_key = "match_key";
+    const char *xml_not_match_key = "not_match_key";
+    const char *xml_match_key_value = "match_key_value";
+    const char *xml_address_key = "address_match_key";
+    const char *xml_not_address_key = "not_address_match_key";
+    const char *xml_address_key_value = "address_match_key_value";
+
+    const char *xml_if_sid = "if_sid";
+    const char *xml_if_group = "if_group";
+    const char *xml_if_level = "if_level";
+    const char *xml_fts = "if_fts";
+
+    const char *xml_if_matched_regex = "if_matched_regex";
+    const char *xml_if_matched_group = "if_matched_group";
+    const char *xml_if_matched_sid = "if_matched_sid";
+
+    const char *xml_same_source_ip = "same_source_ip";
+    const char *xml_same_src_port = "same_src_port";
+    const char *xml_same_dst_port = "same_dst_port";
+    const char *xml_same_user = "same_user";
+    const char *xml_same_location = "same_location";
+    const char *xml_same_id = "same_id";
+    const char *xml_dodiff = "check_diff";
+
+    const char *xml_different_url = "different_url";
+    const char *xml_different_srcip = "different_srcip";
+    const char *xml_different_srcgeoip = "different_srcgeoip";
+
+    const char *xml_notsame_source_ip = "not_same_source_ip";
+    const char *xml_notsame_user = "not_same_user";
+    const char *xml_notsame_agent = "not_same_agent";
+    const char *xml_notsame_id = "not_same_id";
+
+    const char *xml_options = "options";
 
     char *rulepath;
 
-    int i;
+    size_t i;
     int default_timeframe = 360;
 
-
-    /* If no directory in the rulefile add the default */
-    if((strchr(rulefile, '/')) == NULL)
-    {
-        /* Building the rule file name + path */
+    /* If no directory in the rulefile, add the default */
+    if ((strchr(rulefile, '/')) == NULL) {
+        /* Build the rule file name + path */
         i = strlen(RULEPATH) + strlen(rulefile) + 2;
-        rulepath = (char *)calloc(i,sizeof(char));
-        if(!rulepath)
-        {
-            ErrorExit(MEM_ERROR,ARGV0);
+        rulepath = (char *)calloc(i, sizeof(char));
+        if (!rulepath) {
+            ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
         }
-        snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile);
-    }
-    else
-    {
+        snprintf(rulepath, i, "%s/%s", RULEPATH, rulefile);
+    } else {
         os_strdup(rulefile, rulepath);
         debug1("%s is the rulefile", rulefile);
         debug1("Not modifing the rule path");
     }
 
-
     i = 0;
 
-    /* Reading the XML */
-    if(OS_ReadXML(rulepath,&xml) < 0)
-    {
+    /* Read the XML */
+    if (OS_ReadXML(rulepath, &xml) < 0) {
         merror(XML_ERROR, ARGV0, rulepath, xml.err, xml.err_line);
         free(rulepath);
-        return(-1);    
+        return (-1);
     }
-
-
-    /* Debug wrapper */
     debug2("%s: DEBUG: read xml for rule.", ARGV0);
 
-
-
-    /* Applying any variable found */
-    if(OS_ApplyVariables(&xml) != 0)
-    {
+    /* Apply any variable found */
+    if (OS_ApplyVariables(&xml) != 0) {
         merror(XML_ERROR_VAR, ARGV0, rulepath, xml.err);
-        return(-1);
+        free(rulepath);
+        return (-1);
     }
-
-
-    /* Debug wrapper */
     debug2("%s: DEBUG: XML Variables applied.", ARGV0);
 
-
-    /* Getting the root elements */
-    node = OS_GetElementsbyNode(&xml,NULL);
-    if(!node)
-    {
+    /* Get the root elements */
+    node = OS_GetElementsbyNode(&xml, NULL);
+    if (!node) {
         merror(CONFIG_ERROR, ARGV0, rulepath);
         OS_ClearXML(&xml);
-        return(-1);
+        free(rulepath);
+        return (-1);
     }
 
-
-    /* Zeroing the rule memory -- not used anymore */
+    /* Zero the rule memory -- not used anymore */
     free(rulepath);
 
-
-    /* Getting default time frame */
+    /* Get default time frame */
     default_timeframe = getDefine_Int("analysisd",
                                       "default_timeframe",
-                                      60, 3600);
-
+                                      60, MAX_TIMEFRAME);
 
-    /* Checking if there is any invalid global option */
-    while(node[i])
-    {
-        if(node[i]->element)
-        {
-            if(strcasecmp(node[i]->element,xml_group) != 0)
-            {
+    /* Check if there is any invalid global option */
+    while (node[i]) {
+        if (node[i]->element) {
+            if (strcasecmp(node[i]->element, xml_group) != 0) {
                 merror("rules_op: Invalid root element \"%s\"."
-                        "Only \"group\" is allowed",node[i]->element);
+                       "Only \"group\" is allowed", node[i]->element);
                 OS_ClearXML(&xml);
-                return(-1);
+                return (-1);
             }
-            if((!node[i]->attributes) || (!node[i]->values)||
+            if ((!node[i]->attributes) || (!node[i]->values) ||
                     (!node[i]->values[0]) || (!node[i]->attributes[0]) ||
-                    (strcasecmp(node[i]->attributes[0],"name") != 0) ||
-                    (node[i]->attributes[1]))
-            {
+                    (strcasecmp(node[i]->attributes[0], "name") != 0) ||
+                    (node[i]->attributes[1])) {
                 merror("rules_op: Invalid root element '%s'."
-                        "Only the group name is allowed",node[i]->element);
+                       "Only the group name is allowed", node[i]->element);
                 OS_ClearXML(&xml);
-                return(-1);
+                return (-1);
             }
-        }
-        else
-        {
+        } else {
             merror(XML_READ_ERROR, ARGV0);
             OS_ClearXML(&xml);
-            return(-1);
+            return (-1);
         }
         i++;
     }
 
-
-    /* Getting the rules now */
-    i=0;
-    while(node[i])
-    {
+    /* Get the rules */
+    i = 0;
+    while (node[i]) {
         XML_NODE rule = NULL;
 
         int j = 0;
 
-        /* Getting all rules for a global group */
-        rule = OS_GetElementsbyNode(&xml,node[i]);
-        if(rule == NULL)
-        {
+        /* Get all rules for a global group */
+        rule = OS_GetElementsbyNode(&xml, node[i]);
+        if (rule == NULL) {
             merror("%s: Group '%s' without any rule.",
-                    ARGV0, node[i]->element);
+                   ARGV0, node[i]->element);
             OS_ClearXML(&xml);
-            return(-1);
+            return (-1);
         }
 
-        while(rule[j])
-        {
+        while (rule[j]) {
             RuleInfo *config_ruleinfo = NULL;
 
-
-            /* Checking if the rule element is correct */
-            if((!rule[j]->element)||
-                    (strcasecmp(rule[j]->element,xml_rule) != 0))
-            {
+            /* Check if the rule element is correct */
+            if ((!rule[j]->element) ||
+                    (strcasecmp(rule[j]->element, xml_rule) != 0)) {
                 merror("%s: Invalid configuration. '%s' is not "
                        "a valid element.", ARGV0, rule[j]->element);
                 OS_ClearXML(&xml);
-                return(-1);
+                return (-1);
             }
 
-
-            /* Checking for the attributes of the rule */
-            if((!rule[j]->attributes) || (!rule[j]->values))
-            {
+            /* Check for the attributes of the rule */
+            if ((!rule[j]->attributes) || (!rule[j]->values)) {
                 merror("%s: Invalid rule '%d'. You must specify"
-                        " an ID and a level at least.", ARGV0, j);
+                       " an ID and a level at least.", ARGV0, j);
                 OS_ClearXML(&xml);
-                return(-1);
+                return (-1);
             }
 
-
             /* Attribute block */
             {
-                int id = -1,level = -1,maxsize = 0,timeframe = 0;
+                int id = -1, level = -1, maxsize = 0, timeframe = 0;
                 int frequency = 0, accuracy = 1, noalert = 0, ignore_time = 0;
                 int overwrite = 0;
 
-                /* Getting default time frame */
+                /* Get default timeframe */
                 timeframe = default_timeframe;
 
-
-                if(getattributes(rule[j]->attributes,rule[j]->values,
-                            &id,&level,&maxsize,&timeframe,
-                            &frequency,&accuracy,&noalert,
-                            &ignore_time, &overwrite) < 0)
-                {
+                if (getattributes(rule[j]->attributes, rule[j]->values,
+                                  &id, &level, &maxsize, &timeframe,
+                                  &frequency, &accuracy, &noalert,
+                                  &ignore_time, &overwrite) < 0) {
                     merror("%s: Invalid attribute for rule.", ARGV0);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
 
-                if((id == -1) || (level == -1))
-                {
+                if ((id == -1) || (level == -1)) {
                     merror("%s: No rule id or level specified for "
-                            "rule '%d'.",ARGV0, j);
+                           "rule '%d'.", ARGV0, j);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
 
-                if(overwrite != 1 && doesRuleExist(id, NULL))
-                {
-                    merror("%s: Duplicate rule ID:%d",ARGV0, id);
+                if (overwrite != 1 && doesRuleExist(id, NULL)) {
+                    merror("%s: Duplicate rule ID:%d", ARGV0, id);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
 
-                /* Allocating memory and initializing structure */
+                /* Allocate memory and initialize structure */
                 config_ruleinfo = zerorulemember(id, level, maxsize,
-                            frequency,timeframe,
-                            noalert, ignore_time, overwrite);
-
+                                                 frequency, timeframe,
+                                                 noalert, ignore_time, overwrite);
 
                 /* If rule is 0, set it to level 99 to have high priority.
-                 * set it to 0 again later
+                 * Set it to 0 again later.
                  */
-                 if(config_ruleinfo->level == 0)
-                     config_ruleinfo->level = 99;
-
-
-                 /* Each level now is going to be multiplied by 100.
-                  * If the accuracy is set to 0 we don't multiply,
-                  * so it will be at the end of the list. We will
-                  * divide by 100 later.
-                  */
-                 if(accuracy)
-                 {
-                     config_ruleinfo->level *= 100;
-                 }
-
-                 if(config_ruleinfo->maxsize > 0)
-                 {
-                     if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
-                     {
-                         config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                     }
-                 }
+                if (config_ruleinfo->level == 0) {
+                    config_ruleinfo->level = 99;
+                }
 
-            } /* end attributes/memory allocation block */
+                /* Each level now is going to be multiplied by 100.
+                 * If the accuracy is set to 0 we don't multiply,
+                 * so it will be at the end of the list. We will
+                 * divide by 100 later.
+                 */
+                if (accuracy) {
+                    config_ruleinfo->level *= 100;
+                }
 
+                if (config_ruleinfo->maxsize > 0) {
+                    if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                        config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                    }
+                }
+
+            } /* end attributes/memory allocation block */
 
             /* Here we can assign the group name to the rule.
              * The level is correct so the rule is probably going to
@@ -363,110 +320,116 @@ int Rules_OP_ReadRules(char * rulefile)
              */
             os_strdup(node[i]->values[0], config_ruleinfo->group);
 
-
             /* Rule elements block */
             {
                 int k = 0;
+                int ifield = 0;
                 int info_type = 0;
                 int count_info_detail = 0;
                 RuleInfoDetail *last_info_detail = NULL;
                 char *regex = NULL;
                 char *match = NULL;
+                char *pcre2 = NULL;
+                char *match_pcre2 = NULL;
                 char *url = NULL;
+                char *url_pcre2 = NULL;
                 char *if_matched_regex = NULL;
                 char *if_matched_group = NULL;
                 char *user = NULL;
                 char *id = NULL;
                 char *srcport = NULL;
                 char *dstport = NULL;
+                char *srcgeoip = NULL;
+                char *dstgeoip = NULL;
+
                 char *status = NULL;
                 char *hostname = NULL;
                 char *extra_data = NULL;
                 char *program_name = NULL;
 
+                char *user_pcre2 = NULL;
+                char *id_pcre2 = NULL;
+                char *srcport_pcre2 = NULL;
+                char *dstport_pcre2 = NULL;
+                char *srcgeoip_pcre2 = NULL;
+                char *dstgeoip_pcre2 = NULL;
+
+                char *status_pcre2 = NULL;
+                char *hostname_pcre2 = NULL;
+                char *extra_data_pcre2 = NULL;
+                char *program_name_pcre2 = NULL;
+
                 XML_NODE rule_opt = NULL;
-                rule_opt =  OS_GetElementsbyNode(&xml,rule[j]);
-                if(rule_opt == NULL)
-                {
+                rule_opt =  OS_GetElementsbyNode(&xml, rule[j]);
+                if (rule_opt == NULL) {
                     merror("%s: Rule '%d' without any option. "
-                            "It may lead to false positives and some "
-                            "other problems for the system. Exiting.",
-                            ARGV0, config_ruleinfo->sigid);
+                           "It may lead to false positives and some "
+                           "other problems for the system. Exiting.",
+                           ARGV0, config_ruleinfo->sigid);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
 
-                while(rule_opt[k])
-                {
-                    if((!rule_opt[k]->element)||(!rule_opt[k]->content))
+                while (rule_opt[k]) {
+                    if ((!rule_opt[k]->element) || (!rule_opt[k]->content)) {
                         break;
-                    else if(strcasecmp(rule_opt[k]->element,xml_regex)==0)
-                    {
+                    } else if (strcasecmp(rule_opt[k]->element, xml_regex) == 0) {
                         regex =
                             loadmemory(regex,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_match)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_pcre2) == 0) {
+                        pcre2 =
+                            loadmemory(pcre2,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_match) == 0) {
                         match =
                             loadmemory(match,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element, xml_decoded)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_match_pcre2) == 0) {
+                        match_pcre2 =
+                            loadmemory(match_pcre2,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_decoded) == 0) {
                         config_ruleinfo->decoded_as =
                             getDecoderfromlist(rule_opt[k]->content);
 
-                        if(config_ruleinfo->decoded_as == 0)
-                        {
+                        if (config_ruleinfo->decoded_as == 0) {
                             merror("%s: Invalid decoder name: '%s'.",
                                    ARGV0, rule_opt[k]->content);
                             OS_ClearXML(&xml);
-                            return(-1);
+                            return (-1);
                         }
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_cve)==0)
-                    {
-                        if(config_ruleinfo->info_details == NULL)
-                        {
+                    } else if (strcasecmp(rule_opt[k]->element, xml_cve) == 0) {
+                        if (config_ruleinfo->info_details == NULL) {
                             config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE,
-                                    rule_opt[k]->content);
-                        }
-                        else
-                        {
+                                                            rule_opt[k]->content);
+                        } else {
                             for (last_info_detail = config_ruleinfo->info_details;
                                     last_info_detail->next != NULL;
-                                    last_info_detail = last_info_detail->next)
-                            {
+                                    last_info_detail = last_info_detail->next) {
                                 count_info_detail++;
                             }
                             /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */
-                            if (count_info_detail <= MAX_RULEINFODETAIL)
-                            {
+                            if (count_info_detail <= MAX_RULEINFODETAIL) {
                                 last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE,
-                                        rule_opt[k]->content);
+                                                         rule_opt[k]->content);
                             }
                         }
 
                         /* keep old methods for now */
-                        config_ruleinfo->cve=
+                        config_ruleinfo->cve =
                             loadmemory(config_ruleinfo->cve,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_info)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_info) == 0) {
 
                         info_type = get_info_attributes(rule_opt[k]->attributes,
                                                         rule_opt[k]->values);
                         debug1("info_type = %d", info_type);
 
-                        if(config_ruleinfo->info_details == NULL)
-                        {
+                        if (config_ruleinfo->info_details == NULL) {
                             config_ruleinfo->info_details = zeroinfodetails(info_type,
-                                    rule_opt[k]->content);
-                        }
-                        else
-                        {
+                                                            rule_opt[k]->content);
+                        } else {
                             for (last_info_detail = config_ruleinfo->info_details;
                                     last_info_detail->next != NULL;
                                     last_info_detail = last_info_detail->next) {
@@ -480,272 +443,341 @@ int Rules_OP_ReadRules(char * rulefile)
 
 
                         /* keep old methods for now */
-                        config_ruleinfo->info=
+                        config_ruleinfo->info =
                             loadmemory(config_ruleinfo->info,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_day_time)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_day_time) == 0) {
                         config_ruleinfo->day_time =
                             OS_IsValidTime(rule_opt[k]->content);
-                        if(!config_ruleinfo->day_time)
-                        {
+                        if (!config_ruleinfo->day_time) {
                             merror(INVALID_CONFIG, ARGV0,
-                                    rule_opt[k]->element,
-                                    rule_opt[k]->content);
-                            return(-1);
+                                   rule_opt[k]->element,
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
 
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_week_day)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_week_day) == 0) {
                         config_ruleinfo->week_day =
                             OS_IsValidDay(rule_opt[k]->content);
 
-                        if(!config_ruleinfo->week_day)
-                        {
+                        if (!config_ruleinfo->week_day) {
                             merror(INVALID_CONFIG, ARGV0,
-                                    rule_opt[k]->element,
-                                    rule_opt[k]->content);
-                            return(-1);
+                                   rule_opt[k]->element,
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_group)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_group) == 0) {
                         config_ruleinfo->group =
                             loadmemory(config_ruleinfo->group,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_comment)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_comment) == 0) {
                         char *newline;
 
                         newline = strchr(rule_opt[k]->content, '\n');
-                        if(newline)
-                        {
+                        if (newline) {
                             *newline = ' ';
                         }
 
-                        config_ruleinfo->comment=
+                        config_ruleinfo->comment =
                             loadmemory(config_ruleinfo->comment,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_srcip)==0)
-                    {
-                        int ip_s = 0;
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_srcip) == 0) {
+                        unsigned int ip_s = 0;
 
                         /* Getting size of source ip list */
-                        while(config_ruleinfo->srcip &&
-                              config_ruleinfo->srcip[ip_s])
-                        {
+                        while (config_ruleinfo->srcip &&
+                                config_ruleinfo->srcip[ip_s]) {
                             ip_s++;
                         }
 
                         config_ruleinfo->srcip =
-                                    realloc(config_ruleinfo->srcip,
+                            (os_ip **) realloc(config_ruleinfo->srcip,
                                     (ip_s + 2) * sizeof(os_ip *));
 
 
                         /* Allocating memory for the individual entries */
                         os_calloc(1, sizeof(os_ip),
-                                     config_ruleinfo->srcip[ip_s]);
-                        config_ruleinfo->srcip[ip_s +1] = NULL;
+                                  config_ruleinfo->srcip[ip_s]);
+                        config_ruleinfo->srcip[ip_s + 1] = NULL;
 
 
                         /* Checking if the ip is valid */
-                        if(!OS_IsValidIP(rule_opt[k]->content,
-                                         config_ruleinfo->srcip[ip_s]))
-                        {
+                        if (!OS_IsValidIP(rule_opt[k]->content,
+                                          config_ruleinfo->srcip[ip_s])) {
                             merror(INVALID_IP, ARGV0, rule_opt[k]->content);
-                            return(-1);
+                            return (-1);
                         }
 
-                        if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
                             config_ruleinfo->alert_opts |= DO_PACKETINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_dstip)==0)
-                    {
-                        int ip_s = 0;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_dstip) == 0) {
+                        unsigned int ip_s = 0;
 
                         /* Getting size of source ip list */
-                        while(config_ruleinfo->dstip &&
-                                config_ruleinfo->dstip[ip_s])
-                        {
+                        while (config_ruleinfo->dstip &&
+                                config_ruleinfo->dstip[ip_s]) {
                             ip_s++;
                         }
 
                         config_ruleinfo->dstip =
-                                    realloc(config_ruleinfo->dstip,
+                            (os_ip **) realloc(config_ruleinfo->dstip,
                                     (ip_s + 2) * sizeof(os_ip *));
 
 
                         /* Allocating memory for the individual entries */
                         os_calloc(1, sizeof(os_ip),
-                                config_ruleinfo->dstip[ip_s]);
-                        config_ruleinfo->dstip[ip_s +1] = NULL;
+                                  config_ruleinfo->dstip[ip_s]);
+                        config_ruleinfo->dstip[ip_s + 1] = NULL;
 
 
                         /* Checking if the ip is valid */
-                        if(!OS_IsValidIP(rule_opt[k]->content,
-                                    config_ruleinfo->dstip[ip_s]))
-                        {
+                        if (!OS_IsValidIP(rule_opt[k]->content,
+                                          config_ruleinfo->dstip[ip_s])) {
                             merror(INVALID_IP, ARGV0, rule_opt[k]->content);
-                            return(-1);
+                            return (-1);
                         }
 
-                        if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
                             config_ruleinfo->alert_opts |= DO_PACKETINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_user)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_user) == 0) {
                         user =
                             loadmemory(user,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
+                    } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip)==0) {
+                        srcgeoip =
+                            loadmemory(srcgeoip,
                                     rule_opt[k]->content);
 
                         if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_id)==0)
-                    {
+                    } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip)==0) {
+                        dstgeoip =
+                            loadmemory(dstgeoip,
+                                    rule_opt[k]->content);
+
+                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                    } else if (strcasecmp(rule_opt[k]->element, xml_id) == 0) {
                         id =
                             loadmemory(id,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_srcport)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_srcport) == 0) {
                         srcport =
                             loadmemory(srcport,
-                                    rule_opt[k]->content);
-                        if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
+                                       rule_opt[k]->content);
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
                             config_ruleinfo->alert_opts |= DO_PACKETINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_dstport)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_dstport) == 0) {
                         dstport =
                             loadmemory(dstport,
-                                    rule_opt[k]->content);
+                                       rule_opt[k]->content);
 
-                        if(!(config_ruleinfo->alert_opts & DO_PACKETINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
                             config_ruleinfo->alert_opts |= DO_PACKETINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_status)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_status) == 0) {
                         status =
                             loadmemory(status,
-                                    rule_opt[k]->content);
+                                       rule_opt[k]->content);
 
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_hostname)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_hostname) == 0) {
                         hostname =
                             loadmemory(hostname,
-                                    rule_opt[k]->content);
+                                       rule_opt[k]->content);
 
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_data)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_data) == 0) {
                         extra_data =
                             loadmemory(extra_data,
-                                    rule_opt[k]->content);
+                                       rule_opt[k]->content);
 
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                       xml_program_name)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_program_name) == 0) {
                         program_name =
                             loadmemory(program_name,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_user_pcre2) == 0) {
+                        user_pcre2 =
+                            loadmemory(user_pcre2,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
+                    } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip_pcre2)==0) {
+                        srcgeoip_pcre2 =
+                            loadmemory(srcgeoip_pcre2,
                                     rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_action)==0)
-                    {
+
+                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                    } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip_pcre2)==0) {
+                        dstgeoip_pcre2 =
+                            loadmemory(dstgeoip_pcre2,
+                                    rule_opt[k]->content);
+
+                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                    } else if (strcasecmp(rule_opt[k]->element, xml_id_pcre2) == 0) {
+                        id_pcre2 =
+                            loadmemory(id_pcre2,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_srcport_pcre2) == 0) {
+                        srcport_pcre2 =
+                            loadmemory(srcport_pcre2,
+                                       rule_opt[k]->content);
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
+                            config_ruleinfo->alert_opts |= DO_PACKETINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_dstport_pcre2) == 0) {
+                        dstport_pcre2 =
+                            loadmemory(dstport_pcre2,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) {
+                            config_ruleinfo->alert_opts |= DO_PACKETINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_status_pcre2) == 0) {
+                        status_pcre2 =
+                            loadmemory(status_pcre2,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_hostname_pcre2) == 0) {
+                        hostname_pcre2 =
+                            loadmemory(hostname_pcre2,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element, xml_data_pcre2) == 0) {
+                        extra_data_pcre2 =
+                            loadmemory(extra_data_pcre2,
+                                       rule_opt[k]->content);
+
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_program_name_pcre2) == 0) {
+                        program_name_pcre2 =
+                            loadmemory(program_name_pcre2,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_action) == 0) {
                         config_ruleinfo->action =
                             loadmemory(config_ruleinfo->action,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_list)==0)
-                    {
-                        debug1("-> %s == %s",rule_opt[k]->element, xml_list);
-                        if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content)
-                        {
-                            int list_att_num=0;
-                            int rule_type=0;
-                            OSMatch *matcher=NULL;
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_field) == 0) {
+                        if (rule_opt[k]->attributes[0]) {
+                            os_calloc(1, sizeof(FieldInfo), config_ruleinfo->fields[ifield]);
+
+                            if (strcasecmp(rule_opt[k]->attributes[0], xml_name) == 0) {
+                                config_ruleinfo->fields[ifield]->name = loadmemory(config_ruleinfo->fields[ifield]->name, rule_opt[k]->values[0]);
+                            } else {
+                                merror("%s: Bad attribute '%s' for field.", ARGV0, rule_opt[k]->attributes[0]);
+                                return -1;
+                            }
+                        } else {
+                            merror("%s: No such attribute '%s' for field.", ARGV0, xml_name);
+                            return (-1);
+                        }
+
+                        os_calloc(1, sizeof(OSRegex), config_ruleinfo->fields[ifield]->regex);
+
+                        if (!OSRegex_Compile(rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex, 0)) {
+                            merror(REGEX_COMPILE, ARGV0, rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex->error);
+                            return -1;
+                        }
+
+                        ifield++;
+
+                    } else if (strcasecmp(rule_opt[k]->element, xml_list) == 0) {
+                        debug1("-> %s == %s", rule_opt[k]->element, xml_list);
+                        if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content) {
+                            int list_att_num = 0;
+                            int rule_type = 0;
+                            OSMatch *matcher = NULL;
                             int lookup_type = LR_STRING_MATCH;
-                            while(rule_opt[k]->attributes[list_att_num])
-                            {
-                                if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0)
-                                {
-                                    if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key) == 0)
+                            while (rule_opt[k]->attributes[list_att_num]) {
+                                if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0) {
+                                    if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key) == 0) {
                                         lookup_type = LR_STRING_MATCH;
-                                    else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_match_key)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_match_key) == 0) {
                                         lookup_type = LR_STRING_NOT_MATCH;
-                                    else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key_value)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key_value) == 0) {
                                         lookup_type = LR_STRING_MATCH_VALUE;
-                                    else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key) == 0) {
                                         lookup_type = LR_ADDRESS_MATCH;
-                                    else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_address_key)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_address_key) == 0) {
                                         lookup_type = LR_ADDRESS_NOT_MATCH;
-                                    else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key_value)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key_value) == 0) {
                                         lookup_type = LR_ADDRESS_MATCH_VALUE;
-                                    else
-                                    {
+                                    } else {
                                         merror(INVALID_CONFIG, ARGV0,
                                                rule_opt[k]->element,
                                                rule_opt[k]->content);
                                         merror("%s: List match lookup=\"%s\" is not valid.",
-                                                ARGV0,rule_opt[k]->values[list_att_num]);
-                                        return(-1);
-                                     }
-                                }
-                                else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field)==0)
-                                {
-                                    if(strcasecmp(rule_opt[k]->values[list_att_num],xml_srcip)==0)
+                                               ARGV0, rule_opt[k]->values[list_att_num]);
+                                        return (-1);
+                                    }
+                                } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field) == 0) {
+                                    if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcip) == 0) {
                                         rule_type = RULE_SRCIP;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_srcport)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcport) == 0) {
                                         rule_type = RULE_SRCPORT;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstip)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstip) == 0) {
                                         rule_type = RULE_DSTIP;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstport)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstport) == 0) {
                                         rule_type = RULE_DSTPORT;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_user)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_user) == 0) {
                                         rule_type = RULE_USER;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_url)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_url) == 0) {
                                         rule_type = RULE_URL;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_id)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_id) == 0) {
                                         rule_type = RULE_ID;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_hostname)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_hostname) == 0) {
                                         rule_type = RULE_HOSTNAME;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_program_name)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_program_name) == 0) {
                                         rule_type = RULE_PROGRAM_NAME;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_status)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_status) == 0) {
                                         rule_type = RULE_STATUS;
-                                    else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_action)==0)
+                                    } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_action) == 0) {
                                         rule_type = RULE_ACTION;
-                                    else
-                                    {
+                                    } else {
                                         merror(INVALID_CONFIG, ARGV0,
                                                rule_opt[k]->element,
                                                rule_opt[k]->content);
                                         merror("%s: List match field=\"%s\" is not valid.",
-                                                ARGV0,rule_opt[k]->values[list_att_num]);
-                                        return(-1);
-                                     }
-                                }
-                                else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue)==0)
-                                {
+                                               ARGV0, rule_opt[k]->values[list_att_num]);
+                                        return (-1);
+                                    }
+                                } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue) == 0) {
                                     os_calloc(1, sizeof(OSMatch), matcher);
-                                    if(!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0))
-                                    {
+                                    if (!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0)) {
                                         merror(INVALID_CONFIG, ARGV0,
                                                rule_opt[k]->element,
                                                rule_opt[k]->content);
@@ -753,720 +785,743 @@ int Rules_OP_ReadRules(char * rulefile)
                                                ARGV0,
                                                rule_opt[k]->values[list_att_num],
                                                matcher->error);
-                                        return(-1);
+                                        return (-1);
                                     }
-                                }
-                                else
-                                {
-                                       merror("%s:List feild=\"%s\" is not valid",ARGV0,
+                                } else {
+                                    merror("%s:List field=\"%s\" is not valid", ARGV0,
                                            rule_opt[k]->values[list_att_num]);
                                     merror(INVALID_CONFIG, ARGV0,
                                            rule_opt[k]->element, rule_opt[k]->content);
-                                    return(-1);
+                                    return (-1);
                                 }
                                 list_att_num++;
                             }
-                            if(rule_type == 0)
-                            {
-                                merror("%s:List requires the field=\"\" Attrubute",ARGV0);
+                            if (rule_type == 0) {
+                                merror("%s:List requires the field=\"\" Attrubute", ARGV0);
                                 merror(INVALID_CONFIG, ARGV0,
                                        rule_opt[k]->element, rule_opt[k]->content);
-                                return(-1);
+                                return (-1);
                             }
 
-                            /* Wow it's all ready - this seams too complex to get to this point */
+                            /* Wow it's all ready - this seems too complex to get to this point */
                             config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists,
-                                           lookup_type,
-                                           rule_type,
-                                           rule_opt[k]->content,
-                                           matcher);
-                            if (config_ruleinfo->lists == NULL)
-                            {
+                                                                    lookup_type,
+                                                                    rule_type,
+                                                                    rule_opt[k]->content,
+                                                                    matcher);
+                            if (config_ruleinfo->lists == NULL) {
                                 merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content);
-                                return(-1);
+                                return (-1);
                             }
-                        }
-                        else
-                        {
-                            merror("%s:List must have a correctly formatted feild attribute",
+                        } else {
+                            merror("%s:List must have a correctly formatted field attribute",
                                    ARGV0);
                             merror(INVALID_CONFIG,
                                    ARGV0,
                                    rule_opt[k]->element,
                                    rule_opt[k]->content);
-                            return(-1);
+                            return (-1);
                         }
                         /* xml_list eval is done */
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_url)==0)
-                    {
-                        url=
+                    } else if (strcasecmp(rule_opt[k]->element, xml_url) == 0) {
+                        url =
                             loadmemory(url,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element, xml_compiled)==0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_url_pcre2) == 0) {
+                        url_pcre2 =
+                            loadmemory(url_pcre2,
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_compiled) == 0) {
                         int it_id = 0;
 
-                        while(compiled_rules_name[it_id])
-                        {
-                            if(strcmp(compiled_rules_name[it_id],
-                                      rule_opt[k]->content) == 0)
+                        while (compiled_rules_name[it_id]) {
+                            if (strcmp(compiled_rules_name[it_id],
+                                       rule_opt[k]->content) == 0) {
                                 break;
+                            }
                             it_id++;
                         }
 
-                        /* checking if the name is valid. */
-                        if(!compiled_rules_name[it_id])
-                        {
+                        /* Checking if the name is valid */
+                        if (!compiled_rules_name[it_id]) {
                             merror("%s: ERROR: Compiled rule not found: '%s'",
                                    ARGV0, rule_opt[k]->content);
                             merror(INVALID_CONFIG, ARGV0,
                                    rule_opt[k]->element, rule_opt[k]->content);
-                            return(-1);
+                            return (-1);
 
                         }
 
-                        config_ruleinfo->compiled_rule = compiled_rules_list[it_id];
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        config_ruleinfo->compiled_rule = (void *(*)(void *)) compiled_rules_list[it_id];
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
+                        }
                     }
 
-                    /* We allow these four categories so far */
-                    else if(strcasecmp(rule_opt[k]->element, xml_category)==0)
-                    {
-                        if(strcmp(rule_opt[k]->content, "firewall") == 0)
-                        {
+                    else if (strcasecmp(rule_opt[k]->element, xml_category) == 0) {
+                        if (strcmp(rule_opt[k]->content, "firewall") == 0) {
                             config_ruleinfo->category = FIREWALL;
-                        }
-                        else if(strcmp(rule_opt[k]->content, "ids") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "ids") == 0) {
                             config_ruleinfo->category = IDS;
-                        }
-                        else if(strcmp(rule_opt[k]->content, "syslog") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "syslog") == 0) {
                             config_ruleinfo->category = SYSLOG;
-                        }
-                        else if(strcmp(rule_opt[k]->content, "web-log") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "web-log") == 0) {
                             config_ruleinfo->category = WEBLOG;
-                        }
-                        else if(strcmp(rule_opt[k]->content, "squid") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "squid") == 0) {
                             config_ruleinfo->category = SQUID;
-                        }
-                        else if(strcmp(rule_opt[k]->content,"windows") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "windows") == 0) {
                             config_ruleinfo->category = DECODER_WINDOWS;
-                        }
-                        else if(strcmp(rule_opt[k]->content,"ossec") == 0)
-                        {
+                        } else if (strcmp(rule_opt[k]->content, "ossec") == 0) {
                             config_ruleinfo->category = OSSEC_RL;
-                        }
-                        else
-                        {
+                        } else {
                             merror(INVALID_CAT, ARGV0, rule_opt[k]->content);
-                            return(-1);
+                            return (-1);
                         }
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_if_sid)==0)
-                    {
-                        config_ruleinfo->if_sid=
+                    } else if (strcasecmp(rule_opt[k]->element, xml_if_sid) == 0) {
+                        config_ruleinfo->if_sid =
                             loadmemory(config_ruleinfo->if_sid,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_if_level)==0)
-                    {
-                        if(!OS_StrIsNum(rule_opt[k]->content))
-                        {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_if_level) == 0) {
+                        if (!OS_StrIsNum(rule_opt[k]->content)) {
                             merror(INVALID_CONFIG, ARGV0,
-                                    "if_level",
-                                    rule_opt[k]->content);
-                            return(-1);
+                                   "if_level",
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
 
-                        config_ruleinfo->if_level=
+                        config_ruleinfo->if_level =
                             loadmemory(config_ruleinfo->if_level,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,xml_if_group)==0)
-                    {
-                        config_ruleinfo->if_group=
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element, xml_if_group) == 0) {
+                        config_ruleinfo->if_group =
                             loadmemory(config_ruleinfo->if_group,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                       xml_if_matched_regex) == 0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_if_matched_regex) == 0) {
                         config_ruleinfo->context = 1;
-                        if_matched_regex=
+                        if_matched_regex =
                             loadmemory(if_matched_regex,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                       xml_if_matched_group) == 0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_if_matched_group) == 0) {
                         config_ruleinfo->context = 1;
-                        if_matched_group=
+                        if_matched_group =
                             loadmemory(if_matched_group,
-                                    rule_opt[k]->content);
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                       xml_if_matched_sid) == 0)
-                    {
+                                       rule_opt[k]->content);
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_if_matched_sid) == 0) {
                         config_ruleinfo->context = 1;
-                        if(!OS_StrIsNum(rule_opt[k]->content))
-                        {
+                        if (!OS_StrIsNum(rule_opt[k]->content)) {
                             merror(INVALID_CONFIG, ARGV0,
-                                    "if_matched_sid",
-                                    rule_opt[k]->content);
-                            return(-1);
+                                   "if_matched_sid",
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
                         config_ruleinfo->if_matched_sid =
                             atoi(rule_opt[k]->content);
 
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_same_source_ip)==0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_SRCIP;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_same_src_port)==0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_SRCPORT;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_same_source_ip) == 0) {
+                        config_ruleinfo->context_opts |= SAME_SRCIP;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_same_src_port) == 0) {
+                        config_ruleinfo->context_opts |= SAME_SRCPORT;
 
-                        if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                               xml_dodiff)==0)
-                    {
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_dodiff) == 0) {
                         config_ruleinfo->context = 1;
-                        config_ruleinfo->context_opts|= SAME_DODIFF;
-                        if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO))
+                        config_ruleinfo->context_opts |= SAME_DODIFF;
+                        if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= DO_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_same_dst_port) == 0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_DSTPORT;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_same_dst_port) == 0) {
+                        config_ruleinfo->context_opts |= SAME_DSTPORT;
+
+                        if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_notsame_source_ip) == 0) {
+                        config_ruleinfo->context_opts &= NOT_SAME_SRCIP;
+                    } else if (strcmp(rule_opt[k]->element, xml_same_id) == 0) {
+                        config_ruleinfo->context_opts |= SAME_ID;
+                    } else if (strcmp(rule_opt[k]->element,
+                                      xml_different_url) == 0) {
+                        config_ruleinfo->context_opts |= DIFFERENT_URL;
+
+                        if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) {
+                            config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
+                        }
+                    } else if(strcmp(rule_opt[k]->element,
+                                   xml_different_srcip) == 0) {
+                        config_ruleinfo->context_opts|= DIFFERENT_SRCIP;
 
                         if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
                             config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_notsame_source_ip)==0)
-                    {
-                        config_ruleinfo->context_opts&= NOT_SAME_SRCIP;
-                    }
-                    else if(strcmp(rule_opt[k]->element, xml_same_id) == 0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_ID;
-                    }
-                    else if(strcmp(rule_opt[k]->element,
-                                   xml_different_url) == 0)
-                    {
-                        config_ruleinfo->context_opts|= DIFFERENT_URL;
+                    } else if(strcmp(rule_opt[k]->element,
+                                   xml_different_srcgeoip) == 0) {
+                        config_ruleinfo->context_opts|= DIFFERENT_SRCGEOIP;
 
                         if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
                             config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
-                    }
-                    else if(strcmp(rule_opt[k]->element,xml_notsame_id) == 0)
-                    {
-                        config_ruleinfo->context_opts&= NOT_SAME_ID;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_fts) == 0)
-                    {
+                    } else if (strcmp(rule_opt[k]->element, xml_notsame_id) == 0) {
+                        config_ruleinfo->context_opts &= NOT_SAME_ID;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_fts) == 0) {
                         config_ruleinfo->alert_opts |= DO_FTS;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_same_user)==0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_USER;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_same_user) == 0) {
+                        config_ruleinfo->context_opts |= SAME_USER;
 
-                        if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
+                        if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_notsame_user)==0)
-                    {
-                        config_ruleinfo->context_opts&= NOT_SAME_USER;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_same_location)==0)
-                    {
-                        config_ruleinfo->context_opts|= SAME_LOCATION;
-                        if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO))
+                        }
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_notsame_user) == 0) {
+                        config_ruleinfo->context_opts &= NOT_SAME_USER;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_same_location) == 0) {
+                        config_ruleinfo->context_opts |= SAME_LOCATION;
+                        if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) {
                             config_ruleinfo->alert_opts |= SAME_EXTRAINFO;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_notsame_agent)==0)
-                    {
-                        config_ruleinfo->context_opts&= NOT_SAME_AGENT;
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_options) == 0)
-                    {
-                        if(strcmp("alert_by_email",
-                                  rule_opt[k]->content) == 0)
-                        {
-                            if(!(config_ruleinfo->alert_opts & DO_MAILALERT))
-                            {
-                                config_ruleinfo->alert_opts|= DO_MAILALERT;
-                            }
                         }
-                        else if(strcmp("no_email_alert",
-                                       rule_opt[k]->content) == 0)
-                        {
-                            if(config_ruleinfo->alert_opts & DO_MAILALERT)
-                            {
-                              config_ruleinfo->alert_opts&=0xfff-DO_MAILALERT;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_notsame_agent) == 0) {
+                        config_ruleinfo->context_opts &= NOT_SAME_AGENT;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_options) == 0) {
+                        if (strcmp("alert_by_email",
+                                   rule_opt[k]->content) == 0) {
+                            if (!(config_ruleinfo->alert_opts & DO_MAILALERT)) {
+                                config_ruleinfo->alert_opts |= DO_MAILALERT;
                             }
-                        }
-                        else if(strcmp("log_alert",
-                                       rule_opt[k]->content) == 0)
-                        {
-                            if(!(config_ruleinfo->alert_opts & DO_LOGALERT))
-                            {
-                                config_ruleinfo->alert_opts|= DO_LOGALERT;
+                        } else if (strcmp("no_email_alert",
+                                          rule_opt[k]->content) == 0) {
+                            if (config_ruleinfo->alert_opts & DO_MAILALERT) {
+                                config_ruleinfo->alert_opts &= 0xfff - DO_MAILALERT;
                             }
-                        }
-                        else if(strcmp("no_log", rule_opt[k]->content) == 0)
-                        {
-                            if(config_ruleinfo->alert_opts & DO_LOGALERT)
-                            {
-                              config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT;
+                        } else if (strcmp("log_alert",
+                                          rule_opt[k]->content) == 0) {
+                            if (!(config_ruleinfo->alert_opts & DO_LOGALERT)) {
+                                config_ruleinfo->alert_opts |= DO_LOGALERT;
                             }
-                        }
-                        else if(strcmp("no_ar", rule_opt[k]->content) == 0)
-                        {
-                            if(!(config_ruleinfo->alert_opts & NO_AR))
-                            {
-                                config_ruleinfo->alert_opts|= NO_AR;
+                        } else if (strcmp("no_log", rule_opt[k]->content) == 0) {
+                            if (config_ruleinfo->alert_opts & DO_LOGALERT) {
+                                config_ruleinfo->alert_opts &= 0xfff - DO_LOGALERT;
                             }
-                        }
-                        else
-                        {
+                        } else if (strcmp("no_ar", rule_opt[k]->content) == 0) {
+                            if (!(config_ruleinfo->alert_opts & NO_AR)) {
+                                config_ruleinfo->alert_opts |= NO_AR;
+                            }
+                        } else {
                             merror(XML_VALUEERR, ARGV0, xml_options,
-                                                        rule_opt[k]->content);
+                                   rule_opt[k]->content);
 
                             merror("%s: Invalid option '%s' for "
-                                   "rule '%d'.",ARGV0, rule_opt[k]->element,
+                                   "rule '%d'.", ARGV0, rule_opt[k]->element,
                                    config_ruleinfo->sigid);
                             OS_ClearXML(&xml);
-                            return(-1);
+                            return (-1);
                         }
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_ignore) == 0)
-                    {
-                        if(strstr(rule_opt[k]->content, "user") != NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_DSTUSER;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_ignore) == 0) {
+                        if (strstr(rule_opt[k]->content, "user") != NULL) {
+                            config_ruleinfo->ignore |= FTS_DSTUSER;
                         }
-                        if(strstr(rule_opt[k]->content, "srcip") != NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_SRCIP;
+                        if (strstr(rule_opt[k]->content, "srcip") != NULL) {
+                            config_ruleinfo->ignore |= FTS_SRCIP;
                         }
-                        if(strstr(rule_opt[k]->content, "dstip") != NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_DSTIP;
+                        if (strstr(rule_opt[k]->content, "dstip") != NULL) {
+                            config_ruleinfo->ignore |= FTS_DSTIP;
                         }
-                        if(strstr(rule_opt[k]->content, "id") != NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_ID;
+                        if (strstr(rule_opt[k]->content, "id") != NULL) {
+                            config_ruleinfo->ignore |= FTS_ID;
                         }
-                        if(strstr(rule_opt[k]->content,"location")!= NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_LOCATION;
+                        if (strstr(rule_opt[k]->content, "location") != NULL) {
+                            config_ruleinfo->ignore |= FTS_LOCATION;
                         }
-                        if(strstr(rule_opt[k]->content,"data")!= NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_DATA;
+                        if (strstr(rule_opt[k]->content, "data") != NULL) {
+                            config_ruleinfo->ignore |= FTS_DATA;
                         }
-                        if(strstr(rule_opt[k]->content, "name") != NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_NAME;
+                        if (strstr(rule_opt[k]->content, "name") != NULL) {
+                            config_ruleinfo->ignore |= FTS_NAME;
 
                         }
-                        if(!config_ruleinfo->ignore)
-                        {
+                        if (!config_ruleinfo->ignore) {
                             merror("%s: Wrong ignore option: '%s'",
-                                                    ARGV0,
-                                                    rule_opt[k]->content);
-                            return(-1);
+                                   ARGV0,
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
-                    }
-                    else if(strcasecmp(rule_opt[k]->element,
-                                xml_check_if_ignored) == 0)
-                    {
-                        if(strstr(rule_opt[k]->content, "user") != NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_DSTUSER;
+                    } else if (strcasecmp(rule_opt[k]->element,
+                                          xml_check_if_ignored) == 0) {
+                        if (strstr(rule_opt[k]->content, "user") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_DSTUSER;
                         }
-                        if(strstr(rule_opt[k]->content, "srcip") != NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_SRCIP;
+                        if (strstr(rule_opt[k]->content, "srcip") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_SRCIP;
                         }
-                        if(strstr(rule_opt[k]->content, "dstip") != NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_DSTIP;
+                        if (strstr(rule_opt[k]->content, "dstip") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_DSTIP;
                         }
-                        if(strstr(rule_opt[k]->content, "id") != NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_ID;
+                        if (strstr(rule_opt[k]->content, "id") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_ID;
                         }
-                        if(strstr(rule_opt[k]->content,"location")!= NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_LOCATION;
+                        if (strstr(rule_opt[k]->content, "location") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_LOCATION;
                         }
-                        if(strstr(rule_opt[k]->content,"data")!= NULL)
-                        {
-                            config_ruleinfo->ignore|=FTS_DATA;
+                        if (strstr(rule_opt[k]->content, "data") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_DATA;
                         }
-                        if(strstr(rule_opt[k]->content, "name") != NULL)
-                        {
-                            config_ruleinfo->ckignore|=FTS_NAME;
+                        if (strstr(rule_opt[k]->content, "name") != NULL) {
+                            config_ruleinfo->ckignore |= FTS_NAME;
 
                         }
-                        if(!config_ruleinfo->ckignore)
-                        {
+                        if (!config_ruleinfo->ckignore) {
                             merror("%s: Wrong check_if_ignored option: '%s'",
-                                                    ARGV0,
-                                                    rule_opt[k]->content);
-                            return(-1);
+                                   ARGV0,
+                                   rule_opt[k]->content);
+                            return (-1);
                         }
-                    }
-                    else
-                    {
+                    } else {
                         merror("%s: Invalid option '%s' for "
-                                "rule '%d'.",ARGV0, rule_opt[k]->element,
-                                config_ruleinfo->sigid);
+                               "rule '%d'.", ARGV0, rule_opt[k]->element,
+                               config_ruleinfo->sigid);
                         OS_ClearXML(&xml);
-                        return(-1);
+                        return (-1);
                     }
                     k++;
                 }
 
-
-                /* Checking for a valid use of frequency */
-                if((config_ruleinfo->context_opts ||
-                   config_ruleinfo->frequency) &&
-                   !config_ruleinfo->context)
-                {
+                /* Check for valid use of frequency */
+                if ((config_ruleinfo->context_opts ||
+                        config_ruleinfo->frequency) &&
+                        !config_ruleinfo->context) {
                     merror("%s: Invalid use of frequency/context options. "
                            "Missing if_matched on rule '%d'.",
                            ARGV0, config_ruleinfo->sigid);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
 
-
                 /* If if_matched_group we must have a if_sid or if_group */
-                if(if_matched_group)
-                {
-                    if(!config_ruleinfo->if_sid && !config_ruleinfo->if_group)
-                    {
+                if (if_matched_group) {
+                    if (!config_ruleinfo->if_sid && !config_ruleinfo->if_group) {
                         os_strdup(if_matched_group,
                                   config_ruleinfo->if_group);
                     }
                 }
 
                 /* If_matched_sid, we need to get the if_sid */
-                if(config_ruleinfo->if_matched_sid &&
-                   !config_ruleinfo->if_sid &&
-                   !config_ruleinfo->if_group)
-                {
+                if (config_ruleinfo->if_matched_sid &&
+                        !config_ruleinfo->if_sid &&
+                        !config_ruleinfo->if_group) {
                     os_calloc(16, sizeof(char), config_ruleinfo->if_sid);
                     snprintf(config_ruleinfo->if_sid, 15, "%d",
                              config_ruleinfo->if_matched_sid);
                 }
 
-                /* Checking the regexes */
-                if(regex)
-                {
+                /* Check the regexes */
+                if (regex) {
                     os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex);
-                    if(!OSRegex_Compile(regex, config_ruleinfo->regex, 0))
-                    {
+                    if (!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) {
                         merror(REGEX_COMPILE, ARGV0, regex,
-                                config_ruleinfo->regex->error);
-                        return(-1);
+                               config_ruleinfo->regex->error);
+                        return (-1);
                     }
                     free(regex);
                     regex = NULL;
                 }
 
-                /* Adding in match */
-                if(match)
-                {
+                if (pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->pcre2);
+                    if (!OSPcre2_Compile(pcre2, config_ruleinfo->pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, pcre2,
+                               config_ruleinfo->pcre2->error);
+                        return (-1);
+                    }
+                    free(pcre2);
+                    pcre2 = NULL;
+                }
+
+                /* Add in match */
+                if (match) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->match);
-                    if(!OSMatch_Compile(match, config_ruleinfo->match, 0))
-                    {
+                    if (!OSMatch_Compile(match, config_ruleinfo->match, 0)) {
                         merror(REGEX_COMPILE, ARGV0, match,
-                                config_ruleinfo->match->error);
-                        return(-1);
+                               config_ruleinfo->match->error);
+                        return (-1);
                     }
                     free(match);
                     match = NULL;
                 }
+                else if (match_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->match_pcre2);
+                    if (!OSPcre2_Compile(match_pcre2, config_ruleinfo->match_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, match_pcre2,
+                               config_ruleinfo->match_pcre2->error);
+                        return (-1);
+                    }
+                    free(match_pcre2);
+                    match_pcre2 = NULL;
+                }
 
-                /* Adding in id */
-                if(id)
-                {
+                /* Add in id */
+                if (id) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->id);
-                    if(!OSMatch_Compile(id, config_ruleinfo->id, 0))
-                    {
+                    if (!OSMatch_Compile(id, config_ruleinfo->id, 0)) {
                         merror(REGEX_COMPILE, ARGV0, id,
-                                              config_ruleinfo->id->error);
-                        return(-1);
+                               config_ruleinfo->id->error);
+                        return (-1);
                     }
                     free(id);
                     id = NULL;
                 }
+                if (id_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->id_pcre2);
+                    if (!OSPcre2_Compile(id_pcre2, config_ruleinfo->id_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, id,
+                               config_ruleinfo->id_pcre2->error);
+                        return (-1);
+                    }
+                    free(id_pcre2);
+                    id_pcre2 = NULL;
+                }
 
-                /* Adding srcport */
-                if(srcport)
-                {
+                /* Add srcport */
+                if (srcport) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport);
-                    if(!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0))
-                    {
+                    if (!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) {
                         merror(REGEX_COMPILE, ARGV0, srcport,
-                                              config_ruleinfo->id->error);
-                        return(-1);
+                               config_ruleinfo->id->error);
+                        return (-1);
                     }
                     free(srcport);
                     srcport = NULL;
                 }
+                if (srcport_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcport_pcre2);
+                    if (!OSPcre2_Compile(srcport_pcre2, config_ruleinfo->srcport_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, srcport_pcre2,
+                               config_ruleinfo->id->error);
+                        return (-1);
+                    }
+                    free(srcport_pcre2);
+                    srcport_pcre2 = NULL;
+                }
 
-                /* Adding dstport */
-                if(dstport)
-                {
+                /* Add dstport */
+                if (dstport) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport);
-                    if(!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0))
-                    {
+                    if (!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) {
                         merror(REGEX_COMPILE, ARGV0, dstport,
-                                              config_ruleinfo->id->error);
-                        return(-1);
+                               config_ruleinfo->id->error);
+                        return (-1);
                     }
                     free(dstport);
                     dstport = NULL;
                 }
+                else if (dstport_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstport_pcre2);
+                    if (!OSPcre2_Compile(dstport_pcre2, config_ruleinfo->dstport_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, dstport_pcre2,
+                               config_ruleinfo->id->error);
+                        return (-1);
+                    }
+                    free(dstport_pcre2);
+                    dstport_pcre2 = NULL;
+                }
 
-                /* Adding in status */
-                if(status)
-                {
+                /* Add in status */
+                if (status) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->status);
-                    if(!OSMatch_Compile(status, config_ruleinfo->status, 0))
-                    {
+                    if (!OSMatch_Compile(status, config_ruleinfo->status, 0)) {
                         merror(REGEX_COMPILE, ARGV0, status,
-                                              config_ruleinfo->status->error);
-                        return(-1);
+                               config_ruleinfo->status->error);
+                        return (-1);
                     }
                     free(status);
                     status = NULL;
                 }
+                else if (status_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->status_pcre2);
+                    if (!OSPcre2_Compile(status_pcre2, config_ruleinfo->status_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, status_pcre2,
+                               config_ruleinfo->status_pcre2->error);
+                        return (-1);
+                    }
+                    free(status_pcre2);
+                    status_pcre2 = NULL;
+                }
 
-                /* Adding in hostname */
-                if(hostname)
-                {
+                /* Add in hostname */
+                if (hostname) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname);
-                    if(!OSMatch_Compile(hostname, config_ruleinfo->hostname,0))
-                    {
+                    if (!OSMatch_Compile(hostname, config_ruleinfo->hostname, 0)) {
                         merror(REGEX_COMPILE, ARGV0, hostname,
-                                config_ruleinfo->hostname->error);
-                        return(-1);
+                               config_ruleinfo->hostname->error);
+                        return (-1);
                     }
                     free(hostname);
                     hostname = NULL;
                 }
+                else if (hostname_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->hostname_pcre2);
+                    if (!OSPcre2_Compile(hostname_pcre2, config_ruleinfo->hostname_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, hostname_pcre2,
+                               config_ruleinfo->hostname_pcre2->error);
+                        return (-1);
+                    }
+                    free(hostname_pcre2);
+                    hostname_pcre2 = NULL;
+                }
 
-                /* Adding extra data */
-                if(extra_data)
-                {
+                /* Add extra data */
+                if (extra_data) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data);
-                    if(!OSMatch_Compile(extra_data,
-                                        config_ruleinfo->extra_data, 0))
-                    {
+                    if (!OSMatch_Compile(extra_data,
+                                         config_ruleinfo->extra_data, 0)) {
                         merror(REGEX_COMPILE, ARGV0, extra_data,
-                                config_ruleinfo->extra_data->error);
-                        return(-1);
+                               config_ruleinfo->extra_data->error);
+                        return (-1);
                     }
                     free(extra_data);
                     extra_data = NULL;
                 }
+                else if (extra_data_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->extra_data_pcre2);
+                    if (!OSPcre2_Compile(extra_data_pcre2,
+                                         config_ruleinfo->extra_data_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, extra_data_pcre2,
+                               config_ruleinfo->extra_data_pcre2->error);
+                        return (-1);
+                    }
+                    free(extra_data_pcre2);
+                    extra_data_pcre2 = NULL;
+                }
 
-                /* Adding in program name */
-                if(program_name)
-                {
-                    os_calloc(1,sizeof(OSMatch),config_ruleinfo->program_name);
-                    if(!OSMatch_Compile(program_name,
-                                        config_ruleinfo->program_name,0))
-                    {
+                /* Add in program name */
+                if (program_name) {
+                    os_calloc(1, sizeof(OSMatch), config_ruleinfo->program_name);
+                    if (!OSMatch_Compile(program_name,
+                                         config_ruleinfo->program_name, 0)) {
                         merror(REGEX_COMPILE, ARGV0, program_name,
-                                config_ruleinfo->program_name->error);
-                        return(-1);
+                               config_ruleinfo->program_name->error);
+                        return (-1);
                     }
                     free(program_name);
                     program_name = NULL;
                 }
+                else if (program_name_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->program_name_pcre2);
+                    if (!OSPcre2_Compile(program_name_pcre2,
+                                         config_ruleinfo->program_name_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, program_name_pcre2,
+                               config_ruleinfo->program_name_pcre2->error);
+                        return (-1);
+                    }
+                    free(program_name_pcre2);
+                    program_name_pcre2 = NULL;
+                }
 
-                /* Adding in user */
-                if(user)
-                {
+                /* Add in user */
+                if (user) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->user);
-                    if(!OSMatch_Compile(user, config_ruleinfo->user, 0))
-                    {
+                    if (!OSMatch_Compile(user, config_ruleinfo->user, 0)) {
                         merror(REGEX_COMPILE, ARGV0, user,
-                                              config_ruleinfo->user->error);
-                        return(-1);
+                               config_ruleinfo->user->error);
+                        return (-1);
                     }
                     free(user);
                     user = NULL;
                 }
+                else if (user_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->user_pcre2);
+                    if (!OSPcre2_Compile(user_pcre2, config_ruleinfo->user_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, user_pcre2,
+                               config_ruleinfo->user_pcre2->error);
+                        return (-1);
+                    }
+                    free(user_pcre2);
+                    user_pcre2 = NULL;
+                }
+
+                /* Adding in srcgeoip */
+                if(srcgeoip) {
+                    os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcgeoip);
+                    if(!OSMatch_Compile(srcgeoip, config_ruleinfo->srcgeoip, 0)) {
+                        merror(REGEX_COMPILE, ARGV0, srcgeoip,
+                                              config_ruleinfo->srcgeoip->error);
+                        return(-1);
+                    }
+                    free(srcgeoip);
+                    srcgeoip = NULL;
+                }
+                else if(srcgeoip_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcgeoip_pcre2);
+                    if(!OSPcre2_Compile(srcgeoip_pcre2, config_ruleinfo->srcgeoip_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, srcgeoip_pcre2,
+                                              config_ruleinfo->srcgeoip_pcre2->error);
+                        return(-1);
+                    }
+                    free(srcgeoip_pcre2);
+                    srcgeoip_pcre2 = NULL;
+                }
+
+
+                /* Adding in dstgeoip */
+                if(dstgeoip) {
+                    os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstgeoip);
+                    if(!OSMatch_Compile(dstgeoip, config_ruleinfo->dstgeoip, 0)) {
+                        merror(REGEX_COMPILE, ARGV0, dstgeoip,
+                                              config_ruleinfo->dstgeoip->error);
+                        return(-1);
+                    }
+                    free(dstgeoip);
+                    dstgeoip = NULL;
+                }
+                else if(dstgeoip_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstgeoip_pcre2);
+                    if(!OSPcre2_Compile(dstgeoip_pcre2, config_ruleinfo->dstgeoip_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, dstgeoip_pcre2,
+                                              config_ruleinfo->dstgeoip_pcre2->error);
+                        return(-1);
+                    }
+                    free(dstgeoip_pcre2);
+                    dstgeoip_pcre2 = NULL;
+                }
+
 
-                /* Adding in url */
-                if(url)
-                {
+                /* Add in URL */
+                if (url) {
                     os_calloc(1, sizeof(OSMatch), config_ruleinfo->url);
-                    if(!OSMatch_Compile(url, config_ruleinfo->url, 0))
-                    {
+                    if (!OSMatch_Compile(url, config_ruleinfo->url, 0)) {
                         merror(REGEX_COMPILE, ARGV0, url,
-                                config_ruleinfo->url->error);
-                        return(-1);
+                               config_ruleinfo->url->error);
+                        return (-1);
                     }
                     free(url);
                     url = NULL;
                 }
+                else if (url_pcre2) {
+                    os_calloc(1, sizeof(OSPcre2), config_ruleinfo->url_pcre2);
+                    if (!OSPcre2_Compile(url_pcre2, config_ruleinfo->url_pcre2, PCRE2_CASELESS)) {
+                        merror(REGEX_COMPILE, ARGV0, url_pcre2,
+                               config_ruleinfo->url_pcre2->error);
+                        return (-1);
+                    }
+                    free(url_pcre2);
+                    url_pcre2 = NULL;
+                }
 
-                /* Adding matched_group */
-                if(if_matched_group)
-                {
+                /* Add matched_group */
+                if (if_matched_group) {
                     os_calloc(1, sizeof(OSMatch),
-                                 config_ruleinfo->if_matched_group);
+                              config_ruleinfo->if_matched_group);
 
-                    if(!OSMatch_Compile(if_matched_group,
-                                        config_ruleinfo->if_matched_group,
-                                        0))
-                    {
+                    if (!OSMatch_Compile(if_matched_group,
+                                         config_ruleinfo->if_matched_group,
+                                         0)) {
                         merror(REGEX_COMPILE, ARGV0, if_matched_group,
-                                config_ruleinfo->if_matched_group->error);
-                        return(-1);
+                               config_ruleinfo->if_matched_group->error);
+                        return (-1);
                     }
                     free(if_matched_group);
                     if_matched_group = NULL;
                 }
 
-                /* Adding matched_regex */
-                if(if_matched_regex)
-                {
+                /* Add matched_regex */
+                if (if_matched_regex) {
                     os_calloc(1, sizeof(OSRegex),
-                            config_ruleinfo->if_matched_regex);
-                    if(!OSRegex_Compile(if_matched_regex,
-                                config_ruleinfo->if_matched_regex, 0))
-                    {
+                              config_ruleinfo->if_matched_regex);
+                    if (!OSRegex_Compile(if_matched_regex,
+                                         config_ruleinfo->if_matched_regex, 0)) {
                         merror(REGEX_COMPILE, ARGV0, if_matched_regex,
-                                config_ruleinfo->if_matched_regex->error);
-                        return(-1);
+                               config_ruleinfo->if_matched_regex->error);
+                        return (-1);
                     }
                     free(if_matched_regex);
                     if_matched_regex = NULL;
                 }
-            } /* enf of elements block */
-
+                OS_ClearNode(rule_opt);
+            } /* end of elements block */
 
-            /* Assigning an active response to the rule */
+            /* Assign an active response to the rule */
             Rule_AddAR(config_ruleinfo);
 
             j++; /* next rule */
 
-
-            /* Creating the last_events if necessary */
-            if(config_ruleinfo->context)
-            {
+            /* Create the last_events if necessary */
+            if (config_ruleinfo->context) {
                 int ii = 0;
                 os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *),
                           config_ruleinfo->last_events);
 
-                /* Zeroing each entry */
-                for(;ii<=MAX_LAST_EVENTS;ii++)
-                {
+                /* Zero each entry */
+                for (; ii <= MAX_LAST_EVENTS; ii++) {
                     config_ruleinfo->last_events[ii] = NULL;
                 }
             }
 
-
-            /* Adding the rule to the rules list.
+            /* Add the rule to the rules list.
              * Only the template rules are supposed
              * to be at the top level. All others
              * will be a "child" of someone.
              */
-            if(config_ruleinfo->sigid < 10)
-            {
+            if (config_ruleinfo->sigid < 10) {
                 OS_AddRule(config_ruleinfo);
-            }
-            else if(config_ruleinfo->alert_opts & DO_OVERWRITE)
-            {
-                if(!OS_AddRuleInfo(NULL, config_ruleinfo,
-                                   config_ruleinfo->sigid))
-                {
+            } else if (config_ruleinfo->alert_opts & DO_OVERWRITE) {
+                if (!OS_AddRuleInfo(NULL, config_ruleinfo,
+                                    config_ruleinfo->sigid)) {
                     merror("%s: Overwrite rule '%d' not found.",
-                            ARGV0, config_ruleinfo->sigid);
+                           ARGV0, config_ruleinfo->sigid);
                     OS_ClearXML(&xml);
-                    return(-1);
+                    return (-1);
                 }
-            }
-            else
-            {
+            } else {
                 OS_AddChild(config_ruleinfo);
             }
 
-            /* Cleaning what we do not need */
-            if(config_ruleinfo->if_group)
-            {
+            /* Clean what we do not need */
+            if (config_ruleinfo->if_group) {
                 free(config_ruleinfo->if_group);
                 config_ruleinfo->if_group = NULL;
             }
 
-            /* Setting the event_search pointer */
-            if(config_ruleinfo->if_matched_sid)
-            {
-                config_ruleinfo->event_search =
-                                 (void *)Search_LastSids;
+            /* Set the event_search pointer */
+            if (config_ruleinfo->if_matched_sid) {
+                config_ruleinfo->event_search = (void *(*)(void *, void *))
+                    Search_LastSids;
 
-                /* Marking rules that match this id */
+                /* Mark rules that match this id */
                 OS_MarkID(NULL, config_ruleinfo);
             }
 
-            /* Marking the rules that match if_matched_group */
-            else if(config_ruleinfo->if_matched_group)
-            {
-                /* Creating list */
+            /* Mark the rules that match if_matched_group */
+            else if (config_ruleinfo->if_matched_group) {
+                /* Create list */
                 config_ruleinfo->group_search = OSList_Create();
-                if(!config_ruleinfo->group_search)
-                {
-                    ErrorExit(MEM_ERROR, ARGV0);
+                if (!config_ruleinfo->group_search) {
+                    ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
                 }
 
-                /* Marking rules that match this group */
+                /* Mark rules that match this group */
                 OS_MarkGroup(NULL, config_ruleinfo);
 
-                /* Setting function pointer */
-                config_ruleinfo->event_search =
-                                 (void *)Search_LastGroups;
-            }
-            else if(config_ruleinfo->context)
-            {
-                if((config_ruleinfo->context == 1) &&
-                   (config_ruleinfo->context_opts & SAME_DODIFF))
-                {
+                /* Set function pointer */
+                config_ruleinfo->event_search = (void *(*)(void *, void *))
+                    Search_LastGroups;
+            } else if (config_ruleinfo->context) {
+                if ((config_ruleinfo->context == 1) &&
+                        (config_ruleinfo->context_opts & SAME_DODIFF)) {
                     config_ruleinfo->context = 0;
-                }
-                else
-                {
-                    config_ruleinfo->event_search =
-                                 (void *)Search_LastEvents;
+                } else {
+                    config_ruleinfo->event_search = (void *(*)(void *, void *))
+                        Search_LastEvents;
                 }
             }
 
@@ -1476,116 +1531,94 @@ int Rules_OP_ReadRules(char * rulefile)
 
     } /* while (node[i]) */
 
-    /* Cleaning global node */
+    /* Clean global node */
     OS_ClearNode(node);
     OS_ClearXML(&xml);
 
-    #ifdef DEBUG
+#ifdef DEBUG
     {
         RuleNode *dbg_node = OS_GetFirstRule();
-        while(dbg_node)
-        {
-            if(dbg_node->child)
-            {
+        while (dbg_node) {
+            if (dbg_node->child) {
                 RuleNode *child_node = dbg_node->child;
 
-                printf("** Child Node for %d **\n",dbg_node->ruleinfo->sigid);
-                while(child_node)
-                {
+                printf("** Child Node for %d **\n", dbg_node->ruleinfo->sigid);
+                while (child_node) {
                     child_node = child_node->next;
                 }
             }
             dbg_node = dbg_node->next;
         }
     }
-    #endif
+#endif
 
     /* Done over here */
-    return(0);
+    return (0);
 }
 
-
-/* loadmemory: v0.1
- * Allocate memory at "*at" and copy *str to it.
- * If *at already exist, realloc the memory and cat str
- * on it.
- * It will return the new string
+/* Allocate memory at "*at" and copy *str to it.
+ * If *at already exist, realloc the memory and cat str on it.
+ * Returns the new string
  */
-char *loadmemory(char *at, char *str)
+static char *loadmemory(char *at, const char *str)
 {
-    if(at == NULL)
-    {
-        int strsize = 0;
-        if((strsize = strlen(str)) < OS_SIZE_2048)
-        {
-            at = calloc(strsize+1,sizeof(char));
-            if(at == NULL)
-            {
-                merror(MEM_ERROR,ARGV0);
-                return(NULL);
+    if (at == NULL) {
+        size_t strsize = 0;
+        if ((strsize = strlen(str)) < OS_SIZE_2048) {
+            at = (char *) calloc(strsize + 1, sizeof(char));
+            if (at == NULL) {
+                merror(MEM_ERROR, ARGV0, errno, strerror(errno));
+                return (NULL);
             }
-            strncpy(at,str,strsize);
-            return(at);
-        }
-        else
-        {
-            merror(SIZE_ERROR,ARGV0,str);
-            return(NULL);
+            strncpy(at, str, strsize);
+            return (at);
+        } else {
+            merror(SIZE_ERROR, ARGV0, str);
+            return (NULL);
         }
-    }
-    else /*at is not null. Need to reallocat its memory and copy str to it*/
-    {
-        int strsize = strlen(str);
-        int atsize = strlen(at);
-        int finalsize = atsize+strsize+1;
-
-        if((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048))
-        {
-            merror(SIZE_ERROR,ARGV0,str);
-            return(NULL);
+    } else {
+        /* at is not null. Need to reallocate its memory and copy str to it */
+        size_t strsize = strlen(str);
+        size_t atsize = strlen(at);
+        size_t finalsize = atsize + strsize + 1;
+
+        if ((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048)) {
+            merror(SIZE_ERROR, ARGV0, str);
+            return (NULL);
         }
 
-        at = realloc(at, (finalsize)*sizeof(char));
+        at = (char *) realloc(at, (finalsize) * sizeof(char));
 
-        if(at == NULL)
-        {
-            merror(MEM_ERROR,ARGV0);
-            return(NULL);
+        if (at == NULL) {
+            merror(MEM_ERROR, ARGV0, errno, strerror(errno));
+            return (NULL);
         }
 
-        strncat(at,str,strsize);
-
-        at[finalsize-1]='\0';
+        strncat(at, str, strsize);
+        at[finalsize - 1] = '\0';
 
-        return(at);
+        return (at);
     }
-    return(NULL);
+    return (NULL);
 }
 
-
-RuleInfoDetail *zeroinfodetails(int type, char *data)
+RuleInfoDetail *zeroinfodetails(int type, const char *data)
 {
     RuleInfoDetail *info_details_pt = NULL;
 
-    info_details_pt = (RuleInfoDetail *)calloc(1,sizeof(RuleInfoDetail));
+    info_details_pt = (RuleInfoDetail *)calloc(1, sizeof(RuleInfoDetail));
 
-    if (info_details_pt == NULL)
-    {
-        ErrorExit(MEM_ERROR,ARGV0);
+    if (info_details_pt == NULL) {
+        ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
     }
-    /* type */
-    info_details_pt->type = type;
 
-    /* data */
+    info_details_pt->type = type;
     os_strdup(data, info_details_pt->data);
-
     info_details_pt->next = NULL;
 
-
-    return(info_details_pt);
+    return (info_details_pt);
 }
 
-
 RuleInfo *zerorulemember(int id, int level,
                          int maxsize, int frequency,
                          int timeframe, int noalert,
@@ -1593,12 +1626,11 @@ RuleInfo *zerorulemember(int id, int level,
 {
     RuleInfo *ruleinfo_pt = NULL;
 
-    /* Allocation memory for structure */
-    ruleinfo_pt = (RuleInfo *)calloc(1,sizeof(RuleInfo));
+    /* Allocate memory for structure */
+    ruleinfo_pt = (RuleInfo *)calloc(1, sizeof(RuleInfo));
 
-    if(ruleinfo_pt == NULL)
-    {
-        ErrorExit(MEM_ERROR,ARGV0);
+    if (ruleinfo_pt == NULL) {
+        ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
     }
 
     /* Default values */
@@ -1615,8 +1647,7 @@ RuleInfo *zerorulemember(int id, int level,
     ruleinfo_pt->firedtimes = 0;
     ruleinfo_pt->maxsize = maxsize;
     ruleinfo_pt->frequency = frequency;
-    if(ruleinfo_pt->frequency > _max_freq)
-    {
+    if (ruleinfo_pt->frequency > _max_freq) {
         _max_freq = ruleinfo_pt->frequency;
     }
     ruleinfo_pt->ignore_time = ignore_time;
@@ -1628,18 +1659,18 @@ RuleInfo *zerorulemember(int id, int level,
     ruleinfo_pt->ignore = 0;
     ruleinfo_pt->ckignore = 0;
 
-    if(noalert)
-    {
+    if (noalert) {
         ruleinfo_pt->alert_opts |= NO_ALERT;
     }
-    if(Config.mailbylevel <= level)
+    if (Config.mailbylevel <= level) {
         ruleinfo_pt->alert_opts |= DO_MAILALERT;
-    if(Config.logbylevel <= level)
+    }
+    if (Config.logbylevel <= level) {
         ruleinfo_pt->alert_opts |= DO_LOGALERT;
+    }
 
-    /* Overwriting a rule */
-    if(overwrite)
-    {
+    /* Overwrite a rule */
+    if (overwrite) {
         ruleinfo_pt->alert_opts |= DO_OVERWRITE;
     }
 
@@ -1675,12 +1706,14 @@ RuleInfo *zerorulemember(int id, int level,
     ruleinfo_pt->hostname = NULL;
     ruleinfo_pt->program_name = NULL;
     ruleinfo_pt->action = NULL;
+    os_calloc(Config.decoder_order_size, sizeof(FieldInfo*), ruleinfo_pt->fields);
+
 
-    /* Zeroing last matched events */
+    /* Zero last matched events */
     ruleinfo_pt->__frequency = 0;
     ruleinfo_pt->last_events = NULL;
 
-    /* zeroing the list of previous matches */
+    /* Zeroing the list of previous matches */
     ruleinfo_pt->sid_prev_matched = NULL;
     ruleinfo_pt->group_prev_matched = NULL;
 
@@ -1691,296 +1724,232 @@ RuleInfo *zerorulemember(int id, int level,
     ruleinfo_pt->compiled_rule = NULL;
     ruleinfo_pt->lists = NULL;
 
-    return(ruleinfo_pt);
+    return (ruleinfo_pt);
 }
 
 int get_info_attributes(char **attributes, char **values)
 {
-    char *xml_type = "type";
-    int k=0;
-    if(!attributes)
-        return(RULEINFODETAIL_TEXT);
+    const char *xml_type = "type";
+    int k = 0;
 
-    while(attributes[k])
-    {
-        if (!values[k])
-        {
+    if (!attributes) {
+        return (RULEINFODETAIL_TEXT);
+    }
+
+    while (attributes[k]) {
+        if (!values[k]) {
             merror("rules_op: Entry info type \"%s\" does not have a value",
-                    attributes[k]);
+                   attributes[k]);
             return (-1);
-        }
-        else if(strcasecmp(attributes[k],xml_type) == 0)
-        {
-            if(strcmp(values[k], "text") == 0)
-            {
-                return(RULEINFODETAIL_TEXT);
-            }
-            else if(strcmp(values[k], "link") == 0)
-            {
-                return(RULEINFODETAIL_LINK);
-            }
-            else if(strcmp(values[k], "cve") == 0)
-            {
-                return(RULEINFODETAIL_CVE);
-            }
-            else if(strcmp(values[k], "osvdb") == 0)
-            {
-                return(RULEINFODETAIL_OSVDB);
+        } else if (strcasecmp(attributes[k], xml_type) == 0) {
+            if (strcmp(values[k], "text") == 0) {
+                return (RULEINFODETAIL_TEXT);
+            } else if (strcmp(values[k], "link") == 0) {
+                return (RULEINFODETAIL_LINK);
+            } else if (strcmp(values[k], "cve") == 0) {
+                return (RULEINFODETAIL_CVE);
+            } else if (strcmp(values[k], "osvdb") == 0) {
+                return (RULEINFODETAIL_OSVDB);
             }
         }
     }
-    return(RULEINFODETAIL_TEXT);
+    return (RULEINFODETAIL_TEXT);
 }
 
 /* Get the attributes */
-int getattributes(char **attributes, char **values,
+static int getattributes(char **attributes, char **values,
                   int *id, int *level,
                   int *maxsize, int *timeframe,
                   int *frequency, int *accuracy,
                   int *noalert, int *ignore_time, int *overwrite)
 {
-    int k=0;
-
-    char *xml_id = "id";
-    char *xml_level = "level";
-    char *xml_maxsize = "maxsize";
-    char *xml_timeframe = "timeframe";
-    char *xml_frequency = "frequency";
-    char *xml_accuracy = "accuracy";
-    char *xml_noalert = "noalert";
-    char *xml_ignore_time = "ignore";
-    char *xml_overwrite = "overwrite";
-
-
-    /* Getting attributes */
-    while(attributes[k])
-    {
-        if(!values[k])
-        {
+    int k = 0;
+
+    const char *xml_id = "id";
+    const char *xml_level = "level";
+    const char *xml_maxsize = "maxsize";
+    const char *xml_timeframe = "timeframe";
+    const char *xml_frequency = "frequency";
+    const char *xml_accuracy = "accuracy";
+    const char *xml_noalert = "noalert";
+    const char *xml_ignore_time = "ignore";
+    const char *xml_overwrite = "overwrite";
+
+    /* Get attributes */
+    while (attributes[k]) {
+        if (!values[k]) {
             merror("rules_op: Attribute \"%s\" without value."
-                    ,attributes[k]);
-            return(-1);
+                   , attributes[k]);
+            return (-1);
         }
-        /* Getting rule Id */
-        else if(strcasecmp(attributes[k],xml_id) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%6d",id);
-            }
-            else
-            {
+        /* Get rule id */
+        else if (strcasecmp(attributes[k], xml_id) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%6d", id);
+            } else {
                 merror("rules_op: Invalid rule id: %s. "
-                        "Must be integer" ,
-                        values[k]);
-                return(-1);
+                       "Must be integer" ,
+                       values[k]);
+                return (-1);
             }
         }
-        /* Getting level */
-        else if(strcasecmp(attributes[k],xml_level) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%4d",level);
-            }
-            else
-            {
+        /* Get level */
+        else if (strcasecmp(attributes[k], xml_level) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%4d", level);
+            } else {
                 merror("rules_op: Invalid level: %s. "
-                        "Must be integer" ,
-                        values[k]);
-                return(-1);
+                       "Must be integer" ,
+                       values[k]);
+                return (-1);
             }
         }
-        /* Getting maxsize */
-        else if(strcasecmp(attributes[k],xml_maxsize) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%4d",maxsize);
-            }
-            else
-            {
+        /* Get maxsize */
+        else if (strcasecmp(attributes[k], xml_maxsize) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%4d", maxsize);
+            } else {
                 merror("rules_op: Invalid maxsize: %s. "
-                        "Must be integer" ,
-                        values[k]);
-                return(-1);
+                       "Must be integer" ,
+                       values[k]);
+                return (-1);
             }
         }
-        /* Getting timeframe */
-        else if(strcasecmp(attributes[k],xml_timeframe) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%5d",timeframe);
-            }
-            else
-            {
+        /* Get timeframe */
+        else if (strcasecmp(attributes[k], xml_timeframe) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%5d", timeframe);
+            } else {
                 merror("rules_op: Invalid timeframe: %s. "
-                        "Must be integer" ,
-                        values[k]);
-                return(-1);
+                       "Must be integer" ,
+                       values[k]);
+                return (-1);
             }
         }
-        /* Getting frequency */
-        else if(strcasecmp(attributes[k],xml_frequency) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%4d",frequency);
-            }
-            else
-            {
+        /* Get frequency */
+        else if (strcasecmp(attributes[k], xml_frequency) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%4d", frequency);
+            } else {
                 merror("rules_op: Invalid frequency: %s. "
-                        "Must be integer" ,
-                        values[k]);
-                return(-1);
+                       "Must be integer" ,
+                       values[k]);
+                return (-1);
             }
         }
         /* Rule accuracy */
-        else if(strcasecmp(attributes[k],xml_accuracy) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%4d",accuracy);
-            }
-            else
-            {
+        else if (strcasecmp(attributes[k], xml_accuracy) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%4d", accuracy);
+            } else {
                 merror("rules_op: Invalid accuracy: %s. "
                        "Must be integer" ,
                        values[k]);
-                return(-1);
+                return (-1);
             }
         }
-         /* Rule ignore_time */
-        else if(strcasecmp(attributes[k],xml_ignore_time) == 0)
-        {
-            if(OS_StrIsNum(values[k]))
-            {
-                sscanf(values[k],"%6d",ignore_time);
-            }
-            else
-            {
+        /* Rule ignore_time */
+        else if (strcasecmp(attributes[k], xml_ignore_time) == 0) {
+            if (OS_StrIsNum(values[k])) {
+                sscanf(values[k], "%6d", ignore_time);
+            } else {
                 merror("rules_op: Invalid ignore_time: %s. "
                        "Must be integer" ,
                        values[k]);
-                return(-1);
+                return (-1);
             }
         }
         /* Rule noalert */
-        else if(strcasecmp(attributes[k],xml_noalert) == 0)
-        {
+        else if (strcasecmp(attributes[k], xml_noalert) == 0) {
             *noalert = 1;
-        }
-        else if(strcasecmp(attributes[k], xml_overwrite) == 0)
-        {
-            if(strcmp(values[k], "yes") == 0)
-            {
+        } else if (strcasecmp(attributes[k], xml_overwrite) == 0) {
+            if (strcmp(values[k], "yes") == 0) {
                 *overwrite = 1;
-            }
-            else if(strcmp(values[k], "no") == 0)
-            {
+            } else if (strcmp(values[k], "no") == 0) {
                 *overwrite = 0;
-            }
-            else
-            {
+            } else {
                 merror("rules_op: Invalid overwrite: %s. "
                        "Can only by 'yes' or 'no'.", values[k]);
-                return(-1);
+                return (-1);
             }
-        }
-        else
-        {
+        } else {
             merror("rules_op: Invalid attribute \"%s\". "
-                    "Only id, level, maxsize, accuracy, noalert and timeframe "
-                    "are allowed.", attributes[k]);
-            return(-1);
+                   "Only id, level, maxsize, accuracy, noalert and timeframe "
+                   "are allowed.", attributes[k]);
+            return (-1);
         }
         k++;
     }
-    return(0);
+    return (0);
 }
 
-
-/* Bind active responses to the rule.
- * No return.
- */
-void Rule_AddAR(RuleInfo *rule_config)
+/* Bind active responses to a rule */
+static void Rule_AddAR(RuleInfo *rule_config)
 {
-    int rule_ar_size = 0;
+    unsigned int rule_ar_size = 0;
     int mark_to_ar = 0;
     int rule_real_level = 0;
 
     OSListNode *my_ars_node;
 
-
-    /* Setting the correctly levels
+    /* Set the correct levels
      * We play internally with the rules, to set
      * the priorities... Rules with 0 of accuracy,
      * receive a low level and go down in the list
      */
-    if(rule_config->level == 9900)
+    if (rule_config->level == 9900) {
         rule_real_level = 0;
+    }
 
-    else if(rule_config->level >= 100)
-        rule_real_level = rule_config->level/100;
-
+    else if (rule_config->level >= 100) {
+        rule_real_level = rule_config->level / 100;
+    }
 
     /* No AR for ignored rules */
-    if(rule_real_level == 0)
-    {
+    if (rule_real_level == 0) {
         return;
     }
 
     /* No AR when options no_ar is set */
-    if(rule_config->alert_opts & NO_AR)
-    {
+    if (rule_config->alert_opts & NO_AR) {
         return;
     }
 
-    if(!active_responses)
-    {
+    if (!active_responses) {
         return;
     }
 
-    /* Looping on all AR */
+    /* Loop on all AR */
     my_ars_node = OSList_GetFirstNode(active_responses);
-    while(my_ars_node)
-    {
+    while (my_ars_node) {
         active_response *my_ar;
 
 
         my_ar = (active_response *)my_ars_node->data;
         mark_to_ar = 0;
 
-        /* Checking if the level for the ar is higher */
-        if(my_ar->level)
-        {
-            if(rule_real_level >= my_ar->level)
-            {
+        /* Check if the level for the ar is higher */
+        if (my_ar->level) {
+            if (rule_real_level >= my_ar->level) {
                 mark_to_ar = 1;
             }
         }
 
-        /* Checking if group matches */
-        if(my_ar->rules_group)
-        {
-           if(OS_Regex(my_ar->rules_group, rule_config->group))
-           {
-               mark_to_ar = 1;
-           }
+        /* Check if group matches */
+        if (my_ar->rules_group) {
+            if (OS_Regex(my_ar->rules_group, rule_config->group)) {
+                mark_to_ar = 1;
+            }
         }
 
-        /* Checking if rule id matches */
-        if(my_ar->rules_id)
-        {
+        /* Check if rule id matches */
+        if (my_ar->rules_id) {
             int r_id = 0;
             char *str_pt = my_ar->rules_id;
 
-            while(*str_pt != '\0')
-            {
+            while (*str_pt != '\0') {
                 /* We allow spaces in between */
-                if(*str_pt == ' ')
-                {
+                if (*str_pt == ' ') {
                     str_pt++;
                     continue;
                 }
@@ -1989,50 +1958,41 @@ void Rule_AddAR(RuleInfo *rule_config)
                  * and search for the next digit
                  * available
                  */
-                else if(isdigit((int)*str_pt))
-                {
+                else if (isdigit((int)*str_pt)) {
                     r_id = atoi(str_pt);
 
                     /* mark to ar if id matches */
-                    if(r_id == rule_config->sigid)
-                    {
+                    if (r_id == rule_config->sigid) {
                         mark_to_ar = 1;
                     }
 
                     str_pt = strchr(str_pt, ',');
-                    if(str_pt)
-                    {
+                    if (str_pt) {
                         str_pt++;
-                    }
-                    else
-                    {
+                    } else {
                         break;
                     }
                 }
 
-                /* Checking for duplicate commas */
-                else if(*str_pt == ',')
-                {
+                /* Check for duplicate commas */
+                else if (*str_pt == ',') {
                     str_pt++;
                     continue;
                 }
 
-                else
-                {
+                else {
                     break;
                 }
             }
         } /* eof of rules_id */
 
-
         /* Bind AR to the rule */
-        if(mark_to_ar == 1)
-        {
+        if (mark_to_ar == 1) {
             rule_ar_size++;
 
-            rule_config->ar = realloc(rule_config->ar,
+            rule_config->ar = (active_response **) realloc(rule_config->ar,
                                       (rule_ar_size + 1)
-                                      *sizeof(active_response *));
+                                      * sizeof(active_response *));
 
             /* Always set the last node to NULL */
             rule_config->ar[rule_ar_size - 1] = my_ar;
@@ -2045,67 +2005,55 @@ void Rule_AddAR(RuleInfo *rule_config)
     return;
 }
 
-
-/* print rule */
-void printRuleinfo(RuleInfo *rule, int node)
+static void printRuleinfo(const RuleInfo *rule, int node)
 {
     debug1("%d : rule:%d, level %d, timeout: %d",
-            node,
-            rule->sigid,
-            rule->level,
-            rule->ignore_time);
+           node,
+           rule->sigid,
+           rule->level,
+           rule->ignore_time);
 }
 
-
-
-/* Add Rule to hash. */
+/* Add rule to hash */
 int AddHash_Rule(RuleNode *node)
 {
-    while(node)
-    {
-        char _id_key[15];
-        char *id_key;
-
-        snprintf(_id_key, 14, "%d", node->ruleinfo->sigid);
-        os_strdup(_id_key, id_key);
+    while (node) {
+        char id_key[15];
 
+        snprintf(id_key, 14, "%d", node->ruleinfo->sigid);
 
-        /* Adding key to hash. */
+        /* Add key to hash */
         OSHash_Add(Config.g_rules_hash, id_key, node->ruleinfo);
-        if(node->child)
-        {
+        if (node->child) {
             AddHash_Rule(node->child);
         }
 
         node = node->next;
     }
 
-    return(0);
+    return (0);
 }
 
-
-
-/* _set levels */
 int _setlevels(RuleNode *node, int nnode)
 {
     int l_size = 0;
-    while(node)
-    {
-        if(node->ruleinfo->level == 9900)
+    while (node) {
+        if (node->ruleinfo->level == 9900) {
             node->ruleinfo->level = 0;
+        }
 
-        if(node->ruleinfo->level >= 100)
-            node->ruleinfo->level/=100;
+        if (node->ruleinfo->level >= 100) {
+            node->ruleinfo->level /= 100;
+        }
 
         l_size++;
 
         /* Rule information */
         printRuleinfo(node->ruleinfo, nnode);
 
-        if(node->child)
-        {
+        if (node->child) {
             int chl_size = 0;
-            chl_size = _setlevels(node->child, nnode+1);
+            chl_size = _setlevels(node->child, nnode + 1);
 
             l_size += chl_size;
         }
@@ -2113,39 +2061,36 @@ int _setlevels(RuleNode *node, int nnode)
         node = node->next;
     }
 
-    return(l_size);
+    return (l_size);
 }
 
-/* test if a rule id exists
- * return 1 when exists
- * return 0 when not
+/* Test if a rule id exists
+ * return 1 if exists, otherwise 0
  */
-int doesRuleExist(int sid, RuleNode *r_node)
+static int doesRuleExist(int sid, RuleNode *r_node)
 {
-    /* start from the beginning of the list by default */
-    if(!r_node)
+    /* Start from the beginning of the list by default */
+    if (!r_node) {
         r_node = OS_GetFirstRule();
+    }
 
-    while(r_node)
-    {
-        /* Checking if the sigid matches */
-        if(r_node->ruleinfo->sigid == sid)
+    while (r_node) {
+        /* Check if the sigid matches */
+        if (r_node->ruleinfo->sigid == sid) {
             return (1);
+        }
 
-        /* Checking if the rule has a child */
-        if(r_node->child)
-        {
-            /* check recursive */
-            if(doesRuleExist(sid, r_node->child))
+        /* Check if the rule has a child */
+        if (r_node->child) {
+            /* Check recursively */
+            if (doesRuleExist(sid, r_node->child)) {
                 return (1);
+            }
         }
 
-        /* go to the next rule */
+        /* Go to the next rule */
         r_node = r_node->next;
     }
 
     return (0);
 }
-
-
-/* EOF */