mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
config: Add option to NOT preserve effective context when changing a template
Let's say you have a template T with variable VAR1 = ON and you have a context C(T) that doesn't specify VAR1. If you read C, the effective value of VAR1 is ON. Now you change T VAR1 to OFF and call ast_config_text_file_save. The current behavior is that the file gets re-written with T/VAR1=OFF but C/VAR1=ON is added. Personally, I think this is a bug. It's preserving the effective state of C even though I didn't specify C/VAR1 in th first place. I believe the behavior should be that if I didn't specify C/VAR1 originally, then the effective value of C/VAR1 should continue to follow the inherited state. Now, if I DID explicitly specify C/VAR1, the it should be preserved even if the template changes. Even though I think the existing behavior is a bug, it's been that way forever so I'm not changing it. Instead, I've created ast_config_text_file_save2() that takes a bitmask of flags, one of which is to preserve the effective context (the current behavior). The original ast_config_text_file_save calls *2 with the preserve flag. If you want the new behavior, call *2 directly without a flag. I've also updated Manager UpdateConfig with a new parameter 'PreserveEffectiveContext' whose default is 'yes'. If you want the new behavior with UpdateConfig, set 'PreserveEffectiveContext: no'. Tested-by: George Joseph Review: https://reviewboard.asterisk.org/r/4297/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430295 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1250,8 +1250,11 @@ void ast_category_inherit(struct ast_category *new, const struct ast_category *b
|
||||
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));
|
||||
for (var = base->root; var; var = var->next) {
|
||||
struct ast_variable *cloned = variable_clone(var);
|
||||
cloned->inherited = 1;
|
||||
ast_variable_append(new, cloned);
|
||||
}
|
||||
}
|
||||
|
||||
struct ast_config *ast_config_new(void)
|
||||
@@ -2358,10 +2361,15 @@ static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast
|
||||
|
||||
int config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
|
||||
{
|
||||
return ast_config_text_file_save(configfile, cfg, generator);
|
||||
return ast_config_text_file_save2(configfile, cfg, generator, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT);
|
||||
}
|
||||
|
||||
int ast_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
|
||||
{
|
||||
return ast_config_text_file_save2(configfile, cfg, generator, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT);
|
||||
}
|
||||
|
||||
int ast_config_text_file_save2(const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
|
||||
{
|
||||
FILE *f;
|
||||
char fn[PATH_MAX];
|
||||
@@ -2522,13 +2530,27 @@ int ast_config_text_file_save(const char *configfile, const struct ast_config *c
|
||||
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 (flags & CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT) {
|
||||
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (var->inherited) {
|
||||
found = 1;
|
||||
break;
|
||||
} else {
|
||||
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
var = var->next;
|
||||
|
@@ -412,6 +412,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
<parameter name="Reload">
|
||||
<para>Whether or not a reload should take place (or name of specific module).</para>
|
||||
</parameter>
|
||||
<parameter name="PreserveEffectiveContext">
|
||||
<para>Whether the effective category contents should be preserved on template change. Default is true (pre 13.2 behavior).</para>
|
||||
</parameter>
|
||||
<parameter name="Action-000000">
|
||||
<para>Action to take.</para>
|
||||
<para>0's represent 6 digit number beginning with 000000.</para>
|
||||
@@ -3767,6 +3770,8 @@ static int action_updateconfig(struct mansession *s, const struct message *m)
|
||||
const char *dfn = astman_get_header(m, "DstFilename");
|
||||
int res;
|
||||
const char *rld = astman_get_header(m, "Reload");
|
||||
int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
|
||||
const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
|
||||
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
|
||||
enum error_type result;
|
||||
|
||||
@@ -3784,7 +3789,10 @@ static int action_updateconfig(struct mansession *s, const struct message *m)
|
||||
result = handle_updates(s, m, cfg, dfn);
|
||||
if (!result) {
|
||||
ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
|
||||
res = ast_config_text_file_save(dfn, cfg, "Manager");
|
||||
if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
|
||||
preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
|
||||
}
|
||||
res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
|
||||
ast_config_destroy(cfg);
|
||||
if (res) {
|
||||
astman_send_error(s, m, "Save of config failed");
|
||||
|
Reference in New Issue
Block a user