Added 'base' and 'variables' to CONF_SECTION, so that the
authoraland <aland>
Mon, 12 Feb 2007 10:38:19 +0000 (10:38 +0000)
committeraland <aland>
Mon, 12 Feb 2007 10:38:19 +0000 (10:38 +0000)
allocated memory can get automatically freed.

Ported from 1.1.x

src/include/conffile.h
src/main/conffile.c

index bc1f31e..ddda6e6 100644 (file)
@@ -52,13 +52,8 @@ void         cf_pair_free(CONF_PAIR **cp);
 void           cf_section_free(CONF_SECTION **cp);
 int            cf_item_parse(CONF_SECTION *cs, const char *name,
                              int type, void *data, const char *dflt);
-int            cf_section_parse(const CONF_SECTION *, void *base,
+int            cf_section_parse(CONF_SECTION *, void *base,
                                 const CONF_PARSER *variables);
-/*
- *     Free strings we've parsed into a structure.
- */
-void           cf_section_parse_free_strings(void *base,
-                                             const CONF_PARSER *variables);
 CONF_SECTION   *cf_file_read(const char *file);
 int            cf_file_include(const char *file, CONF_SECTION *cs);
 
index c6a80be..835159c 100644 (file)
@@ -81,6 +81,8 @@ struct conf_part {
        rbtree_t        *section_tree; /* no jokes here */
        rbtree_t        *name2_tree; /* for sections of the same name2 */
        rbtree_t        *data_tree;
+       void *base;
+       const CONF_PARSER *variables;
 };
 
 
@@ -262,6 +264,50 @@ static int data_cmp(const void *a, const void *b)
        return strcmp(one->name, two->name);
 }
 
+
+/*
+ *     Free strings we've parsed into data structures.
+ */
+static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
+{
+       int i;
+
+       /*
+        *      Don't automatically free the strings if we're being
+        *      called from a module.
+        */
+       if (base || !variables) return;
+       
+       /*
+        *      Free up dynamically allocated string pointers.
+        */
+       for (i = 0; variables[i].name != NULL; i++) {
+               char **p;
+
+               if (variables[i].type != PW_TYPE_STRING_PTR) {
+                       continue;
+               }
+
+               /*
+                *      Prefer the data, if it's there.
+                *      Else use the base + offset.
+                */
+               if (!variables[i].data) {
+                       continue;
+               }
+
+               /*
+                *      FIXME: Add base
+                */
+               p = (char **) (variables[i].data);
+
+
+               free(*p);
+               *p = NULL;
+       }
+}
+
+
 /*
  *     Free a CONF_SECTION
  */
@@ -271,6 +317,10 @@ void cf_section_free(CONF_SECTION **cs)
 
        if (!cs || !*cs) return;
 
+       if ((*cs)->variables) {
+               cf_section_parse_free((*cs)->base, (*cs)->variables);
+       }
+
        for (ci = (*cs)->children; ci; ci = next) {
                next = ci->next;
 
@@ -842,7 +892,7 @@ int cf_item_parse(CONF_SECTION *cs, const char *name,
 /*
  *     Parse a configuration section into user-supplied variables.
  */
-int cf_section_parse(const CONF_SECTION *cs, void *base,
+int cf_section_parse(CONF_SECTION *cs, void *base,
                     const CONF_PARSER *variables)
 {
        int i;
@@ -870,11 +920,13 @@ int cf_section_parse(const CONF_SECTION *cs, void *base,
 
                        if (!variables[i].dflt) {
                                DEBUG2("Internal sanity check 1 failed in cf_section_parse");
+                               cf_section_parse_free(base, variables);
                                return -1;
                        }
                        
                        if (cf_section_parse(subcs, base,
                                             (const CONF_PARSER *) variables[i].dflt) < 0) {
+                               cf_section_parse_free(base, variables);
                                return -1;
                        }
                        continue;
@@ -886,6 +938,7 @@ int cf_section_parse(const CONF_SECTION *cs, void *base,
                        data = ((char *)base) + variables[i].offset;
                } else {
                        DEBUG2("Internal sanity check 2 failed in cf_section_parse");
+                       cf_section_parse_free(base, variables);
                        return -1;
                }
 
@@ -894,46 +947,15 @@ int cf_section_parse(const CONF_SECTION *cs, void *base,
                 */
                if (cf_item_parse(cs, variables[i].name, variables[i].type,
                                  data, variables[i].dflt) < 0) {
+                       cf_section_parse_free(base, variables);
                        return -1;
                }
        } /* for all variables in the configuration section */
 
-       return 0;
-}
-
-
-/*
- *     Free strings we've parsed into data structures.
- */
-void cf_section_parse_free_strings(void *base, const CONF_PARSER *variables)
-{
-       int i;
-
-       if (!variables) return;
-       
-       /*
-        *      Free up dynamically allocated string pointers.
-        */
-       for (i = 0; variables[i].name != NULL; i++) {
-               char **p;
+       cs->base = base;
+       cs->variables = variables;
 
-               if ((variables[i].type != PW_TYPE_STRING_PTR) &&
-                   (variables[i].type != PW_TYPE_FILENAME)) {
-                       continue;
-               }
-               
-               /*
-                *      Prefer the data, if it's there.
-                *      Else use the base + offset.
-                */
-               if (variables[i].data) {
-                       p = (char **) &(variables[i].data);
-               } else {
-                       p = (char **) (((char *)base) + variables[i].offset);
-               }
-               free(*p);
-               *p = NULL;
-       }
+       return 0;
 }