aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-25 21:21:33 +0000
committermurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-25 21:21:33 +0000
commit845b84d2fd5cb2f2966a02a3f5fcf8d813647c86 (patch)
treeef591875baea46ffc7484a2f500059dd0a4180e2
parente0ec65d0cdbf99de014aa6e474a2447914ebc944 (diff)
Merged revisions 144523 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r144523 | murf | 2008-09-25 15:18:12 -0600 (Thu, 25 Sep 2008) | 13 lines I added a little verbage to hashtab for the hashtab_destroy func. It was pretty sparsely documented. This update fleshes out the pbx_lua module, to add the switch statements to the extensions in the extensions.lua file, as well as removing them when the module is unloaded. Many thanks to Matt Nicholson for his fine contribution! ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@144524 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--configs/extensions.lua.sample9
-rw-r--r--include/asterisk/hashtab.h6
-rw-r--r--pbx/pbx_lua.c78
3 files changed, 82 insertions, 11 deletions
diff --git a/configs/extensions.lua.sample b/configs/extensions.lua.sample
index 8aee734b4..44b9b81b5 100644
--- a/configs/extensions.lua.sample
+++ b/configs/extensions.lua.sample
@@ -18,15 +18,6 @@ TRUNKMSD = 1
-- representing a context. Extensions are defined in each context. See below
-- for examples.
--
--- This file can be automatically included in the extensions.conf file using
--- the 'utils/build-extensions-conf.lua' script and a #exec statement in
--- extensions.conf.
---
--- #exec /usr/bin/utils/build-extensions.conf.lua -c
---
--- The 'execincludes' option must be set to 'yes' in the [options] section of
--- asterisk.conf for this to work properly.
---
-- Extension names may be numbers, letters, or combinations thereof. If
-- an extension name is prefixed by a '_' character, it is interpreted as
-- a pattern rather than a literal. In patterns, some characters have
diff --git a/include/asterisk/hashtab.h b/include/asterisk/hashtab.h
index ed9a95e84..aa4dc59db 100644
--- a/include/asterisk/hashtab.h
+++ b/include/asterisk/hashtab.h
@@ -198,7 +198,11 @@ struct ast_hashtab * ast_hashtab_create(int initial_buckets,
/*!
* \brief This func will free the hash table and all its memory.
- * \note It doesn't touch the objects stored in it
+ * \note It doesn't touch the objects stored in it, unless you
+ * specify a destroy func; it will call that func for each
+ * object in the hashtab, remove all the objects, and then
+ * free the hashtab itself. If no destroyfunc is specified
+ * then the routine will assume you will free it yourself.
* \param tab
* \param objdestroyfunc
*/
diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c
index 78fa872ac..9d95dc985 100644
--- a/pbx/pbx_lua.c
+++ b/pbx/pbx_lua.c
@@ -40,12 +40,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/utils.h"
#include "asterisk/term.h"
#include "asterisk/paths.h"
+#include "asterisk/hashtab.h"
#include <lua5.1/lua.h>
#include <lua5.1/lauxlib.h>
#include <lua5.1/lualib.h>
static char *config = "extensions.lua";
+static char *registrar = "pbx_lua";
#define LUA_EXT_DATA_SIZE 256
#define LUA_BUF_SIZE 4096
@@ -55,6 +57,7 @@ static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
static int lua_reload_extensions(lua_State *L);
static void lua_free_extensions(void);
static int lua_sort_extensions(lua_State *L);
+static int lua_register_switches(lua_State *L);
static int lua_extension_cmp(lua_State *L);
static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
static int lua_pbx_findapp(lua_State *L);
@@ -92,6 +95,9 @@ AST_MUTEX_DEFINE_STATIC(config_file_lock);
char *config_file_data = NULL;
long config_file_size = 0;
+static struct ast_context *local_contexts = NULL;
+static struct ast_hashtab *local_table = NULL;
+
static const struct ast_datastore_info lua_datastore = {
.type = "lua",
.destroy = lua_state_destroy,
@@ -789,6 +795,65 @@ static int lua_sort_extensions(lua_State *L)
}
/*!
+ * \brief Register dialplan switches for our pbx_lua contexs.
+ *
+ * In the event of an error, an error string will be pushed onto the lua stack.
+ *
+ * \retval 0 success
+ * \retval 1 failure
+ */
+static int lua_register_switches(lua_State *L)
+{
+ int extensions;
+ struct ast_context *con = NULL;
+
+ /* create the hash table for our contexts */
+ /* XXX do we ever need to destroy this? pbx_config does not */
+ if (!local_table)
+ local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
+
+ /* load the 'extensions' table */
+ lua_getglobal(L, "extensions");
+ extensions = lua_gettop(L);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
+ return 1;
+ }
+
+ /* iterate through the extensions table and register a context and
+ * dialplan switch for each lua context
+ */
+ for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
+ int context = lua_gettop(L);
+ int context_name = context - 1;
+ const char *context_str = lua_tostring(L, context_name);
+
+ /* find or create this context */
+ con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
+ if (!con) {
+ /* remove extensions table and context key and value */
+ lua_pop(L, 3);
+ lua_pushstring(L, "Failed to find or create context\n");
+ return 1;
+ }
+
+ /* register the switch */
+ if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
+ /* remove extensions table and context key and value */
+ lua_pop(L, 3);
+ lua_pushstring(L, "Unable to create switch for context\n");
+ return 1;
+ }
+ }
+
+ /* remove the extensions table */
+ lua_pop(L, 1);
+ return 0;
+}
+
+
+/*!
* \brief [lua_CFunction] Compare two extensions (for access from lua, don't
* call directly)
*
@@ -852,7 +917,8 @@ static char *lua_read_extensions_file(lua_State *L, long *size)
if (luaL_loadbuffer(L, data, *size, "extensions.lua")
|| lua_pcall(L, 0, LUA_MULTRET, 0)
- || lua_sort_extensions(L)) {
+ || lua_sort_extensions(L)
+ || lua_register_switches(L)) {
ast_free(data);
data = NULL;
*size = 0;
@@ -933,6 +999,15 @@ static int lua_reload_extensions(lua_State *L)
config_file_data = data;
config_file_size = size;
+
+ /* merge our new contexts */
+ ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
+ /* merge_contexts_and_delete will actually, at the correct moment,
+ set the global dialplan pointers to your local_contexts and local_table.
+ It then will free up the old tables itself. Just be sure not to
+ hang onto the pointers. */
+ local_table = NULL;
+ local_contexts = NULL;
ast_mutex_unlock(&config_file_lock);
return 0;
@@ -1320,6 +1395,7 @@ static int load_or_reload_lua_stuff(void)
static int unload_module(void)
{
+ ast_context_destroy(NULL, registrar);
ast_unregister_switch(&lua_switch);
lua_free_extensions();
return 0;