+ os_strdup(node[i]->content, Config->includes[rules_size - 2]);
+ Config->includes[rules_size - 1] = NULL;
+ debug1("adding rule: %s", node[i]->content);
+ } else if (strcmp(node[i]->element, xml_rules_decoders) == 0) {
+ decoders_size++;
+ Config->decoders = (char **) realloc(Config->decoders,
+ sizeof(char *)*decoders_size);
+ if (!Config->decoders) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ return (OS_INVALID);
+ }
+
+ os_strdup(node[i]->content, Config->decoders[decoders_size - 2]);
+ Config->decoders[decoders_size - 1] = NULL;
+ debug1("adding decoder: %s", node[i]->content);
+ } else if (strcmp(node[i]->element, xml_rules_lists) == 0) {
+ lists_size++;
+ Config->lists = (char **) realloc(Config->lists,
+ sizeof(char *)*lists_size);
+ if (!Config->lists) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ return (OS_INVALID);
+ }
+ os_strdup(node[i]->content, Config->lists[lists_size - 2]);
+ Config->lists[lists_size - 1] = NULL;
+
+ } else if (strcmp(node[i]->element, xml_rules_decoders_dir) == 0) {
+
+ if (node[i]->attributes && node[i]->values) {
+ while (node[i]->attributes[att_count]) {
+ if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) {
+ if (node[i]->values[att_count]) {
+ if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) {
+ merror(CONFIG_ERROR, __local_name, "pattern in decoders_dir does not compile");
+ merror("%s: ERROR: Regex would not compile", __local_name);
+ return (-1);
+ }
+ }
+ }
+ att_count++;
+ }
+ } else {
+ OSRegex_Compile(".xml$", ®ex, 0);
+ }
+
+#ifdef TESTRULE
+ snprintf(path, PATH_MAX + 1, "%s", node[i]->content);
+#else
+ snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content);
+#endif
+
+ f_name[PATH_MAX + 1] = '\0';
+ dfd = opendir(path);
+
+ att_count = 0; // Reset this variable after it was used in decoder
+
+ if (dfd != NULL) {
+ start_point = decoders_size - 1;
+ while ((entry = readdir(dfd)) != NULL) {
+ snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name);
+
+ /* Ignore . and .. */
+ if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
+ continue;
+ }
+
+ /* No duplicates allowed */
+ if (file_in_list(decoders_size, f_name, entry->d_name, Config->decoders)) {
+ continue;
+ }
+
+ if (OSRegex_Execute(f_name, ®ex)) {
+ decoders_size++;
+ Config->decoders = (char **) realloc(Config->decoders, sizeof(char *)*decoders_size);
+ if (!Config->decoders) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ OSRegex_FreePattern(®ex);
+ closedir(dfd);
+ return (-1);
+ }
+
+ os_strdup(f_name, Config->decoders[decoders_size - 2]);
+ Config->decoders[decoders_size - 1] = NULL;
+ debug1("adding decoder: %s", f_name);
+ } else {
+ debug1("Regex does not match \"%s\"", f_name);
+ }
+ }
+
+ OSRegex_FreePattern(®ex);
+ closedir(dfd);
+ /* Sort just then newly added items */
+ qsort(Config->decoders + start_point , decoders_size - start_point - 1, sizeof(char *), cmpr);
+ }
+ debug1("decoders_size %d", decoders_size);
+ for (ii = 0; ii < decoders_size - 1; ii++) {
+ debug1("- %s", Config->decoders[ii]);
+ }
+ } else if (strcmp(node[i]->element, xml_rules_rules_dir) == 0) {
+ if (node[i]->attributes && node[i]->values) {
+ while (node[i]->attributes[att_count]) {
+ if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) {
+ if (node[i]->values[att_count]) {
+ if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) {
+ merror(CONFIG_ERROR, __local_name, "pattern in rules_dir does not compile");
+ merror("%s: ERROR: Regex would not compile", __local_name);
+ return (-1);
+ }
+ }
+ }
+ att_count++;
+ }
+ } else {
+ OSRegex_Compile(".xml$", ®ex, 0);
+ }
+
+#ifdef TESTRULE
+ snprintf(path, PATH_MAX + 1, "%s", node[i]->content);
+#else
+ snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content);
+#endif
+
+ f_name[PATH_MAX + 1] = '\0';
+ dfd = opendir(path);
+
+ if (dfd != NULL) {
+ start_point = rules_size - 1;
+ while ((entry = readdir(dfd)) != NULL) {
+ snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name);
+
+ /* Ignore . and .. */
+ if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
+ continue;
+ }
+
+ /* No duplicates allowed */
+ if (file_in_list(rules_size, f_name, entry->d_name, Config->includes)) {
+ continue;
+ }
+
+ if (OSRegex_Execute(f_name, ®ex)) {
+ rules_size++;
+ Config->includes = (char **) realloc(Config->includes, sizeof(char *)*rules_size);
+ if (!Config->includes) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ OSRegex_FreePattern(®ex);
+ closedir(dfd);
+ return (-1);
+ }
+
+ os_strdup(f_name, Config->includes[rules_size - 2]);
+ Config->includes[rules_size - 1] = NULL;
+ debug1("adding rule: %s", f_name);
+ } else {
+ debug1("Regex does not match \"%s\"", f_name);
+ }
+ }
+
+ OSRegex_FreePattern(®ex);
+ closedir(dfd);
+ /* Sort just then newly added items */
+ qsort(Config->includes + start_point , rules_size - start_point - 1, sizeof(char *), cmpr);
+ }
+ } else {
+ merror(XML_INVELEM, __local_name, node[i]->element);
+ OSRegex_FreePattern(®ex);
+ return (OS_INVALID);