diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2d37862568..3d9d80b205 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -15073,7 +15073,7 @@ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *messa static int manager_sipnotify(struct mansession *s, const struct message *m) { const char *channame = astman_get_header(m, "Channel"); - struct ast_variable *vars = astman_get_variables(m); + struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL); struct sip_pvt *p; struct ast_variable *header, *var; diff --git a/include/asterisk/config.h b/include/asterisk/config.h index 1c10d176bc..2579ef2795 100644 --- a/include/asterisk/config.h +++ b/include/asterisk/config.h @@ -559,6 +559,16 @@ int ast_realtime_enabled(void); */ struct ast_variable *ast_variables_dup(struct ast_variable *var); +/*! + * \brief Reverse a variable list + * \param var the linked list of variables to reverse + * \return The head of the reversed variable list + * + * \note The variable list var is not preserved in this function and should + * not be used after reversing it. + */ +struct ast_variable *ast_variables_reverse(struct ast_variable *var); + /*! * \brief Free variable list * \param var the linked list of variables to free diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h index 42ff31a456..978151ab1b 100644 --- a/include/asterisk/manager.h +++ b/include/asterisk/manager.h @@ -260,9 +260,21 @@ int __ast_manager_event_multichan(int category, const char *event, int chancount /*! \brief Get header from mananger transaction */ const char *astman_get_header(const struct message *m, char *var); -/*! \brief Get a linked list of the Variable: headers */ +/*! \brief Get a linked list of the Variable: headers + * + * \note Order of variables is reversed from the order they are specified in + * the manager message + */ struct ast_variable *astman_get_variables(const struct message *m); +enum variable_orders { + ORDER_NATURAL, + ORDER_REVERSE +}; + +/*! \brief Get a linked list of the Variable: headers with order specified */ +struct ast_variable *astman_get_variables_order(const struct message *m, enum variable_orders order); + /*! \brief Send error in manager transaction */ void astman_send_error(struct mansession *s, const struct message *m, char *error); diff --git a/main/config.c b/main/config.c index aee81e3ff7..d9bef2e1b3 100644 --- a/main/config.c +++ b/main/config.c @@ -562,6 +562,30 @@ struct ast_variable *ast_variables_dup(struct ast_variable *var) return cloned; } +struct ast_variable *ast_variables_reverse(struct ast_variable *var) +{ + struct ast_variable *var1, *var2; + + var1 = var; + + if (!var1 || !var1->next) { + return var1; + } + + var2 = var1->next; + var1->next = NULL; + + while (var2) { + struct ast_variable *next = var2->next; + + var2->next = var1; + var1 = var2; + var2 = next; + } + + return var1; +} + void ast_variables_destroy(struct ast_variable *v) { struct ast_variable *vn; diff --git a/main/manager.c b/main/manager.c index cb2b0bbe25..09d49f002d 100644 --- a/main/manager.c +++ b/main/manager.c @@ -2389,6 +2389,12 @@ static struct ast_variable *man_do_variable_value(struct ast_variable *head, con } struct ast_variable *astman_get_variables(const struct message *m) +{ + return astman_get_variables_order(m, ORDER_REVERSE); +} + +struct ast_variable *astman_get_variables_order(const struct message *m, + enum variable_orders order) { int varlen; int x; @@ -2405,6 +2411,10 @@ struct ast_variable *astman_get_variables(const struct message *m) head = man_do_variable_value(head, m->headers[x] + varlen); } + if (order == ORDER_NATURAL) { + head = ast_variables_reverse(head); + } + return head; }