[Asterisk-code-review] config: Allow filters when appending to a category (asterisk[master])

Joshua Colp asteriskteam at digium.com
Tue Apr 5 16:38:12 CDT 2016


Joshua Colp has submitted this change and it was merged.

Change subject: config:  Allow filters when appending to a category
......................................................................


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
---
M main/config.c
1 file changed, 23 insertions(+), 10 deletions(-)

Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved; Verified



diff --git a/main/config.c b/main/config.c
index a9ea01a..dad3b66 100644
--- a/main/config.c
+++ b/main/config.c
@@ -72,7 +72,8 @@
 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 @@
 /*! \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 @@
 
 	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,24 +984,30 @@
 	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;
 		}
 	}
 
 	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)
@@ -1125,7 +1133,7 @@
 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 @@
 			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);

-- 
To view, visit https://gerrit.asterisk.org/2488
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I10773da4c79db36fbf1993961992af63d3441580
Gerrit-PatchSet: 3
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <george.joseph at fairview5.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-code-review mailing list