Sun Oct 16 2011 08:41:43

Asterisk developer's documentation


pbx_lua.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2007, Digium, Inc.
00005  *
00006  * Matthew Nicholson <mnicholson@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! 
00020  * \file
00021  *
00022  * \author Matthew Nicholson <mnicholson@digium.com>
00023  * \brief Lua PBX Switch
00024  *
00025  */
00026 
00027 /*** MODULEINFO
00028    <depend>lua</depend>
00029    <support_level>extended</support_level>
00030  ***/
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00035 
00036 #include "asterisk/logger.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/cli.h"
00041 #include "asterisk/utils.h"
00042 #include "asterisk/term.h"
00043 #include "asterisk/paths.h"
00044 #include "asterisk/hashtab.h"
00045 
00046 #include <lua.h>
00047 #include <lauxlib.h>
00048 #include <lualib.h>
00049 
00050 static char *config = "extensions.lua";
00051 static char *registrar = "pbx_lua";
00052 
00053 #define LUA_EXT_DATA_SIZE 256
00054 #define LUA_BUF_SIZE 4096
00055 
00056 static char *lua_read_extensions_file(lua_State *L, long *size);
00057 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
00058 static int lua_reload_extensions(lua_State *L);
00059 static void lua_free_extensions(void);
00060 static int lua_sort_extensions(lua_State *L);
00061 static int lua_register_switches(lua_State *L);
00062 static int lua_extension_cmp(lua_State *L);
00063 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
00064 static int lua_pbx_findapp(lua_State *L);
00065 static int lua_pbx_exec(lua_State *L);
00066 
00067 static int lua_get_variable_value(lua_State *L);
00068 static int lua_set_variable_value(lua_State *L);
00069 static int lua_get_variable(lua_State *L);
00070 static int lua_set_variable(lua_State *L);
00071 static int lua_func_read(lua_State *L);
00072 
00073 static int lua_autoservice_start(lua_State *L);
00074 static int lua_autoservice_stop(lua_State *L);
00075 static int lua_autoservice_status(lua_State *L);
00076 static int lua_check_hangup(lua_State *L);
00077 static int lua_error_function(lua_State *L);
00078 
00079 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
00080 static void lua_push_variable_table(lua_State *L, const char *name);
00081 static void lua_create_app_table(lua_State *L);
00082 static void lua_create_channel_table(lua_State *L);
00083 static void lua_create_variable_metatable(lua_State *L);
00084 static void lua_create_application_metatable(lua_State *L);
00085 static void lua_create_autoservice_functions(lua_State *L);
00086 static void lua_create_hangup_function(lua_State *L);
00087 
00088 static void lua_state_destroy(void *data);
00089 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
00090 static lua_State *lua_get_state(struct ast_channel *chan);
00091 
00092 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
00093 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
00094 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
00095 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
00096 
00097 AST_MUTEX_DEFINE_STATIC(config_file_lock);
00098 static char *config_file_data = NULL;
00099 static long config_file_size = 0;
00100 
00101 static struct ast_context *local_contexts = NULL;
00102 static struct ast_hashtab *local_table = NULL;
00103 
00104 static const struct ast_datastore_info lua_datastore = {
00105    .type = "lua",
00106    .destroy = lua_state_destroy,
00107    .chan_fixup = lua_datastore_fixup,
00108 };
00109 
00110 
00111 /*!
00112  * \brief The destructor for lua_datastore
00113  */
00114 static void lua_state_destroy(void *data)
00115 {
00116    if (data)
00117       lua_close(data);
00118 }
00119 
00120 /*!
00121  * \brief The fixup function for the lua_datastore.
00122  * \param data the datastore data, in this case it will be a lua_State
00123  * \param old_chan the channel we are moving from
00124  * \param new_chan the channel we are moving to
00125  *
00126  * This function updates our internal channel pointer.
00127  */
00128 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
00129 {
00130    lua_State *L = data;
00131    lua_pushlightuserdata(L, new_chan);
00132    lua_setfield(L, LUA_REGISTRYINDEX, "channel");
00133 }
00134 
00135 /*!
00136  * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
00137  * call directly)
00138  *
00139  * This function would be called in the following example as it would be found
00140  * in extensions.lua.
00141  *
00142  * \code
00143  * app.dial
00144  * \endcode
00145  */
00146 static int lua_pbx_findapp(lua_State *L)
00147 {
00148    const char *app_name = luaL_checkstring(L, 2);
00149    
00150    lua_newtable(L);
00151 
00152    lua_pushstring(L, "name");
00153    lua_pushstring(L, app_name);
00154    lua_settable(L, -3);
00155 
00156    luaL_getmetatable(L, "application");
00157    lua_setmetatable(L, -2);
00158 
00159    return 1;
00160 }
00161 
00162 /*!
00163  * \brief [lua_CFunction] This function is part of the 'application' metatable
00164  * and is used to execute applications similar to pbx_exec() (for access from
00165  * lua, don't call directly)
00166  *
00167  * \param L the lua_State to use
00168  * \return nothing
00169  *
00170  * This funciton is executed as the '()' operator for apps accessed through the
00171  * 'app' table.
00172  *
00173  * \code
00174  * app.playback('demo-congrats')
00175  * \endcode
00176  */
00177 static int lua_pbx_exec(lua_State *L)
00178 {
00179    int res, nargs = lua_gettop(L);
00180    char data[LUA_EXT_DATA_SIZE] = "";
00181    char *data_next = data, *app_name;
00182    char *context, *exten;
00183    char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
00184    int priority, autoservice;
00185    size_t data_left = sizeof(data);
00186    struct ast_app *app;
00187    struct ast_channel *chan;
00188    
00189    lua_getfield(L, 1, "name");
00190    app_name = ast_strdupa(lua_tostring(L, -1));
00191    lua_pop(L, 1);
00192    
00193    if (!(app = pbx_findapp(app_name))) {
00194       lua_pushstring(L, "application '");
00195       lua_pushstring(L, app_name);
00196       lua_pushstring(L, "' not found");
00197       lua_concat(L, 3);
00198       return lua_error(L);
00199    }
00200    
00201 
00202    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00203    chan = lua_touserdata(L, -1);
00204    lua_pop(L, 1);
00205    
00206    
00207    lua_getfield(L, LUA_REGISTRYINDEX, "context");
00208    context = ast_strdupa(lua_tostring(L, -1));
00209    lua_pop(L, 1);
00210    
00211    lua_getfield(L, LUA_REGISTRYINDEX, "exten");
00212    exten = ast_strdupa(lua_tostring(L, -1));
00213    lua_pop(L, 1);
00214    
00215    lua_getfield(L, LUA_REGISTRYINDEX, "priority");
00216    priority = lua_tointeger(L, -1);
00217    lua_pop(L, 1);
00218 
00219 
00220    if (nargs > 1) {
00221       int i;
00222 
00223       if (!lua_isnil(L, 2))
00224          ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
00225 
00226       for (i = 3; i <= nargs; i++) {
00227          if (lua_isnil(L, i))
00228             ast_build_string(&data_next, &data_left, ",");
00229          else
00230             ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
00231       }
00232    }
00233    
00234    ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
00235          exten, context, priority,
00236          term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
00237          term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
00238          term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
00239 
00240    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00241    autoservice = lua_toboolean(L, -1);
00242    lua_pop(L, 1);
00243 
00244    if (autoservice)
00245       ast_autoservice_stop(chan);
00246 
00247    res = pbx_exec(chan, app, data);
00248    
00249    if (autoservice)
00250       ast_autoservice_start(chan);
00251 
00252    /* error executing an application, report it */
00253    if (res) {
00254       lua_pushinteger(L, res);
00255       return lua_error(L);
00256    }
00257    return 0;
00258 }
00259 
00260 /*!
00261  * \brief [lua_CFunction] Used to get the value of a variable or dialplan
00262  * function (for access from lua, don't call directly)
00263  * 
00264  * The value of the variable or function is returned.  This function is the
00265  * 'get()' function in the following example as would be seen in
00266  * extensions.lua.
00267  *
00268  * \code
00269  * channel.variable:get()
00270  * \endcode
00271  */
00272 static int lua_get_variable_value(lua_State *L)
00273 {
00274    struct ast_channel *chan;
00275    char *value = NULL, *name;
00276    char *workspace = alloca(LUA_BUF_SIZE);
00277    int autoservice;
00278 
00279    workspace[0] = '\0';
00280 
00281    if (!lua_istable(L, 1)) {
00282       lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
00283       return lua_error(L);
00284    }
00285    
00286    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00287    chan = lua_touserdata(L, -1);
00288    lua_pop(L, 1);
00289 
00290    lua_getfield(L, 1, "name");
00291    name = ast_strdupa(lua_tostring(L, -1));
00292    lua_pop(L, 1);
00293    
00294    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00295    autoservice = lua_toboolean(L, -1);
00296    lua_pop(L, 1);
00297 
00298    if (autoservice)
00299       ast_autoservice_stop(chan);
00300    
00301    /* if this is a dialplan function then use ast_func_read(), otherwise
00302     * use pbx_retrieve_variable() */
00303    if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
00304       value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
00305    } else {
00306       pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
00307    }
00308    
00309    if (autoservice)
00310       ast_autoservice_start(chan);
00311 
00312    if (value) {
00313       lua_pushstring(L, value);
00314    } else {
00315       lua_pushnil(L);
00316    }
00317 
00318    return 1;
00319 }
00320 
00321 /*!
00322  * \brief [lua_CFunction] Used to set the value of a variable or dialplan
00323  * function (for access from lua, don't call directly)
00324  * 
00325  * This function is the 'set()' function in the following example as would be
00326  * seen in extensions.lua.
00327  *
00328  * \code
00329  * channel.variable:set("value")
00330  * \endcode
00331  */
00332 static int lua_set_variable_value(lua_State *L)
00333 {
00334    const char *name, *value;
00335    struct ast_channel *chan;
00336    int autoservice;
00337 
00338    if (!lua_istable(L, 1)) {
00339       lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
00340       return lua_error(L);
00341    }
00342 
00343    lua_getfield(L, 1, "name");
00344    name = ast_strdupa(lua_tostring(L, -1));
00345    lua_pop(L, 1);
00346 
00347    value = luaL_checkstring(L, 2);
00348    
00349    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00350    chan = lua_touserdata(L, -1);
00351    lua_pop(L, 1);
00352 
00353    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00354    autoservice = lua_toboolean(L, -1);
00355    lua_pop(L, 1);
00356 
00357    if (autoservice)
00358       ast_autoservice_stop(chan);
00359 
00360    pbx_builtin_setvar_helper(chan, name, value);
00361    
00362    if (autoservice)
00363       ast_autoservice_start(chan);
00364 
00365    return 0;
00366 }
00367 
00368 /*!
00369  * \brief Update the lua registry with the given context, exten, and priority.
00370  *
00371  * \param L the lua_State to use
00372  * \param context the new context
00373  * \param exten the new exten
00374  * \param priority the new priority
00375  */
00376 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
00377 {
00378    lua_pushstring(L, context);
00379    lua_setfield(L, LUA_REGISTRYINDEX, "context");
00380 
00381    lua_pushstring(L, exten);
00382    lua_setfield(L, LUA_REGISTRYINDEX, "exten");
00383 
00384    lua_pushinteger(L, priority);
00385    lua_setfield(L, LUA_REGISTRYINDEX, "priority");
00386 }
00387 
00388 /*!
00389  * \brief Push a 'variable' table on the stack for access the channel variable
00390  * with the given name.
00391  *
00392  * \param L the lua_State to use
00393  * \param name the name of the variable
00394  */
00395 static void lua_push_variable_table(lua_State *L, const char *name)
00396 {
00397    lua_newtable(L);
00398    luaL_getmetatable(L, "variable");
00399    lua_setmetatable(L, -2);
00400 
00401    lua_pushstring(L, name);
00402    lua_setfield(L, -2, "name");
00403    
00404    lua_pushcfunction(L, &lua_get_variable_value);
00405    lua_setfield(L, -2, "get");
00406    
00407    lua_pushcfunction(L, &lua_set_variable_value);
00408    lua_setfield(L, -2, "set");
00409 }
00410 
00411 /*!
00412  * \brief Create the global 'app' table for executing applications
00413  *
00414  * \param L the lua_State to use
00415  */
00416 static void lua_create_app_table(lua_State *L)
00417 {
00418    lua_newtable(L);
00419    luaL_newmetatable(L, "app");
00420 
00421    lua_pushstring(L, "__index");
00422    lua_pushcfunction(L, &lua_pbx_findapp);
00423    lua_settable(L, -3);
00424 
00425    lua_setmetatable(L, -2);
00426    lua_setglobal(L, "app");
00427 }
00428 
00429 /*!
00430  * \brief Create the global 'channel' table for accesing channel variables
00431  *
00432  * \param L the lua_State to use
00433  */
00434 static void lua_create_channel_table(lua_State *L)
00435 {
00436    lua_newtable(L);
00437    luaL_newmetatable(L, "channel_data");
00438 
00439    lua_pushstring(L, "__index");
00440    lua_pushcfunction(L, &lua_get_variable);
00441    lua_settable(L, -3);
00442 
00443    lua_pushstring(L, "__newindex");
00444    lua_pushcfunction(L, &lua_set_variable);
00445    lua_settable(L, -3);
00446 
00447    lua_setmetatable(L, -2);
00448    lua_setglobal(L, "channel");
00449 }
00450 
00451 /*!
00452  * \brief Create the 'variable' metatable, used to retrieve channel variables
00453  *
00454  * \param L the lua_State to use
00455  */
00456 static void lua_create_variable_metatable(lua_State *L)
00457 {
00458    luaL_newmetatable(L, "variable");
00459 
00460    lua_pushstring(L, "__call");
00461    lua_pushcfunction(L, &lua_func_read);
00462    lua_settable(L, -3);
00463 
00464    lua_pop(L, 1);
00465 }
00466 
00467 /*!
00468  * \brief Create the 'application' metatable, used to execute asterisk
00469  * applications from lua 
00470  *
00471  * \param L the lua_State to use
00472  */
00473 static void lua_create_application_metatable(lua_State *L)
00474 {
00475    luaL_newmetatable(L, "application");
00476 
00477    lua_pushstring(L, "__call");
00478    lua_pushcfunction(L, &lua_pbx_exec);
00479    lua_settable(L, -3);
00480 
00481    lua_pop(L, 1);
00482 }
00483 
00484 /*!
00485  * \brief Create the autoservice functions
00486  *
00487  * \param L the lua_State to use
00488  */
00489 static void lua_create_autoservice_functions(lua_State *L)
00490 {
00491    lua_pushcfunction(L, &lua_autoservice_start);
00492    lua_setglobal(L, "autoservice_start");
00493    
00494    lua_pushcfunction(L, &lua_autoservice_stop);
00495    lua_setglobal(L, "autoservice_stop");
00496 
00497    lua_pushcfunction(L, &lua_autoservice_status);
00498    lua_setglobal(L, "autoservice_status");
00499 
00500    lua_pushboolean(L, 0);
00501    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00502 }
00503 
00504 /*!
00505  * \brief Create the hangup check function
00506  *
00507  * \param L the lua_State to use
00508  */
00509 static void lua_create_hangup_function(lua_State *L)
00510 {
00511    lua_pushcfunction(L, &lua_check_hangup);
00512    lua_setglobal(L, "check_hangup");
00513 }
00514 
00515 /*!
00516  * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
00517  * directly)
00518  * 
00519  * This function is called to lookup a variable construct a 'variable' object.
00520  * It would be called in the following example as would be seen in
00521  * extensions.lua.
00522  *
00523  * \code
00524  * channel.variable
00525  * \endcode
00526  */
00527 static int lua_get_variable(lua_State *L)
00528 {
00529    struct ast_channel *chan;
00530    char *name = ast_strdupa(luaL_checkstring(L, 2));
00531    char *value = NULL;
00532    char *workspace = alloca(LUA_BUF_SIZE);
00533    workspace[0] = '\0';
00534    
00535    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00536    chan = lua_touserdata(L, -1);
00537    lua_pop(L, 1);
00538 
00539    lua_push_variable_table(L, name);
00540    
00541    /* if this is not a request for a dialplan funciton attempt to retrieve
00542     * the value of the variable */
00543    if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
00544       pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
00545    }
00546 
00547    if (value) {
00548       lua_pushstring(L, value);
00549       lua_setfield(L, -2, "value");
00550    }
00551 
00552    return 1;   
00553 }
00554 
00555 /*!
00556  * \brief [lua_CFunction] Set the value of a channel variable or dialplan
00557  * function (for access from lua, don't call directly)
00558  * 
00559  * This function is called to set a variable or dialplan function.  It would be
00560  * called in the following example as would be seen in extensions.lua.
00561  *
00562  * \code
00563  * channel.variable = "value"
00564  * \endcode
00565  */
00566 static int lua_set_variable(lua_State *L)
00567 {
00568    struct ast_channel *chan;
00569    int autoservice;
00570    const char *name = luaL_checkstring(L, 2);
00571    const char *value = luaL_checkstring(L, 3);
00572 
00573    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00574    chan = lua_touserdata(L, -1);
00575    lua_pop(L, 1);
00576 
00577    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00578    autoservice = lua_toboolean(L, -1);
00579    lua_pop(L, 1);
00580 
00581    if (autoservice)
00582       ast_autoservice_stop(chan);
00583 
00584    pbx_builtin_setvar_helper(chan, name, value);
00585    
00586    if (autoservice)
00587       ast_autoservice_start(chan);
00588 
00589    return 0;
00590 }
00591 
00592 /*!
00593  * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
00594  * function (for access from lua, don't call directly)
00595  * 
00596  * This function is called to create a 'variable' object to access a dialplan
00597  * function.  It would be called in the following example as would be seen in
00598  * extensions.lua.
00599  *
00600  * \code
00601  * channel.func("arg1", "arg2", "arg3")
00602  * \endcode
00603  *
00604  * To actually do anything with the resulting value you must use the 'get()'
00605  * and 'set()' methods (the reason is the resulting value is not a value, but
00606  * an object in the form of a lua table).
00607  */
00608 static int lua_func_read(lua_State *L)
00609 {
00610    int nargs = lua_gettop(L);
00611    char fullname[LUA_EXT_DATA_SIZE] = "";
00612    char *fullname_next = fullname, *name;
00613    size_t fullname_left = sizeof(fullname);
00614    
00615    lua_getfield(L, 1, "name");
00616    name = ast_strdupa(lua_tostring(L, -1));
00617    lua_pop(L, 1);
00618 
00619    ast_build_string(&fullname_next, &fullname_left, "%s(", name);
00620    
00621    if (nargs > 1) {
00622       int i;
00623 
00624       if (!lua_isnil(L, 2))
00625          ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
00626 
00627       for (i = 3; i <= nargs; i++) {
00628          if (lua_isnil(L, i))
00629             ast_build_string(&fullname_next, &fullname_left, ",");
00630          else
00631             ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
00632       }
00633    }
00634 
00635    ast_build_string(&fullname_next, &fullname_left, ")");
00636    
00637    lua_push_variable_table(L, fullname);
00638    
00639    return 1;
00640 }
00641 
00642 /*!
00643  * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
00644  * channel (for access from lua, don't call directly)
00645  *
00646  * \param L the lua_State to use
00647  *
00648  * This function will set a flag that will cause pbx_lua to maintain an
00649  * autoservice on this channel.  The autoservice will automatically be stopped
00650  * and restarted before calling applications and functions.
00651  *
00652  * \return This function returns the result of the ast_autoservice_start()
00653  * function as a boolean to its lua caller.
00654  */
00655 static int lua_autoservice_start(lua_State *L)
00656 {
00657    struct ast_channel *chan;
00658    int res;
00659 
00660    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00661    if (lua_toboolean(L, -1)) {
00662       /* autoservice already running */
00663       return 1;
00664    }
00665    lua_pop(L, 1);
00666 
00667    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00668    chan = lua_touserdata(L, -1);
00669    lua_pop(L, 1);
00670 
00671    res = ast_autoservice_start(chan);
00672 
00673    lua_pushboolean(L, !res);
00674    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00675 
00676    lua_pushboolean(L, !res);
00677    return 1;
00678 }
00679 
00680 /*!
00681  * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
00682  * this channel (for access from lua, don't call directly)
00683  *
00684  * \param L the lua_State to use
00685  *
00686  * This function will stop any autoservice running and turn off the autoservice
00687  * flag.  If this function returns false, it's probably because no autoservice
00688  * was running to begin with.
00689  *
00690  * \return This function returns the result of the ast_autoservice_stop()
00691  * function as a boolean to its lua caller.
00692  */
00693 static int lua_autoservice_stop(lua_State *L)
00694 {
00695    struct ast_channel *chan;
00696    int res;
00697 
00698    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00699    if (!lua_toboolean(L, -1)) {
00700       /* no autoservice running */
00701       return 1;
00702    }
00703    lua_pop(L, 1);
00704 
00705    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00706    chan = lua_touserdata(L, -1);
00707    lua_pop(L, 1);
00708 
00709    res = ast_autoservice_stop(chan);
00710 
00711    lua_pushboolean(L, 0);
00712    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00713 
00714    lua_pushboolean(L, !res);
00715    return 1;
00716 }
00717 
00718 /*!
00719  * \brief [lua_CFunction] Get the status of the autoservice flag (for access
00720  * from lua, don't call directly)
00721  *
00722  * \param L the lua_State to use
00723  *
00724  * \return This function returns the status of the autoservice flag as a
00725  * boolean to its lua caller.
00726  */
00727 static int lua_autoservice_status(lua_State *L)
00728 {
00729    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00730    return 1;
00731 }
00732 
00733 /*!
00734  * \brief [lua_CFunction] Check if this channel has been hungup or not (for
00735  * access from lua, don't call directly)
00736  *
00737  * \param L the lua_State to use
00738  *
00739  * \return This function returns true if the channel was hungup
00740  */
00741 static int lua_check_hangup(lua_State *L)
00742 {
00743    struct ast_channel *chan;
00744    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00745    chan = lua_touserdata(L, -1);
00746    lua_pop(L, 1);
00747 
00748    lua_pushboolean(L, ast_check_hangup(chan));
00749    return 1;
00750 }
00751 
00752 /*!
00753  * \brief [lua_CFunction] Handle lua errors (for access from lua, don't call
00754  * directly)
00755  *
00756  * \param L the lua_State to use
00757  */
00758 static int lua_error_function(lua_State *L)
00759 {
00760    int message_index;
00761 
00762    /* pass number arguments right through back to asterisk*/
00763    if (lua_isnumber(L, -1)) {
00764       return 1;
00765    }
00766 
00767    /* if we are here then we have a string error message, let's attach a
00768     * backtrace to it */
00769    message_index = lua_gettop(L);
00770 
00771    /* prepare to prepend a new line to the traceback */
00772    lua_pushliteral(L, "\n");
00773 
00774    lua_getglobal(L, "debug");
00775    lua_getfield(L, -1, "traceback");
00776    lua_remove(L, -2); /* remove the 'debug' table */
00777 
00778    lua_pushvalue(L, message_index);
00779    lua_remove(L, message_index);
00780 
00781    lua_pushnumber(L, 2);
00782 
00783    lua_call(L, 2, 1);
00784 
00785    /* prepend the new line we prepared above */
00786    lua_concat(L, 2);
00787 
00788    return 1;
00789 }
00790 
00791 /*!
00792  * \brief Store the sort order of each context
00793  
00794  * In the event of an error, an error string will be pushed onto the lua stack.
00795  *
00796  * \retval 0 success
00797  * \retval 1 failure
00798  */
00799 static int lua_sort_extensions(lua_State *L)
00800 {
00801    int extensions, extensions_order;
00802 
00803    /* create the extensions_order table */
00804    lua_newtable(L);
00805    lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
00806    lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
00807    extensions_order = lua_gettop(L);
00808 
00809    /* sort each context in the extensions table */
00810    /* load the 'extensions' table */
00811    lua_getglobal(L, "extensions");
00812    extensions = lua_gettop(L);
00813    if (lua_isnil(L, -1)) {
00814       lua_pop(L, 1);
00815       lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
00816       return 1;
00817    }
00818 
00819    /* iterate through the extensions table and create a
00820     * matching table (holding the sort order) in the
00821     * extensions_order table for each context that is found
00822     */
00823    for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
00824       int context = lua_gettop(L);
00825       int context_name = context - 1;
00826       int context_order;
00827 
00828       /* copy the context_name to be used as the key for the
00829        * context_order table in the extensions_order table later */
00830       lua_pushvalue(L, context_name);
00831 
00832       /* create the context_order table */
00833       lua_newtable(L);
00834       context_order = lua_gettop(L);
00835 
00836       /* iterate through this context an popluate the corrisponding
00837        * table in the extensions_order table */
00838       for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
00839          int exten = lua_gettop(L) - 1;
00840 
00841          lua_pushinteger(L, lua_objlen(L, context_order) + 1);
00842          lua_pushvalue(L, exten);
00843          lua_settable(L, context_order);
00844       }
00845       lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
00846 
00847       /* now sort the new table */
00848 
00849       /* push the table.sort function */
00850       lua_getglobal(L, "table");
00851       lua_getfield(L, -1, "sort");
00852       lua_remove(L, -2); /* remove the 'table' table */
00853 
00854       /* push the context_order table */
00855       lua_pushvalue(L, context_name);
00856       lua_gettable(L, extensions_order);
00857 
00858       /* push the comp function */
00859       lua_pushcfunction(L, &lua_extension_cmp);
00860 
00861       if (lua_pcall(L, 2, 0, 0)) {
00862          lua_insert(L, -5);
00863          lua_pop(L, 4);
00864          return 1;
00865       }
00866    }
00867    
00868    /* remove the extensions table and the extensions_order table */
00869    lua_pop(L, 2);
00870    return 0;
00871 }
00872 
00873 /*!
00874  * \brief Register dialplan switches for our pbx_lua contexs.
00875  *
00876  * In the event of an error, an error string will be pushed onto the lua stack.
00877  *
00878  * \retval 0 success
00879  * \retval 1 failure
00880  */
00881 static int lua_register_switches(lua_State *L)
00882 {
00883    int extensions;
00884    struct ast_context *con = NULL;
00885 
00886    /* create the hash table for our contexts */
00887    /* XXX do we ever need to destroy this? pbx_config does not */
00888    if (!local_table)
00889       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
00890 
00891    /* load the 'extensions' table */
00892    lua_getglobal(L, "extensions");
00893    extensions = lua_gettop(L);
00894    if (lua_isnil(L, -1)) {
00895       lua_pop(L, 1);
00896       lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
00897       return 1;
00898    }
00899 
00900    /* iterate through the extensions table and register a context and
00901     * dialplan switch for each lua context
00902     */
00903    for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
00904       int context = lua_gettop(L);
00905       int context_name = context - 1;
00906       const char *context_str = lua_tostring(L, context_name);
00907 
00908       /* find or create this context */
00909       con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
00910       if (!con) {
00911          /* remove extensions table and context key and value */
00912          lua_pop(L, 3);
00913          lua_pushstring(L, "Failed to find or create context\n");
00914          return 1;
00915       }
00916 
00917       /* register the switch */
00918       if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
00919          /* remove extensions table and context key and value */
00920          lua_pop(L, 3);
00921          lua_pushstring(L, "Unable to create switch for context\n");
00922          return 1;
00923       }
00924    }
00925    
00926    /* remove the extensions table */
00927    lua_pop(L, 1);
00928    return 0;
00929 }
00930 
00931 
00932 /*!
00933  * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
00934  * call directly)
00935  *
00936  * This function returns true if the first extension passed should match after
00937  * the second.  It behaves like the '<' operator.
00938  */
00939 static int lua_extension_cmp(lua_State *L)
00940 {
00941    const char *a = luaL_checkstring(L, -2);
00942    const char *b = luaL_checkstring(L, -1);
00943 
00944    if (ast_extension_cmp(a, b) == -1)
00945       lua_pushboolean(L, 1);
00946    else
00947       lua_pushboolean(L, 0);
00948 
00949    return 1;
00950 }
00951 
00952 /*!
00953  * \brief Load the extensions.lua file in to a buffer and execute the file
00954  *
00955  * \param L the lua_State to use
00956  * \param size a pointer to store the size of the buffer
00957  *
00958  * \note The caller is expected to free the buffer at some point.
00959  *
00960  * \return a pointer to the buffer
00961  */
00962 static char *lua_read_extensions_file(lua_State *L, long *size)
00963 {
00964    FILE *f;
00965    int error_func;
00966    char *data;
00967    char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
00968    sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
00969 
00970    if (!(f = fopen(path, "r"))) {
00971       lua_pushstring(L, "cannot open '");
00972       lua_pushstring(L, path);
00973       lua_pushstring(L, "' for reading: ");
00974       lua_pushstring(L, strerror(errno));
00975       lua_concat(L, 4);
00976 
00977       return NULL;
00978    }
00979 
00980    if (fseek(f, 0l, SEEK_END)) {
00981       fclose(f);
00982       lua_pushliteral(L, "error determining the size of the config file");
00983       return NULL;
00984    }
00985 
00986    *size = ftell(f);
00987 
00988    if (fseek(f, 0l, SEEK_SET)) {
00989       *size = 0;
00990       fclose(f);
00991       lua_pushliteral(L, "error reading config file");
00992       return NULL;
00993    }
00994 
00995    if (!(data = ast_malloc(*size))) {
00996       *size = 0;
00997       fclose(f);
00998       lua_pushstring(L, "not enough memory");
00999       return NULL;
01000    }
01001 
01002    if (fread(data, sizeof(char), *size, f) != *size) {
01003       *size = 0;
01004       fclose(f);
01005       lua_pushliteral(L, "problem reading configuration file");
01006       return NULL;
01007    }
01008    fclose(f);
01009 
01010    lua_pushcfunction(L, &lua_error_function);
01011    error_func = lua_gettop(L);
01012 
01013    if (luaL_loadbuffer(L, data, *size, "extensions.lua")
01014          || lua_pcall(L, 0, LUA_MULTRET, error_func)
01015          || lua_sort_extensions(L)
01016          || lua_register_switches(L)) {
01017       ast_free(data);
01018       data = NULL;
01019       *size = 0;
01020    }
01021 
01022    lua_remove(L, error_func);
01023    return data;
01024 }
01025 
01026 /*!
01027  * \brief Load the extensions.lua file from the internal buffer
01028  *
01029  * \param L the lua_State to use
01030  * \param chan channel to work on
01031  *
01032  * This function also sets up some constructs used by the extensions.lua file.
01033  * In the event of an error, an error string will be pushed onto the lua stack.
01034  *
01035  * \retval 0 success
01036  * \retval 1 failure
01037  */
01038 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
01039 {
01040    
01041    /* store a pointer to this channel */
01042    lua_pushlightuserdata(L, chan);
01043    lua_setfield(L, LUA_REGISTRYINDEX, "channel");
01044    
01045    luaL_openlibs(L);
01046 
01047    /* load and sort extensions */
01048    ast_mutex_lock(&config_file_lock);
01049    if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
01050          || lua_pcall(L, 0, LUA_MULTRET, 0)
01051          || lua_sort_extensions(L)) {
01052       ast_mutex_unlock(&config_file_lock);
01053       return 1;
01054    }
01055    ast_mutex_unlock(&config_file_lock);
01056 
01057    /* now we setup special tables and functions */
01058 
01059    lua_create_app_table(L);
01060    lua_create_channel_table(L);
01061 
01062    lua_create_variable_metatable(L);
01063    lua_create_application_metatable(L);
01064 
01065    lua_create_autoservice_functions(L);
01066    lua_create_hangup_function(L);
01067 
01068    return 0;
01069 }
01070 
01071 /*!
01072  * \brief Reload the extensions file and update the internal buffers if it
01073  * loads correctly.
01074  *
01075  * \warning This function should not be called on a lua_State returned from
01076  * lua_get_state().
01077  *
01078  * \param L the lua_State to use (must be freshly allocated with
01079  * luaL_newstate(), don't use lua_get_state())
01080  */
01081 static int lua_reload_extensions(lua_State *L)
01082 {
01083    long size = 0;
01084    char *data = NULL;
01085 
01086    luaL_openlibs(L);
01087 
01088    if (!(data = lua_read_extensions_file(L, &size))) {
01089       return 1;
01090    }
01091 
01092    ast_mutex_lock(&config_file_lock);
01093 
01094    if (config_file_data)
01095       ast_free(config_file_data);
01096 
01097    config_file_data = data;
01098    config_file_size = size;
01099    
01100    /* merge our new contexts */
01101    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01102    /* merge_contexts_and_delete will actually, at the correct moment, 
01103       set the global dialplan pointers to your local_contexts and local_table.
01104       It then will free up the old tables itself. Just be sure not to
01105       hang onto the pointers. */
01106    local_table = NULL;
01107    local_contexts = NULL;
01108 
01109    ast_mutex_unlock(&config_file_lock);
01110    return 0;
01111 }
01112 
01113 /*!
01114  * \brief Free the internal extensions buffer.
01115  */
01116 static void lua_free_extensions()
01117 {
01118    ast_mutex_lock(&config_file_lock);
01119    config_file_size = 0;
01120    ast_free(config_file_data);
01121    ast_mutex_unlock(&config_file_lock);
01122 }
01123 
01124 /*!
01125  * \brief Get the lua_State for this channel
01126  *
01127  * If no channel is passed then a new state is allocated.  States with no
01128  * channel assocatied with them should only be used for matching extensions.
01129  * If the channel does not yet have a lua state associated with it, one will be
01130  * created.
01131  *
01132  * \note If no channel was passed then the caller is expected to free the state
01133  * using lua_close().
01134  *
01135  * \return a lua_State
01136  */
01137 static lua_State *lua_get_state(struct ast_channel *chan)
01138 {
01139    struct ast_datastore *datastore = NULL;
01140    lua_State *L;
01141 
01142    if (!chan) {
01143       lua_State *L = luaL_newstate();
01144       if (!L) {
01145          ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01146          return NULL;
01147       }
01148 
01149       if (lua_load_extensions(L, NULL)) {
01150          const char *error = lua_tostring(L, -1);
01151          ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
01152          lua_close(L);
01153          return NULL;
01154       }
01155       return L;
01156    } else {
01157       ast_channel_lock(chan);
01158       datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
01159       ast_channel_unlock(chan);
01160 
01161       if (!datastore) {
01162          /* nothing found, allocate a new lua state */
01163          datastore = ast_datastore_alloc(&lua_datastore, NULL);
01164          if (!datastore) {
01165             ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
01166             return NULL;
01167          }
01168 
01169          datastore->data = luaL_newstate();
01170          if (!datastore->data) {
01171             ast_datastore_free(datastore);
01172             ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01173             return NULL;
01174          }
01175 
01176          ast_channel_lock(chan);
01177          ast_channel_datastore_add(chan, datastore);
01178          ast_channel_unlock(chan);
01179 
01180          L = datastore->data;
01181 
01182          if (lua_load_extensions(L, chan)) {
01183             const char *error = lua_tostring(L, -1);
01184             ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
01185 
01186             ast_channel_lock(chan);
01187             ast_channel_datastore_remove(chan, datastore);
01188             ast_channel_unlock(chan);
01189 
01190             ast_datastore_free(datastore);
01191             return NULL;
01192          }
01193       }
01194 
01195       return datastore->data;
01196    }
01197 }
01198 
01199 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
01200 {
01201    int res;
01202    lua_State *L;
01203    struct ast_module_user *u = ast_module_user_add(chan);
01204    if (!u) {
01205       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01206       return 0;
01207    }
01208 
01209    L = lua_get_state(chan);
01210    if (!L) {
01211       ast_module_user_remove(u);
01212       return 0;
01213    }
01214 
01215    res = lua_find_extension(L, context, exten, priority, &exists, 0);
01216 
01217    if (!chan) lua_close(L);
01218    ast_module_user_remove(u);
01219    return res;
01220 }
01221 
01222 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
01223 {
01224    int res;
01225    lua_State *L;
01226    struct ast_module_user *u = ast_module_user_add(chan);
01227    if (!u) {
01228       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01229       return 0;
01230    }
01231 
01232    L = lua_get_state(chan);
01233    if (!L) {
01234       ast_module_user_remove(u);
01235       return 0;
01236    }
01237 
01238    res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
01239 
01240    if (!chan) lua_close(L);
01241    ast_module_user_remove(u);
01242    return res;
01243 }
01244 
01245 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
01246 {
01247    int res;
01248    lua_State *L;
01249    struct ast_module_user *u = ast_module_user_add(chan);
01250    if (!u) {
01251       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01252       return 0;
01253    }
01254 
01255    L = lua_get_state(chan);
01256    if (!L) {
01257       ast_module_user_remove(u);
01258       return 0;
01259    }
01260    
01261    res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
01262 
01263    if (!chan) lua_close(L);
01264    ast_module_user_remove(u);
01265    return res;
01266 }
01267 
01268 
01269 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
01270 {
01271    int res, error_func;
01272    lua_State *L;
01273    struct ast_module_user *u = ast_module_user_add(chan);
01274    if (!u) {
01275       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01276       return -1;
01277    }
01278    
01279    L = lua_get_state(chan);
01280    if (!L) {
01281       ast_module_user_remove(u);
01282       return -1;
01283    }
01284 
01285    lua_pushcfunction(L, &lua_error_function);
01286    error_func = lua_gettop(L);
01287 
01288    /* push the extension function onto the stack */
01289    if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
01290       lua_pop(L, 1); /* pop the debug function */
01291       ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
01292       if (!chan) lua_close(L);
01293       ast_module_user_remove(u);
01294       return -1;
01295    }
01296 
01297    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
01298    if (lua_toboolean(L, -1)) {
01299       ast_autoservice_start(chan);
01300    }
01301    lua_pop(L, 1);
01302 
01303    lua_update_registry(L, context, exten, priority);
01304    
01305    lua_pushstring(L, context);
01306    lua_pushstring(L, exten);
01307    
01308    res = lua_pcall(L, 2, 0, error_func);
01309    if (res) {
01310       if (res == LUA_ERRRUN) {
01311          res = -1;
01312          if (lua_isnumber(L, -1)) {
01313             res = lua_tointeger(L, -1);
01314          } else if (lua_isstring(L, -1)) {
01315             const char *error = lua_tostring(L, -1);
01316             ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
01317          }
01318       } else if (res == LUA_ERRERR) {
01319          res = -1;
01320          ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
01321       } else if (res == LUA_ERRMEM) {
01322          res = -1;
01323          ast_log(LOG_ERROR, "Memory allocation error\n");
01324       }
01325       lua_pop(L, 1);
01326    }
01327    lua_remove(L, error_func);
01328 
01329    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
01330    if (lua_toboolean(L, -1)) {
01331       ast_autoservice_stop(chan);
01332    }
01333    lua_pop(L, 1);
01334 
01335    if (!chan) lua_close(L);
01336    ast_module_user_remove(u);
01337    return res;
01338 }
01339 
01340 /*!
01341  * \brief Locate an extensions and optionally push the matching function on the
01342  * stack
01343  *
01344  * \param L the lua_State to use
01345  * \param context the context to look in
01346  * \param exten the extension to look up
01347  * \param priority the priority to check, '1' is the only valid priority
01348  * \param func the calling func, used to adjust matching behavior between,
01349  * match, canmatch, and matchmore
01350  * \param push_func whether or not to push the lua function for the given
01351  * extension onto the stack
01352  */
01353 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
01354 {
01355    int context_table, context_order_table, i;
01356 
01357    ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
01358    if (priority != 1)
01359       return 0;
01360 
01361    /* load the 'extensions' table */
01362    lua_getglobal(L, "extensions");
01363    if (lua_isnil(L, -1)) {
01364       ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
01365       lua_pop(L, 1);
01366       return 0;
01367    }
01368 
01369    /* load the given context */
01370    lua_getfield(L, -1, context);
01371    if (lua_isnil(L, -1)) {
01372       lua_pop(L, 2);
01373       return 0;
01374    }
01375 
01376    /* remove the extensions table */
01377    lua_remove(L, -2);
01378 
01379    context_table = lua_gettop(L);
01380 
01381    /* load the extensions order table for this context */
01382    lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
01383    lua_getfield(L, -1, context);
01384 
01385    lua_remove(L, -2);  /* remove the extensions order table */
01386 
01387    context_order_table = lua_gettop(L);
01388    
01389    /* step through the extensions looking for a match */
01390    for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
01391       int e_index_copy, match = 0;
01392       const char *e;
01393 
01394       lua_pushinteger(L, i);
01395       lua_gettable(L, context_order_table);
01396       lua_gettop(L);
01397 
01398       /* copy the key at the top of the stack for use later */
01399       lua_pushvalue(L, -1);
01400       e_index_copy = lua_gettop(L);
01401 
01402       if (!(e = lua_tostring(L, e_index_copy))) {
01403          lua_pop(L, 2);
01404          continue;
01405       }
01406 
01407       /* make sure this is not the 'include' extension */
01408       if (!strcasecmp(e, "include")) {
01409          lua_pop(L, 2);
01410          continue;
01411       }
01412 
01413       if (func == &matchmore)
01414          match = ast_extension_close(e, exten, E_MATCHMORE);
01415       else if (func == &canmatch)
01416          match = ast_extension_close(e, exten, E_CANMATCH);
01417       else
01418          match = ast_extension_match(e, exten);
01419 
01420       /* the extension matching functions return 0 on fail, 1 on
01421        * match, 2 on earlymatch */
01422 
01423       if (!match) {
01424          /* pop the copy and the extension */
01425          lua_pop(L, 2);
01426          continue;   /* keep trying */
01427       }
01428 
01429       if (func == &matchmore && match == 2) {
01430          /* We match an extension ending in '!'. The decision in
01431           * this case is final and counts as no match. */
01432          lua_pop(L, 4);
01433          return 0;
01434       }
01435 
01436       /* remove the context table, the context order table, the
01437        * extension, and the extension copy (or replace the extension
01438        * with the corresponding function) */
01439       if (push_func) {
01440          lua_pop(L, 1);  /* pop the copy */
01441          lua_gettable(L, context_table);
01442          lua_insert(L, -3);
01443          lua_pop(L, 2);
01444       } else {
01445          lua_pop(L, 4);
01446       }
01447 
01448       return 1;
01449    }
01450 
01451    /* load the includes for this context */
01452    lua_getfield(L, context_table, "include");
01453    if (lua_isnil(L, -1)) {
01454       lua_pop(L, 3);
01455       return 0;
01456    }
01457 
01458    /* remove the context and the order table*/
01459    lua_remove(L, context_order_table);
01460    lua_remove(L, context_table);
01461 
01462    /* Now try any includes we have in this context */
01463    for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
01464       const char *c = lua_tostring(L, -1);
01465       if (!c)
01466          continue;
01467 
01468       if (lua_find_extension(L, c, exten, priority, func, push_func)) {
01469          /* remove the value, the key, and the includes table
01470           * from the stack.  Leave the function behind if
01471           * necessary */
01472 
01473          if (push_func)
01474             lua_insert(L, -4);
01475 
01476          lua_pop(L, 3);
01477          return 1;
01478       }
01479    }
01480 
01481    /* pop the includes table */
01482    lua_pop(L, 1);
01483    return 0;
01484 }
01485 
01486 static struct ast_switch lua_switch = {
01487         .name     = "Lua",
01488         .description = "Lua PBX Switch",
01489         .exists      = exists,
01490         .canmatch = canmatch,
01491         .exec     = exec,
01492         .matchmore   = matchmore,
01493 };
01494 
01495 
01496 static int load_or_reload_lua_stuff(void)
01497 {
01498    int res = AST_MODULE_LOAD_SUCCESS;
01499 
01500    lua_State *L = luaL_newstate();
01501    if (!L) {
01502       ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01503       return AST_MODULE_LOAD_DECLINE;
01504    }
01505 
01506    if (lua_reload_extensions(L)) {
01507       const char *error = lua_tostring(L, -1);
01508       ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
01509       res = AST_MODULE_LOAD_DECLINE;
01510    }
01511 
01512    lua_close(L);
01513    return res;
01514 }
01515 
01516 static int unload_module(void)
01517 {
01518    ast_context_destroy(NULL, registrar);
01519    ast_unregister_switch(&lua_switch);
01520    lua_free_extensions();
01521    return 0;
01522 }
01523 
01524 static int reload(void)
01525 {
01526    return load_or_reload_lua_stuff();
01527 }
01528 
01529 static int load_module(void)
01530 {
01531    int res;
01532 
01533    if ((res = load_or_reload_lua_stuff()))
01534       return res;
01535 
01536    if (ast_register_switch(&lua_switch)) {
01537       ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
01538       return AST_MODULE_LOAD_DECLINE;
01539    }
01540 
01541    return AST_MODULE_LOAD_SUCCESS;
01542 }
01543 
01544 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Lua PBX Switch",
01545       .load = load_module,
01546       .unload = unload_module,
01547       .reload = reload,
01548           );
01549