Author: gtjoseph Date: Wed Jan 7 10:55:14 2015 New Revision: 430295 URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=430295 Log: 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/ Modified: branches/13/include/asterisk/config.h branches/13/main/config.c branches/13/main/manager.c Modified: branches/13/include/asterisk/config.h URL: http://svnview.digium.com/svn/asterisk/branches/13/include/asterisk/config.h?view=diff&rev=430295&r1=430294&r2=430295 ============================================================================== --- branches/13/include/asterisk/config.h (original) +++ branches/13/include/asterisk/config.h Wed Jan 7 10:55:14 2015 @@ -45,6 +45,14 @@ CONFIG_FLAG_NOCACHE = (1 << 2), /*! Don't attempt to load from realtime (typically called from a realtime driver dependency) */ CONFIG_FLAG_NOREALTIME = (1 << 3), +}; + +/*! Flags for ast_config_text_file_save2() + */ +enum config_save_flags { + CONFIG_SAVE_FLAG_NONE = (0), + /*! Insure a context doesn't effectively change if a template changes (pre 13.2 behavior) */ + CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT = (1 << 0), }; #define CONFIG_STATUS_FILEMISSING (void *)0 @@ -86,7 +94,8 @@ int lineno; int object; /*!< 0 for variable, 1 for object */ - int blanklines; /*!< Number of blanklines following entry */ + int blanklines; /*!< Number of blanklines following entry */ + int inherited; /*!< 1 for inherited from template or other base */ 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 */ @@ -907,6 +916,28 @@ int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object); +/*! + * \brief Save a config text file + * \since 13.2.0 + * + * \param filename Filename + * \param cfg ast_config + * \param generator generator + * \param flags List of config_save_flags + * + * \return 0 on success or -1 on failure. + */ +int ast_config_text_file_save2(const char *filename, const struct ast_config *cfg, const char *generator, uint32_t flags); + +/*! + * \brief Save a config text file preserving the pre 13.2 behavior + * + * \param filename Filename + * \param cfg ast_config + * \param generator generator + * + * \return 0 on success or -1 on failure. + */ int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator); int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator) __attribute__((deprecated)); Modified: branches/13/main/config.c URL: http://svnview.digium.com/svn/asterisk/branches/13/main/config.c?view=diff&rev=430295&r1=430294&r2=430295 ============================================================================== --- branches/13/main/config.c (original) +++ branches/13/main/config.c Wed Jan 7 10:55:14 2015 @@ -1250,8 +1250,11 @@ 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 @@ 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 @@ 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; Modified: branches/13/main/manager.c URL: http://svnview.digium.com/svn/asterisk/branches/13/main/manager.c?view=diff&rev=430295&r1=430294&r2=430295 ============================================================================== --- branches/13/main/manager.c (original) +++ branches/13/main/manager.c Wed Jan 7 10:55:14 2015 @@ -411,6 +411,9 @@ </parameter> <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> @@ -3767,6 +3770,8 @@ 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 @@ 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"); -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- svn-commits mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/svn-commits
