[asterisk-commits] tilghman: trunk r107231 - in /trunk: ./ include/asterisk/ main/ pbx/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 10 16:48:21 CDT 2008


Author: tilghman
Date: Mon Mar 10 16:48:20 2008
New Revision: 107231

URL: http://svn.digium.com/view/asterisk?view=rev&rev=107231
Log:
(closes issue #6019)
 Reported by: ssokol
 Patches: 
       20080304__bug6019.diff.txt uploaded by Corydon76 (license 14)
 Tested by: putnopvut

Modified:
    trunk/   (props changed)
    trunk/include/asterisk/pbx.h
    trunk/main/pbx.c
    trunk/pbx/pbx_config.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/pbx.h?view=diff&rev=107231&r1=107230&r2=107231
==============================================================================
--- trunk/include/asterisk/pbx.h (original)
+++ trunk/include/asterisk/pbx.h Mon Mar 10 16:48:20 2008
@@ -839,6 +839,11 @@
   the old linear-search algorithm.  Returns previous value. */
 int pbx_set_extenpatternmatchnew(int newval);
 
+/*! Set "overrideswitch" field.  If set and of nonzero length, all contexts
+ * will be tried directly through the named switch prior to any other
+ * matching within that context. */
+void pbx_set_overrideswitch(const char *newval);
+
 /*!
  * \note This function will handle locking the channel as needed.
  */

Modified: trunk/main/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/main/pbx.c?view=diff&rev=107231&r1=107230&r2=107231
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Mon Mar 10 16:48:20 2008
@@ -123,6 +123,8 @@
 struct ast_context;
 struct ast_app;
 
+AST_THREADSTORAGE(switch_data);
+
 /*!
    \brief ast_exten: An extension
 	The dialplan is saved as a linked list with each context
@@ -166,7 +168,6 @@
 	char *data;				/*!< Data load */
 	int eval;
 	AST_LIST_ENTRY(ast_sw) list;
-	char *tmpdata;
 	char stuff[0];
 };
 
@@ -413,6 +414,7 @@
 
 static int autofallthrough = 1;
 static int extenpatternmatchnew = 0;
+static char *overrideswitch = NULL;
 
 /*! \brief Subscription for device state change events */
 static struct ast_event_sub *device_state_sub;
@@ -1644,6 +1646,7 @@
 	struct ast_sw *sw = NULL;
 	struct ast_exten pattern = {NULL, };
 	struct scoreboard score = {0, };
+	struct ast_str *tmpdata = NULL;
 
 	pattern.label = label;
 	pattern.priority = priority;
@@ -1706,6 +1709,65 @@
 	ast_log(LOG_NOTICE,"The Trie we are searching in:\n");
 	log_match_char_tree(tmp->pattern_tree, "::  ");
 #endif
+
+	do {
+		if (!ast_strlen_zero(overrideswitch)) {
+			char *osw = ast_strdupa(overrideswitch), *name;
+			struct ast_switch *asw;
+			ast_switch_f *aswf = NULL;
+			char *datap;
+			int eval = 0;
+
+			name = strsep(&osw, "/");
+			asw = pbx_findswitch(name);
+
+			if (!asw) {
+				ast_log(LOG_WARNING, "No such switch '%s'\n", name);
+				break;
+			}
+
+			if (osw && strchr(osw, '$')) {
+				eval = 1;
+			}
+
+			if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
+				ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!");
+				break;
+			} else if (eval) {
+				/* Substitute variables now */
+				pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len);
+				datap = tmpdata->str;
+			} else {
+				datap = osw;
+			}
+
+			/* equivalent of extension_match_core() at the switch level */
+			if (action == E_CANMATCH)
+				aswf = asw->canmatch;
+			else if (action == E_MATCHMORE)
+				aswf = asw->matchmore;
+			else /* action == E_MATCH */
+				aswf = asw->exists;
+			if (!aswf) {
+				res = 0;
+			} else {
+				if (chan) {
+					ast_autoservice_start(chan);
+				}
+				res = aswf(chan, context, exten, priority, callerid, datap);
+				if (chan) {
+					ast_autoservice_stop(chan);
+				}
+			}
+			if (res) {	/* Got a match */
+				q->swo = asw;
+				q->data = datap;
+				q->foundcontext = context;
+				/* XXX keep status = STATUS_NO_CONTEXT ? */
+				return NULL;
+			}
+		}
+	} while (0);
 
 	if (extenpatternmatchnew) {
 		new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid);
@@ -1828,8 +1890,13 @@
 		}
 		/* Substitute variables now */
 		
