summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/config.c91
1 files changed, 80 insertions, 11 deletions
diff --git a/main/config.c b/main/config.c
index e2f0a8dc4..736c5428e 100644
--- a/main/config.c
+++ b/main/config.c
@@ -212,12 +212,19 @@ static struct ast_config_engine *config_engine_list;
#define MAX_INCLUDE_LEVEL 10
+struct ast_category_template_instance {
+ char name[80]; /* redundant? */
+ const struct ast_category *inst;
+ AST_LIST_ENTRY(ast_category_template_instance) next;
+};
+
struct ast_category {
char name[80];
int ignored; /*!< do not let user of the config see this category */
int include_level;
char *file; /*!< the file name from whence this declaration was read */
int lineno;
+ AST_LIST_HEAD_NOLOCK(template_instance_list, ast_category_template_instance) template_instances;
struct ast_comment *precomments;
struct ast_comment *sameline;
struct ast_comment *trailing; /*!< the last object in the list will get assigned any trailing comments when EOF is hit */
@@ -515,12 +522,45 @@ void ast_category_append(struct ast_config *config, struct ast_category *categor
config->current = category;
}
+static void ast_destroy_comments(struct ast_category *cat)
+{
+ struct ast_comment *n, *p;
+ for (p=cat->precomments; p; p=n) {
+ n = p->next;
+ free(p);
+ }
+ for (p=cat->sameline; p; p=n) {
+ n = p->next;
+ free(p);
+ }
+ for (p=cat->trailing; p; p=n) {
+ n = p->next;
+ free(p);
+ }
+ cat->precomments = NULL;
+ cat->sameline = NULL;
+ cat->trailing = NULL;
+}
+
+static void ast_destroy_template_list(struct ast_category *cat)
+{
+ struct ast_category_template_instance *x;
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&cat->template_instances, x, next) {
+ AST_LIST_REMOVE_CURRENT(&cat->template_instances, next);
+ free(x);
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+}
+
void ast_category_destroy(struct ast_category *cat)
{
ast_variables_destroy(cat->root);
- if (cat->file)
+ if (cat->file) {
free(cat->file);
-
+ cat->file = 0;
+ }
+ ast_destroy_comments(cat);
+ ast_destroy_template_list(cat);
ast_free(cat);
}
@@ -606,7 +646,10 @@ void ast_category_rename(struct ast_category *cat, const char *name)
static void inherit_category(struct ast_category *new, const struct ast_category *base)
{
struct ast_variable *var;
-
+ struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance));
+ strcpy(x->name, base->name);
+ x->inst = base;
+ AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
for (var = base->root; var; var = var->next)
ast_variable_append(new, variable_clone(var));
}
@@ -711,7 +754,6 @@ int ast_category_delete(struct ast_config *cfg, const char *category)
cat = cfg->root;
while (cat) {
if (cat->name == category) {
- ast_variables_destroy(cat->root);
if (prev) {
prev->next = cat->next;
if (cat == cfg->last)
@@ -721,7 +763,7 @@ int ast_category_delete(struct ast_config *cfg, const char *category)
if (cat == cfg->last)
cfg->last = NULL;
}
- ast_free(cat);
+ ast_category_destroy(cat);
return 0;
}
prev = cat;
@@ -732,7 +774,6 @@ int ast_category_delete(struct ast_config *cfg, const char *category)
cat = cfg->root;
while (cat) {
if (!strcasecmp(cat->name, category)) {
- ast_variables_destroy(cat->root);
if (prev) {
prev->next = cat->next;
if (cat == cfg->last)
@@ -742,7 +783,7 @@ int ast_category_delete(struct ast_config *cfg, const char *category)
if (cat == cfg->last)
cfg->last = NULL;
}
- ast_free(cat);
+ ast_category_destroy(cat);
return 0;
}
prev = cat;
@@ -762,11 +803,9 @@ void ast_config_destroy(struct ast_config *cfg)
cat = cfg->root;
while (cat) {
- ast_variables_destroy(cat->root);
catn = cat;
cat = cat->next;
- ast_free(catn->file);
- ast_free(catn);
+ ast_category_destroy(catn);
}
ast_free(cfg);
}
@@ -1528,7 +1567,20 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
if (!cat->precomments)
fprintf(f,"\n");
fprintf(f, "[%s]", cat->name);
- for (cmt = cat->sameline; cmt; cmt=cmt->next) {
+ if (cat->ignored)
+ fprintf(f, "(!)");
+ if (!AST_LIST_EMPTY(&cat->template_instances)) {
+ struct ast_category_template_instance *x;
+ fprintf(f, "(");
+ AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
+ fprintf(f,"%s",x->name);
+ if (x != AST_LIST_LAST(&cat->template_instances))
+ fprintf(f,",");
+ }
+ fprintf(f, ")");
+ }
+ for(cmt = cat->sameline; cmt; cmt=cmt->next)
+ {
fprintf(f,"%s", cmt->cmt);
}
if (!cat->sameline)
@@ -1543,6 +1595,23 @@ int config_text_file_save(const char *configfile, const struct ast_config *cfg,
var = cat->root;
while (var) {
+ struct ast_category_template_instance *x;
+ int found = 0;
+ AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
+ struct ast_variable *v;
+ for (v = x->inst->root; v; v = v->next) {
+ if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (found) {
+ var = var->next;
+ continue;
+ }
set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi);
f = fopen(fn, "a");
if (!f)