diff options
author | George Joseph <george.joseph@fairview5.com> | 2016-03-27 22:33:29 -0600 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2016-04-05 11:23:50 -0500 |
commit | 50b0922a22ec4ab42dca4bbc89fa49c8e1f5dd23 (patch) | |
tree | b2d78d9814b90a60ab3489c830e0ae72cce3ed75 /main/config.c | |
parent | cac6453e9a9cbc8996769550f0de29d92a0aff56 (diff) |
config: Allow filters when appending to a category
In sorcery based config files where there are multiple categories with the same
name, you can't use the (+) operator to reliably append to a category because
config.c stops looking when it finds the first one with the same name.
Example:
[1000]
type = endpoint
[1000]
type = aor
[1000](+)
authenticate_qualify = yes
This config will fail because config.c appends authenticate_qualify to the
first category it finds, the endpoint, and that's not valid for endpoint.
Solution:
The capability to find a category that contains a certain variable already
exists so the only real change was to parse anything after the '+' that's not a
comma, as a filter string.
[1000]
type = endpoint
[1000]
type = aor
[1000](+type=aor)
authenticate_qualify = yes
This now works as expected.
Although the following example doesn't make any sense for pjsip, you can even
specify multiple filters:
[1000](+type=aor&qualify_frequency=10)
ASTERISK-25868 #close
Reported-by: Nick Repin
Change-Id: I10773da4c79db36fbf1993961992af63d3441580
Diffstat (limited to 'main/config.c')
-rw-r--r-- | main/config.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/main/config.c b/main/config.c index 69621868c..2a6baa133 100644 --- a/main/config.c +++ b/main/config.c @@ -72,7 +72,8 @@ static char *extconfig_conf = "extconfig.conf"; static struct ao2_container *cfg_hooks; static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg); static inline struct ast_variable *variable_list_switch(struct ast_variable *l1, struct ast_variable *l2); -static int does_category_match(struct ast_category *cat, const char *category_name, const char *match); +static int does_category_match(struct ast_category *cat, const char *category_name, + const char *match, char sep); /*! \brief Structure to keep comments for rewriting configuration files */ struct ast_comment { @@ -864,7 +865,8 @@ static void move_variables(struct ast_category *old, struct ast_category *new) /*! \brief Returns true if ALL of the regex expressions and category name match. * Both can be NULL (I.E. no predicate) which results in a true return; */ -static int does_category_match(struct ast_category *cat, const char *category_name, const char *match) +static int does_category_match(struct ast_category *cat, const char *category_name, + const char *match, char sep) { char *dupmatch; char *nvp = NULL; @@ -883,7 +885,7 @@ static int does_category_match(struct ast_category *cat, const char *category_na dupmatch = ast_strdupa(match); - while ((nvp = ast_strsep(&dupmatch, ',', AST_STRSEP_STRIP))) { + while ((nvp = ast_strsep(&dupmatch, sep, AST_STRSEP_STRIP))) { struct ast_variable *v; char *match_name; char *match_value = NULL; @@ -982,19 +984,19 @@ struct ast_category *ast_category_new_template(const char *name, const char *in_ return new_category(name, in_file, lineno, 1); } -struct ast_category *ast_category_get(const struct ast_config *config, - const char *category_name, const char *filter) +static struct ast_category *category_get_sep(const struct ast_config *config, + const char *category_name, const char *filter, char sep) { struct ast_category *cat; for (cat = config->root; cat; cat = cat->next) { - if (cat->name == category_name && does_category_match(cat, category_name, filter)) { + if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) { return cat; } } for (cat = config->root; cat; cat = cat->next) { - if (does_category_match(cat, category_name, filter)) { + if (does_category_match(cat, category_name, filter, sep)) { return cat; } } @@ -1002,6 +1004,12 @@ struct ast_category *ast_category_get(const struct ast_config *config, return NULL; } +struct ast_category *ast_category_get(const struct ast_config *config, + const char *category_name, const char *filter) +{ + return category_get_sep(config, category_name, filter, ','); +} + const char *ast_category_get_name(const struct ast_category *category) { return category->name; @@ -1125,7 +1133,7 @@ static void ast_includes_destroy(struct ast_config_include *incls) static struct ast_category *next_available_category(struct ast_category *cat, const char *name, const char *filter) { - for (; cat && !does_category_match(cat, name, filter); cat = cat->next); + for (; cat && !does_category_match(cat, name, filter, ','); cat = cat->next); return cat; } @@ -1777,8 +1785,13 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, while ((cur = strsep(&c, ","))) { if (!strcasecmp(cur, "!")) { (*cat)->ignored = 1; - } else if (!strcasecmp(cur, "+")) { - *cat = ast_category_get(cfg, catname, NULL); + } else if (cur[0] == '+') { + char *filter = NULL; + + if (cur[1] != ',') { + filter = &cur[1]; + } + *cat = category_get_sep(cfg, catname, filter, '&'); if (!(*cat)) { if (newcat) { ast_category_destroy(newcat); |