← Back to team overview

hipl-core team mailing list archive

Patch: Allow empty lines in hipfw config. Clean up config reader.

 

This was marked as TODO... I've attached the resulting code for
reference.

=== modified file 'firewall/rule_management.c'
--- firewall/rule_management.c	2010-07-16 18:00:53 +0000
+++ firewall/rule_management.c	2010-08-30 12:30:07 +0000
@@ -860,55 +860,11 @@
  */
 
 /**
- * read a rule line in the firewall configuration file
- *
- * @param buf the buffer where the line is read
- * @param buflen the length of the buffer
- * @param file a handle to the firewall configuration file
- *
- * @return the length of the line (excluding trailing 0)
- * @todo check correctness of this function
- */
-static size_t read_line(char *buf, int buflen, FILE *file)
-{
-    int ch     = 0;
-    size_t len = 0;
-
-    HIP_ASSERT(file != 0);
-    HIP_ASSERT(buf != 0);
-    HIP_ASSERT(buflen > 0);
-
-    if (fgets(buf, buflen, file) == NULL) {
-        if (feof(file)) {               /* EOF */
-            len = 0;
-        } else {                        /* error */
-            len = 0;
-        }
-        clearerr(file);
-        return len;
-    }
-
-    len = strlen(buf);
-    if (buf[len - 1] == '\n') {         /* clear any trailing newline */
-        buf[--len] = '\0';
-    } else if ((int)len == buflen - 1) {     /* line too long */
-        while ((ch = getchar()) != '\n' && ch != EOF) {
-            continue;
-        }
-        clearerr(file);
-        return 0;
-    }
-
-    return len;
-}
-
-/**
  * read all rule sets from the specified file and parse into rule
  * lists
  *
  * @param file_name the name of the configuration file to be read
- *
- * @todo fix reading of empty lines (memory problems)
+ *                  (try default config file if NULL)
  */
 void read_rule_file(const char *file_name)
 {
@@ -916,13 +872,6 @@
     DList *output       = NULL;
     DList *forward      = NULL;
     FILE *file          = NULL;
-    struct rule *rule   = NULL;
-    char line[MAX_LINE_LENGTH];
-    char *original_line = NULL;
-    int s               = MAX_LINE_LENGTH;
-    int state           = 0;
-    size_t line_length  = 0;
-    char *tmp_line      = NULL;
 
     if (!file_name) {
         file_name = HIP_FW_DEFAULT_RULE_FILE;
@@ -934,31 +883,38 @@
     file = fopen(file_name, "r");
 
     if (file != NULL) {
-        while ((line_length = read_line(line, s, file)) > 0) {
-            char *comment;
+        char line[MAX_LINE_LENGTH];
 
-            original_line = malloc(line_length + sizeof(char) + 1);
-            original_line = strcpy(original_line, line);
+        while (fgets(line, sizeof(line), file)) {
+            char *found         = NULL;
+            char *original_line = NULL;
+            struct rule *rule   = NULL;
+            int state           = 0;
 
             HIP_DEBUG("line read: %s\n", line);
 
-            /* terminate the line to comment sign */
-            comment = index(line, '#');
-            if (comment) {
-                *comment = 0;
-            }
-
-            if (line_length == 0) {
+            original_line = strdup(line);
+            HIP_ASSERT(original_line);
+
+            /* terminate the line at comment sign */
+            found = index(line, '#');
+            if (found) {
+                *found = '\0';
+            }
+
+            /* remove trailing new line (there is at most one) */
+            found = index(line, '\n');
+            if (found) {
+                *found = '\0';
+            }
+
+            /* skip if empty */
+            if (*line == '\0') {
                 free(original_line);
                 continue;
             }
 
-            /* remove trailing new line */
-            tmp_line = strtok(line, "\n");
-
-            if (tmp_line) {
-                rule = parse_rule(tmp_line);
-            }
+            rule = parse_rule(line);
 
             if (rule) {
                 if (rule->state) {
@@ -975,15 +931,18 @@
                     forward = append_to_list(forward, rule);
                     print_rule((struct rule *) forward->data);
                 }
-            } else if (tmp_line)   {
+            } else {
                 HIP_DEBUG("unable to parse rule: %s\n", original_line);
             }
             free(original_line);
-            original_line = NULL;
+        }
+
+        if (!feof(file)) {
+            HIP_ERROR("fgets(): %s\n", strerror(errno));
         }
         fclose(file);
     } else {
-        HIP_DEBUG("Can't open file %s \n", file_name );
+        HIP_DEBUG("Can't open file %s: %s\n", file_name, strerror(errno));
     }
 
     input_rules   = input;
/**
 * read all rule sets from the specified file and parse into rule
 * lists
 *
 * @param file_name the name of the configuration file to be read
 *                  (try default config file if NULL)
 */
void read_rule_file(const char *file_name)
{
    DList *input        = NULL;
    DList *output       = NULL;
    DList *forward      = NULL;
    FILE *file          = NULL;

    if (!file_name) {
        file_name = HIP_FW_DEFAULT_RULE_FILE;
    }

    check_and_write_default_config(file_name);

    HIP_DEBUG("read_file: file %s\n", file_name);
    file = fopen(file_name, "r");

    if (file != NULL) {
        char line[MAX_LINE_LENGTH];

        while (fgets(line, sizeof(line), file)) {
            char *found         = NULL;
            char *original_line = NULL;
            struct rule *rule   = NULL;
            int state           = 0;

            HIP_DEBUG("line read: %s\n", line);

            original_line = strdup(line);
            HIP_ASSERT(original_line);

            /* terminate the line at comment sign */
            found = index(line, '#');
            if (found) {
                *found = '\0';
            }

            /* remove trailing new line (there is at most one) */
            found = index(line, '\n');
            if (found) {
                *found = '\0';
            }

            /* skip if empty */
            if (*line == '\0') {
                free(original_line);
                continue;
            }

            rule = parse_rule(line);

            if (rule) {
                if (rule->state) {
                    state = 1;
                }

                if (rule->hook == NF_IP6_LOCAL_IN) {
                    input = append_to_list(input, rule);
                    print_rule((struct rule *) input->data);
                } else if (rule->hook == NF_IP6_LOCAL_OUT)    {
                    output = append_to_list(output, rule);
                    print_rule((struct rule *) output->data);
                } else if (rule->hook == NF_IP6_FORWARD)    {
                    forward = append_to_list(forward, rule);
                    print_rule((struct rule *) forward->data);
                }
            } else {
                HIP_DEBUG("unable to parse rule: %s\n", original_line);
            }
            free(original_line);
        }

        if (!feof(file)) {
            HIP_ERROR("fgets(): %s\n", strerror(errno));
        }
        fclose(file);
    } else {
        HIP_DEBUG("Can't open file %s: %s\n", file_name, strerror(errno));
    }

    input_rules   = input;
    set_stateful_filtering();
    output_rules  = output;
    forward_rules = forward;
}

Follow ups