-		if (sw->eval)
-			pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
+		if (sw->eval) {
+			if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
+				ast_log(LOG_WARNING, "Can't evaluate switch?!");
+				continue;
+			}
+			pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len);
+		}
 
 		/* equivalent of extension_match_core() at the switch level */
 		if (action == E_CANMATCH)
@@ -1838,7 +1905,7 @@
 			aswf = asw->matchmore;
 		else /* action == E_MATCH */
 			aswf = asw->exists;
-		datap = sw->eval ? sw->tmpdata : sw->data;
+		datap = sw->eval ? tmpdata->str : sw->data;
 		if (!aswf)
 			res = 0;
 		else {
@@ -3618,6 +3685,18 @@
 	return oldval;
 }
 
+void pbx_set_overrideswitch(const char *newval)
+{
+	if (overrideswitch) {
+		ast_free(overrideswitch);
+	}
+	if (!ast_strlen_zero(newval)) {
+		overrideswitch = ast_strdup(newval);
+	} else {
+		overrideswitch = NULL;
+	}
+}
+
 /*!
  * \brief lookup for a context with a given name,
  * \retval with conlock held if found.
@@ -5781,11 +5860,6 @@
 	if (data)
 		length += strlen(data);
 	length++;
-	if (eval) {
-		/* Create buffer for evaluation of variables */
-		length += SWITCH_DATA_LENGTH;
-		length++;
-	}
 
 	/* allocate new sw structure ... */
 	if (!(new_sw = ast_calloc(1, length)))
@@ -5803,8 +5877,6 @@
 		strcpy(new_sw->data, "");
 		p++;
 	}
-	if (eval)
-		new_sw->tmpdata = p;
 	new_sw->eval	  = eval;
 	new_sw->registrar = registrar;
 

Modified: trunk/pbx/pbx_config.c
URL: http://svn.digium.com/view/asterisk/trunk/pbx/pbx_config.c?view=diff&rev=107231&r1=107230&r2=107231
==============================================================================
--- trunk/pbx/pbx_config.c (original)
+++ trunk/pbx/pbx_config.c Mon Mar 10 16:48:20 2008
@@ -47,6 +47,7 @@
 static int autofallthrough_config = 1;
 static int clearglobalvars_config = 0;
 static int extenpatternmatchnew_config = 0;
+static char *overrideswitch_config = NULL;
 
 AST_MUTEX_DEFINE_STATIC(save_dialplan_lock);
 
@@ -701,7 +702,7 @@
  */
 static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	char filename[256];
+	char filename[256], overrideswitch[256] = "";
 	struct ast_context *c;
 	struct ast_config *cfg;
 	struct ast_variable *v;
@@ -781,11 +782,15 @@
 	}
 
 	/* fireout general info */
-	fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\nextenpatternmatchnew=%s\n\n",
+	if (overrideswitch_config) {
+		snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config);
+	}
+	fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n",
 		static_config ? "yes" : "no",
 		write_protect_config ? "yes" : "no",
                 autofallthrough_config ? "yes" : "no",
 				clearglobalvars_config ? "yes" : "no",
+				overrideswitch_config ? overrideswitch : "",
 				extenpatternmatchnew_config ? "yes" : "no");
 
 	if ((v = ast_variable_browse(cfg, "globals"))) {
@@ -1353,6 +1358,9 @@
 {
 	if (static_config && !write_protect_config)
 		ast_cli_unregister(&cli_dialplan_save);
+	if (overrideswitch_config) {
+		ast_free(overrideswitch_config);
+	}
 	ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
 	ast_context_destroy(NULL, registrar);
 	return 0;
@@ -1369,7 +1377,7 @@
 	struct ast_variable *v;
 	const char *cxt;
 	const char *aft;
-	const char *newpm;
+	const char *newpm, *ovsw;
 	struct ast_flags config_flags = { 0 };
 	cfg = ast_config_load(config_file, config_flags);
 	if (!cfg)
@@ -1383,7 +1391,16 @@
 	if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
 		extenpatternmatchnew_config = ast_true(newpm);
 	clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
-	
+	if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) {
+		if (overrideswitch_config) {
+			ast_free(overrideswitch_config);
+		}
+		if (!ast_strlen_zero(ovsw)) {
+			overrideswitch_config = ast_strdup(ovsw);
+		} else {
+			overrideswitch_config = NULL;
+		}
+	}
 
 	if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 
 		ast_copy_string(userscontext, cxt, sizeof(userscontext));
@@ -1640,6 +1657,7 @@
 	for (con = NULL; (con = ast_walk_contexts(con));)
 		ast_context_verify_includes(con);
 
+	pbx_set_overrideswitch(overrideswitch_config);
 	pbx_set_autofallthrough(autofallthrough_config);
 	pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);
 




More information about the asterisk-commits mailing list