[asterisk-commits] murf: trunk r109169 - in /trunk: include/asterisk/pbx.h main/pbx.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 17 12:47:36 CDT 2008


Author: murf
Date: Mon Mar 17 12:47:36 2008
New Revision: 109169

URL: http://svn.digium.com/view/asterisk?view=rev&rev=109169
Log:
(closes issue #12238)
Reported by: mvanbaak
Tested by: murf, mvanbaak

Due to a bug that occurred when merge_contexts_and_delete scanned the "old" or existing contexts, and found a context
that doesn't exist in the new set, yet owned by a different registrar. The context is created in the new set, with the
old registrar, and and all the priorities and extens that have a different registrar are copied into it. But, not the
includes, ignorepats, and switches. I added code to do this immediately after the context is created.

This still leaves a logical hole in the code. If you define a context in two places, (eg. in extensions.conf and also 
in extensions.ael), and they both have includes, but different in composition, no new context will be generated, and
therefore the 'old' includes, switches, and ignorepats will not be copied. I'd have added code to simply add any non-duplicates
into the 'new' context that had a different registrar, but there is one big complication: includes, and switches are definitely
order dependent. (ignorepats I'm not sure about). And we'll have to develop some sort of policy about how we 
merge order dependent lists, especially if the intersection of the two sets is empty. (in other words, they do not have any
elements in common). Do the new go first, or the old? I've elected to punt this issue until a user complains. Hopefully,
this is pretty rare thing.



Modified:
    trunk/include/asterisk/pbx.h
    trunk/main/pbx.c

Modified: trunk/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/pbx.h?view=diff&rev=109169&r1=109168&r2=109169
==============================================================================
--- trunk/include/asterisk/pbx.h (original)
+++ trunk/include/asterisk/pbx.h Mon Mar 17 12:47:36 2008
@@ -758,6 +758,8 @@
 const char *ast_get_ignorepat_name(struct ast_ignorepat *ip);
 const char *ast_get_switch_name(struct ast_sw *sw);
 const char *ast_get_switch_data(struct ast_sw *sw);
+int ast_get_switch_eval(struct ast_sw *sw);
+	
 /*! @} */
 
 /*! @name Other Extension stuff */

Modified: trunk/main/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/main/pbx.c?view=diff&rev=109169&r1=109168&r2=109169
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Mon Mar 17 12:47:36 2008
@@ -5292,6 +5292,36 @@
 
 AST_LIST_HEAD(store_hints, store_hint);
 
+static void context_merge_incls_swits_igps_other_registrars(struct ast_context *new, struct ast_context *old, const char *registrar)
+{
+	struct ast_include *i;
+	struct ast_ignorepat *ip;
+	struct ast_sw *sw;
+	
+	/* copy in the includes, switches, and ignorepats */
+	/* walk through includes */
+	for (i = NULL; (i = ast_walk_context_includes(old, i)) ; ) {
+		if (strcmp(ast_get_include_registrar(i), registrar) == 0)
+			continue; /* not mine */
+		ast_context_add_include2(new, ast_get_include_name(i), ast_get_include_registrar(i));
+	}
+	
+	/* walk through switches */
+	for (sw = NULL; (sw = ast_walk_context_switches(old, sw)) ; ) {
+		if (strcmp(ast_get_switch_registrar(sw), registrar) == 0)
+			continue; /* not mine */
+		ast_context_add_switch2(new, ast_get_switch_name(sw), ast_get_switch_data(sw), ast_get_switch_eval(sw), ast_get_switch_registrar(sw));
+	}
+	
+	/* walk thru ignorepats ... */
+	for (ip = NULL; (ip = ast_walk_context_ignorepats(old, ip)); ) {
+		if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0)
+			continue; /* not mine */
+		ast_context_add_ignorepat2(new, ast_get_ignorepat_name(ip), ast_get_ignorepat_registrar(ip));
+	}
+}
+
+
 /* the purpose of this routine is to duplicate a context, with all its substructure,
    except for any extens that have a matching registrar */
 static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
@@ -5329,6 +5359,9 @@
 				/* make sure the new context exists, so we have somewhere to stick this exten/prio */
 				if (!new) {
 					new = ast_context_find_or_create(extcontexts, exttable, context->name, prio_item->registrar); /* a new context created via priority from a different context in the old dialplan, gets its registrar from the prio's registrar */
+
+					/* copy in the includes, switches, and ignorepats */
+					context_merge_incls_swits_igps_other_registrars(new, context, registrar);
 				}
 				if (!new) {
 					ast_log(LOG_ERROR,"Could not allocate a new context for %s in merge_and_delete! Danger!\n", context->name);
@@ -5357,6 +5390,9 @@
 		/* we could have given it the registrar of the other module who incremented the refcount,
 		   but that's not available, so we give it the registrar we know about */
 		new = ast_context_find_or_create(extcontexts, exttable, context->name, context->registrar);
+		
+		/* copy in the includes, switches, and ignorepats */
+		context_merge_incls_swits_igps_other_registrars(new, context, registrar);
 	}
 }
 
@@ -7945,6 +7981,11 @@
 	return sw ? sw->data : NULL;
 }
 
+int ast_get_switch_eval(struct ast_sw *sw)
+{
+	return sw->eval;
+}
+
 const char *ast_get_switch_registrar(struct ast_sw *sw)
 {
 	return sw ? sw->registrar : NULL;




More information about the asterisk-commits mailing list