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