summaryrefslogtreecommitdiff
path: root/pbx/pbx_lua.c
diff options
context:
space:
mode:
authorMatthew Nicholson <mnicholson@digium.com>2011-05-06 18:04:23 +0000
committerMatthew Nicholson <mnicholson@digium.com>2011-05-06 18:04:23 +0000
commitbccba53bcff743512c4c70265cad46fc034288fc (patch)
treee6548a4ae984f4b2d5f96d9c90b9324ba18b2a6d /pbx/pbx_lua.c
parent307f148adb3fd9400969e6b7e9f6c231920b0fcd (diff)
Detect Goto in pbx_lua.
This code will actually detect any dialplan jump from any application that calls ast_explicit_goto(). This change is only being done in trunk as it may change the way some dialplans execute. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@317721 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'pbx/pbx_lua.c')
-rw-r--r--pbx/pbx_lua.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c
index b181b3b78..61f93ab63 100644
--- a/pbx/pbx_lua.c
+++ b/pbx/pbx_lua.c
@@ -52,6 +52,11 @@ static char *registrar = "pbx_lua";
#define LUA_EXT_DATA_SIZE 256
#define LUA_BUF_SIZE 4096
+/* This value is used by the lua engine to signal that a Goto or dialplan jump
+ * was detected. Ensure this value does not conflict with any values dialplan
+ * applications might return */
+#define LUA_GOTO_DETECTED 5
+
static char *lua_read_extensions_file(lua_State *L, long *size);
static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
static int lua_reload_extensions(lua_State *L);
@@ -84,6 +89,7 @@ static void lua_create_variable_metatable(lua_State *L);
static void lua_create_application_metatable(lua_State *L);
static void lua_create_autoservice_functions(lua_State *L);
static void lua_create_hangup_function(lua_State *L);
+static void lua_detect_goto(lua_State *L);
static void lua_state_destroy(void *data);
static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
@@ -254,10 +260,73 @@ static int lua_pbx_exec(lua_State *L)
lua_pushinteger(L, res);
return lua_error(L);
}
+
+ lua_detect_goto(L);
+
return 0;
}
/*!
+ * \brief Detect if a Goto or other dialplan jump has been executed and return
+ * control to the pbx engine.
+ */
+static void lua_detect_goto(lua_State *L)
+{
+ struct ast_channel *chan;
+
+ lua_getfield(L, LUA_REGISTRYINDEX, "channel");
+ chan = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ /* check context */
+ lua_getfield(L, LUA_REGISTRYINDEX, "context");
+ lua_pushstring(L, chan->context);
+ if (!lua_equal(L, -1, -2)) {
+ lua_pushliteral(L, "context");
+ goto e_goto_detected;
+ }
+ lua_pop(L, 2);
+
+ /* check exten */
+ lua_getfield(L, LUA_REGISTRYINDEX, "exten");
+ lua_pushstring(L, chan->exten);
+ if (!lua_equal(L, -1, -2)) {
+ lua_pushliteral(L, "exten");
+ goto e_goto_detected;
+ }
+ lua_pop(L, 2);
+
+ /* check priority */
+ lua_getfield(L, LUA_REGISTRYINDEX, "priority");
+ lua_pushinteger(L, chan->priority);
+ if (!lua_equal(L, -1, -2)) {
+ lua_pushliteral(L, "priority");
+ goto e_goto_detected;
+ }
+ lua_pop(L, 2);
+ return;
+
+e_goto_detected:
+ /* format our debug message */
+ lua_insert(L, -3);
+
+ lua_pushliteral(L, " changed from ");
+ lua_insert(L, -3);
+
+ lua_pushliteral(L, " to ");
+ lua_insert(L, -2);
+
+ lua_concat(L, 5);
+
+ ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+
+ /* let the lua engine know it needs to return control to the pbx */
+ lua_pushinteger(L, LUA_GOTO_DETECTED);
+ lua_error(L);
+}
+
+/*!
* \brief [lua_CFunction] Used to get the value of a variable or dialplan
* function (for access from lua, don't call directly)
*
@@ -1372,6 +1441,10 @@ static int exec(struct ast_channel *chan, const char *context, const char *exten
res = -1;
if (lua_isnumber(L, -1)) {
res = lua_tointeger(L, -1);
+
+ if (res == LUA_GOTO_DETECTED) {
+ res = 0;
+ }
} else if (lua_isstring(L, -1)) {
const char *error = lua_tostring(L, -1);
ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);