]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
config: Add option to NOT preserve effective context when changing a template
authorGeorge Joseph <george.joseph@fairview5.com>
Wed, 7 Jan 2015 16:56:59 +0000 (16:56 +0000)
committerGeorge Joseph <george.joseph@fairview5.com>
Wed, 7 Jan 2015 16:56:59 +0000 (16:56 +0000)
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/
........

Merged revisions 430295 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430296 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/config.h
main/config.c
main/manager.c

index 7f0434d888702cd5e4c49b6b39b7f05ad7b7a829..3b46982b20d3c0f5da1a1317d1e2fc5c080e75bc 100644 (file)
@@ -47,6 +47,14 @@ enum {
        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
 #define        CONFIG_STATUS_FILEUNCHANGED     (void *)-1
 #define        CONFIG_STATUS_FILEINVALID       (void *)-2
@@ -86,7 +94,8 @@ struct ast_variable {
 
        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 @@ struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, s
 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));
 
index fe3ad3f9a652d47f2a5b3dcd526272259a5080b0..f454544f2bb3f02033258a09cb2375f6afbca11f 100644 (file)
@@ -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;
index 05ef9a4d2633d3517f503729e06bdf54a9a30f1d..d599a4bde1be5011def334f64f2b5513c5b6cb44 100644 (file)
@@ -420,6 +420,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>
@@ -3775,6 +3778,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;
 
@@ -3792,7 +3797,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");