aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-25 21:18:12 +0000
committermurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-25 21:18:12 +0000
commitdb4e1bcd922e2e3d768a3ec4578323c5da338b6a (patch)
tree29d51cd3fd88938af7fa60efc4c4cc775db31319
parent9a47c54777d45cd0c6a0cfd786e318b87365be49 (diff)
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/trunk@144523 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 6a98e302a..13158d758 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;