]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
channels: Allow updating variable value
authorSean Bright <sean.bright@gmail.com>
Wed, 11 Sep 2019 20:58:29 +0000 (16:58 -0400)
committerSean Bright <sean.bright@gmail.com>
Thu, 12 Sep 2019 20:58:17 +0000 (15:58 -0500)
When modifying an already defined variable in some channel drivers they
add a new variable with the same name to the list, but that value is
never used, only the first one found.

Introduce ast_variable_list_replace() and use it where appropriate.

ASTERISK-23756 #close
Patches:
  setvar-multiplie.patch submitted by Michael Goryainov

Change-Id: Ie1897a96c82b8945e752733612ee963686f32839

channels/chan_dahdi.c
channels/chan_iax2.c
channels/chan_sip.c
include/asterisk/config.h
main/config.c
res/res_pjsip/pjsip_configuration.c

index 1a3b1583090feffda049faf8f6ef8422f1cf3a02..5ff12c65a6b29068dafa6f6145c1071ecac882ba 100644 (file)
@@ -12873,8 +12873,10 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
                        struct ast_variable *v, *tmpvar;
                        for (v = conf->chan.vars ; v ; v = v->next) {
                                if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
-                                       tmpvar->next = tmp->vars;
-                                       tmp->vars = tmpvar;
+                                       if (ast_variable_list_replace(&tmp->vars, tmpvar)) {
+                                               tmpvar->next = tmp->vars;
+                                               tmp->vars = tmpvar;
+                                       }
                                }
                        }
                }
index 3bf06d06ec0b381e6d907f103fba8fb65da0bd34..81bdf154f4782a6b72c6acd0f7b3ef95cd513207 100644 (file)
@@ -7941,9 +7941,11 @@ static int check_access(int callno, struct ast_sockaddr *addr, struct iax_ies *i
                /* We found our match (use the first) */
                /* copy vars */
                for (v = user->vars ; v ; v = v->next) {
-                       if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
-                               tmpvar->next = iaxs[callno]->vars;
-                               iaxs[callno]->vars = tmpvar;
+                       if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
+                               if (ast_variable_list_replace(&iaxs[callno]->vars, tmpvar)) {
+                                       tmpvar->next = iaxs[callno]->vars;
+                                       iaxs[callno]->vars = tmpvar;
+                               }
                        }
                }
                /* If a max AUTHREQ restriction is in place, activate it */
@@ -13212,9 +13214,11 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, st
                                if ((varval = strchr(varname, '='))) {
                                        *varval = '\0';
                                        varval++;
-                                       if((tmpvar = ast_variable_new(varname, varval, ""))) {
-                                               tmpvar->next = user->vars;
-                                               user->vars = tmpvar;
+                                       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
+                                               if (ast_variable_list_replace(&user->vars, tmpvar)) {
+                                                       tmpvar->next = user->vars;
+                                                       user->vars = tmpvar;
+                                               }
                                        }
                                }
                        } else if (!strcasecmp(v->name, "allow")) {
index 223ff3c85b0d26ad8ed9b6becee2c5e8135ba6f0..ea78d23a866ae9ee49c2ded600c8204d92a6cde3 100644 (file)
@@ -31126,8 +31126,10 @@ static struct ast_variable *add_var(const char *buf, struct ast_variable *list)
        if ((varval = strchr(varname, '='))) {
                *varval++ = '\0';
                if ((tmpvar = ast_variable_new(varname, varval, ""))) {
-                       tmpvar->next = list;
-                       list = tmpvar;
+                       if (ast_variable_list_replace(&list, tmpvar)) {
+                               tmpvar->next = list;
+                               list = tmpvar;
+                       }
                }
        }
        return list;
index 5ab1f683f8cfa8d6edad0d9f669c37c3e5e97f1d..04b858afea7e798ceea7ebb341c8f8312cff3fef 100644 (file)
@@ -960,6 +960,24 @@ struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, s
        struct ast_variable *new_var);
 #define ast_variable_list_append(head, new_var) ast_variable_list_append_hint(head, NULL, new_var)
 
+/*!
+ * \brief Replace a variable in the given list with a new value
+ * \since 13.30.0
+ *
+ * \param head A pointer to an ast_variable * of the existing variable list head. May NOT be NULL
+ * but the content may be to initialize a new list.  If so, upon return, this parameter will be updated
+ * with a pointer to the new list head.
+ * \param replacement The variable that replaces another variable in the list with the
+ * same name.
+ *
+ * \retval 0 if a variable was replaced in the list
+ * \retval -1 if no replacement occured
+ *
+ * \note The variable name comparison is performed case-sensitively
+ * \note If a variable is replaced, its memory is freed.
+ */
+int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement);
+
 /*!
  * \brief Update variable value within a config
  *
index 0267979e8c3a7df78e5964be7ddb29c46d288c29..8731ebb40dd35f3a40e3030f21805a729ab241c4 100644 (file)
@@ -669,6 +669,22 @@ struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, s
        return curr;
 }
 
+int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
+{
+       struct ast_variable *v, **prev = head;
+
+       for (v = *head; v; prev = &v->next, v = v->next) {
+               if (!strcmp(v->name, replacement->name)) {
+                       replacement->next = v->next;
+                       *prev = replacement;
+                       ast_free(v);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
 {
        const char *tmp;
index 4f7beb6098ece5d4c2d07c1c6859d1f787293878..b5525beeb2e75f074f515f157cf01b1a7e9db1b0 100644 (file)
@@ -1036,7 +1036,9 @@ static int set_var_handler(const struct aco_option *opt,
                return -1;
        }
 
-       ast_variable_list_append(&endpoint->channel_vars, new_var);
+       if (ast_variable_list_replace(&endpoint->channel_vars, new_var)) {
+               ast_variable_list_append(&endpoint->channel_vars, new_var);
+       }
 
        return 0;
 }