Merged revisions 140817 via svnmerge from
[asterisk-bristuff.git] / pbx / pbx_lua.c
blob689ba1c778106a84b08a00ea881a773f3551a512
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2007, Digium, Inc.
6 * Matthew Nicholson <mnicholson@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
19 /*!
20 * \file
22 * \author Matthew Nicholson <mnicholson@digium.com>
23 * \brief Lua PBX Switch
27 /*** MODULEINFO
28 <depend>lua</depend>
29 ***/
31 #include "asterisk.h"
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35 #include "asterisk/logger.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/module.h"
39 #include "asterisk/cli.h"
40 #include "asterisk/utils.h"
41 #include "asterisk/term.h"
42 #include "asterisk/paths.h"
44 #include <lua5.1/lua.h>
45 #include <lua5.1/lauxlib.h>
46 #include <lua5.1/lualib.h>
48 static char *config = "extensions.lua";
50 #define LUA_EXT_DATA_SIZE 256
51 #define LUA_BUF_SIZE 4096
53 static char *lua_read_extensions_file(lua_State *L, long *size);
54 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
55 static int lua_reload_extensions(lua_State *L);
56 static void lua_free_extensions(void);
57 static int lua_sort_extensions(lua_State *L);
58 static int lua_extension_cmp(lua_State *L);
59 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
60 static int lua_pbx_findapp(lua_State *L);
61 static int lua_pbx_exec(lua_State *L);
63 static int lua_get_variable_value(lua_State *L);
64 static int lua_set_variable_value(lua_State *L);
65 static int lua_get_variable(lua_State *L);
66 static int lua_set_variable(lua_State *L);
67 static int lua_func_read(lua_State *L);
69 static int lua_autoservice_start(lua_State *L);
70 static int lua_autoservice_stop(lua_State *L);
71 static int lua_autoservice_status(lua_State *L);
72 static int lua_check_hangup(lua_State *L);
74 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
75 static void lua_push_variable_table(lua_State *L, const char *name);
76 static void lua_create_app_table(lua_State *L);
77 static void lua_create_channel_table(lua_State *L);
78 static void lua_create_variable_metatable(lua_State *L);
79 static void lua_create_application_metatable(lua_State *L);
80 static void lua_create_autoservice_functions(lua_State *L);
81 static void lua_create_hangup_function(lua_State *L);
83 void lua_state_destroy(void *data);
84 static lua_State *lua_get_state(struct ast_channel *chan);
86 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
87 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
88 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
89 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
91 AST_MUTEX_DEFINE_STATIC(config_file_lock);
92 char *config_file_data = NULL;
93 long config_file_size = 0;
95 static const struct ast_datastore_info lua_datastore = {
96 .type = "lua",
97 .destroy = lua_state_destroy,
102 * \brief The destructor for lua_datastore
104 void lua_state_destroy(void *data)
106 if (data)
107 lua_close(data);
111 * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
112 * call directly)
114 * This function would be called in the following example as it would be found
115 * in extensions.lua.
117 * \code
118 * app.dial
119 * \endcode
121 static int lua_pbx_findapp(lua_State *L)
123 const char *app_name = luaL_checkstring(L, 2);
125 lua_newtable(L);
127 lua_pushstring(L, "name");
128 lua_pushstring(L, app_name);
129 lua_settable(L, -3);
131 luaL_getmetatable(L, "application");
132 lua_setmetatable(L, -2);
134 return 1;
138 * \brief [lua_CFunction] This function is part of the 'application' metatable
139 * and is used to execute applications similar to pbx_exec() (for access from
140 * lua, don't call directly)
142 * \param L the lua_State to use
143 * \return nothing
145 * This funciton is executed as the '()' operator for apps accessed through the
146 * 'app' table.
148 * \code
149 * app.playback('demo-congrats')
150 * \endcode
152 static int lua_pbx_exec(lua_State *L)
154 int res, nargs = lua_gettop(L);
155 char data[LUA_EXT_DATA_SIZE] = "";
156 char *data_next = data, *app_name;
157 char *context, *exten;
158 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
159 int priority, autoservice;
160 size_t data_left = sizeof(data);
161 struct ast_app *app;
162 struct ast_channel *chan;
164 lua_getfield(L, 1, "name");
165 app_name = ast_strdupa(lua_tostring(L, -1));
166 lua_pop(L, 1);
168 if (!(app = pbx_findapp(app_name))) {
169 lua_pushstring(L, "application '");
170 lua_pushstring(L, app_name);
171 lua_pushstring(L, "' not found");
172 lua_concat(L, 3);
173 return lua_error(L);
177 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
178 chan = lua_touserdata(L, -1);
179 lua_pop(L, 1);
182 lua_getfield(L, LUA_REGISTRYINDEX, "context");
183 context = ast_strdupa(lua_tostring(L, -1));
184 lua_pop(L, 1);
186 lua_getfield(L, LUA_REGISTRYINDEX, "exten");
187 exten = ast_strdupa(lua_tostring(L, -1));
188 lua_pop(L, 1);
190 lua_getfield(L, LUA_REGISTRYINDEX, "priority");
191 priority = lua_tointeger(L, -1);
192 lua_pop(L, 1);
195 if (nargs > 1) {
196 int i;
198 if (!lua_isnil(L, 2))
199 ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
201 for (i = 3; i <= nargs; i++) {
202 if (lua_isnil(L, i))
203 ast_build_string(&data_next, &data_left, ",");
204 else
205 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
209 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
210 exten, context, priority,
211 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
212 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
213 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
215 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
216 autoservice = lua_toboolean(L, -1);
217 lua_pop(L, 1);
219 if (autoservice)
220 ast_autoservice_stop(chan);
222 res = pbx_exec(chan, app, data);
224 if (autoservice)
225 ast_autoservice_start(chan);
227 /* error executing an application, report it */
228 if (res) {
229 lua_pushinteger(L, res);
230 return lua_error(L);
232 return 0;
236 * \brief [lua_CFunction] Used to get the value of a variable or dialplan
237 * function (for access from lua, don't call directly)
239 * The value of the variable or function is returned. This function is the
240 * 'get()' function in the following example as would be seen in
241 * extensions.lua.
243 * \code
244 * channel.variable:get()
245 * \endcode
247 static int lua_get_variable_value(lua_State *L)
249 struct ast_channel *chan;
250 char *value = NULL, *name;
251 char *workspace = alloca(LUA_BUF_SIZE);
252 int autoservice;
254 workspace[0] = '\0';
256 if (!lua_istable(L, 1)) {
257 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
258 return lua_error(L);
261 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
262 chan = lua_touserdata(L, -1);
263 lua_pop(L, 1);
265 lua_getfield(L, 1, "name");
266 name = ast_strdupa(lua_tostring(L, -1));
267 lua_pop(L, 1);
269 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
270 autoservice = lua_toboolean(L, -1);
271 lua_pop(L, 1);
273 if (autoservice)
274 ast_autoservice_stop(chan);
276 /* if this is a dialplan function then use ast_func_read(), otherwise
277 * use pbx_retrieve_variable() */
278 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
279 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
280 } else {
281 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
284 if (autoservice)
285 ast_autoservice_start(chan);
287 if (value) {
288 lua_pushstring(L, value);
289 } else {
290 lua_pushnil(L);
293 return 1;
297 * \brief [lua_CFunction] Used to set the value of a variable or dialplan
298 * function (for access from lua, don't call directly)
300 * This function is the 'set()' function in the following example as would be
301 * seen in extensions.lua.
303 * \code
304 * channel.variable:set("value")
305 * \endcode
307 static int lua_set_variable_value(lua_State *L)
309 const char *name, *value;
310 struct ast_channel *chan;
311 int autoservice;
313 if (!lua_istable(L, 1)) {
314 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
315 return lua_error(L);
318 lua_getfield(L, 1, "name");
319 name = ast_strdupa(lua_tostring(L, -1));
320 lua_pop(L, 1);
322 value = luaL_checkstring(L, 2);
324 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
325 chan = lua_touserdata(L, -1);
326 lua_pop(L, 1);
328 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
329 autoservice = lua_toboolean(L, -1);
330 lua_pop(L, 1);
332 if (autoservice)
333 ast_autoservice_stop(chan);
335 pbx_builtin_setvar_helper(chan, name, value);
337 if (autoservice)
338 ast_autoservice_start(chan);
340 return 0;
344 * \brief Update the lua registry with the given context, exten, and priority.
346 * \param L the lua_State to use
347 * \param context the new context
348 * \param exten the new exten
349 * \param priority the new priority
351 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
353 lua_pushstring(L, context);
354 lua_setfield(L, LUA_REGISTRYINDEX, "context");
356 lua_pushstring(L, exten);
357 lua_setfield(L, LUA_REGISTRYINDEX, "exten");
359 lua_pushinteger(L, priority);
360 lua_setfield(L, LUA_REGISTRYINDEX, "priority");
364 * \brief Push a 'variable' table on the stack for access the channel variable
365 * with the given name.
367 * \param L the lua_State to use
368 * \param name the name of the variable
370 static void lua_push_variable_table(lua_State *L, const char *name)
372 lua_newtable(L);
373 luaL_getmetatable(L, "variable");
374 lua_setmetatable(L, -2);
376 lua_pushstring(L, name);
377 lua_setfield(L, -2, "name");
379 lua_pushcfunction(L, &lua_get_variable_value);
380 lua_setfield(L, -2, "get");
382 lua_pushcfunction(L, &lua_set_variable_value);
383 lua_setfield(L, -2, "set");
387 * \brief Create the global 'app' table for executing applications
389 * \param L the lua_State to use
391 static void lua_create_app_table(lua_State *L)
393 lua_newtable(L);
394 luaL_newmetatable(L, "app");
396 lua_pushstring(L, "__index");
397 lua_pushcfunction(L, &lua_pbx_findapp);
398 lua_settable(L, -3);
400 lua_setmetatable(L, -2);
401 lua_setglobal(L, "app");
405 * \brief Create the global 'channel' table for accesing channel variables
407 * \param L the lua_State to use
409 static void lua_create_channel_table(lua_State *L)
411 lua_newtable(L);
412 luaL_newmetatable(L, "channel_data");
414 lua_pushstring(L, "__index");
415 lua_pushcfunction(L, &lua_get_variable);
416 lua_settable(L, -3);
418 lua_pushstring(L, "__newindex");
419 lua_pushcfunction(L, &lua_set_variable);
420 lua_settable(L, -3);
422 lua_setmetatable(L, -2);
423 lua_setglobal(L, "channel");
427 * \brief Create the 'variable' metatable, used to retrieve channel variables
429 * \param L the lua_State to use
431 static void lua_create_variable_metatable(lua_State *L)
433 luaL_newmetatable(L, "variable");
435 lua_pushstring(L, "__call");
436 lua_pushcfunction(L, &lua_func_read);
437 lua_settable(L, -3);
439 lua_pop(L, 1);
443 * \brief Create the 'application' metatable, used to execute asterisk
444 * applications from lua
446 * \param L the lua_State to use
448 static void lua_create_application_metatable(lua_State *L)
450 luaL_newmetatable(L, "application");
452 lua_pushstring(L, "__call");
453 lua_pushcfunction(L, &lua_pbx_exec);
454 lua_settable(L, -3);
456 lua_pop(L, 1);
460 * \brief Create the autoservice functions
462 * \param L the lua_State to use
464 static void lua_create_autoservice_functions(lua_State *L)
466 lua_pushcfunction(L, &lua_autoservice_start);
467 lua_setglobal(L, "autoservice_start");
469 lua_pushcfunction(L, &lua_autoservice_stop);
470 lua_setglobal(L, "autoservice_stop");
472 lua_pushcfunction(L, &lua_autoservice_status);
473 lua_setglobal(L, "autoservice_status");
475 lua_pushboolean(L, 0);
476 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
480 * \brief Create the hangup check function
482 * \param L the lua_State to use
484 static void lua_create_hangup_function(lua_State *L)
486 lua_pushcfunction(L, &lua_check_hangup);
487 lua_setglobal(L, "check_hangup");
491 * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
492 * directly)
494 * This function is called to lookup a variable construct a 'variable' object.
495 * It would be called in the following example as would be seen in
496 * extensions.lua.
498 * \code
499 * channel.variable
500 * \endcode
502 static int lua_get_variable(lua_State *L)
504 struct ast_channel *chan;
505 char *name = ast_strdupa(luaL_checkstring(L, 2));
506 char *value = NULL;
507 char *workspace = alloca(LUA_BUF_SIZE);
508 workspace[0] = '\0';
510 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
511 chan = lua_touserdata(L, -1);
512 lua_pop(L, 1);
514 lua_push_variable_table(L, name);
516 /* if this is not a request for a dialplan funciton attempt to retrieve
517 * the value of the variable */
518 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
519 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
522 if (value) {
523 lua_pushstring(L, value);
524 lua_setfield(L, -2, "value");
527 return 1;
531 * \brief [lua_CFunction] Set the value of a channel variable or dialplan
532 * function (for access from lua, don't call directly)
534 * This function is called to set a variable or dialplan function. It would be
535 * called in the following example as would be seen in extensions.lua.
537 * \code
538 * channel.variable = "value"
539 * \endcode
541 static int lua_set_variable(lua_State *L)
543 struct ast_channel *chan;
544 int autoservice;
545 const char *name = luaL_checkstring(L, 2);
546 const char *value = luaL_checkstring(L, 3);
548 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
549 chan = lua_touserdata(L, -1);
550 lua_pop(L, 1);
552 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
553 autoservice = lua_toboolean(L, -1);
554 lua_pop(L, 1);
556 if (autoservice)
557 ast_autoservice_stop(chan);
559 pbx_builtin_setvar_helper(chan, name, value);
561 if (autoservice)
562 ast_autoservice_start(chan);
564 return 0;
568 * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
569 * function (for access from lua, don't call directly)
571 * This function is called to create a 'variable' object to access a dialplan
572 * function. It would be called in the following example as would be seen in
573 * extensions.lua.
575 * \code
576 * channel.func("arg1", "arg2", "arg3")
577 * \endcode
579 * To actually do anything with the resulting value you must use the 'get()'
580 * and 'set()' methods (the reason is the resulting value is not a value, but
581 * an object in the form of a lua table).
583 static int lua_func_read(lua_State *L)
585 int nargs = lua_gettop(L);
586 char fullname[LUA_EXT_DATA_SIZE] = "";
587 char *fullname_next = fullname, *name;
588 size_t fullname_left = sizeof(fullname);
590 lua_getfield(L, 1, "name");
591 name = ast_strdupa(lua_tostring(L, -1));
592 lua_pop(L, 1);
594 ast_build_string(&fullname_next, &fullname_left, "%s(", name);
596 if (nargs > 1) {
597 int i;
599 if (!lua_isnil(L, 2))
600 ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
602 for (i = 3; i <= nargs; i++) {
603 if (lua_isnil(L, i))
604 ast_build_string(&fullname_next, &fullname_left, ",");
605 else
606 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
610 ast_build_string(&fullname_next, &fullname_left, ")");
612 lua_push_variable_table(L, fullname);
614 return 1;
618 * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
619 * channel (for access from lua, don't call directly)
621 * \param L the lua_State to use
623 * This function will set a flag that will cause pbx_lua to maintain an
624 * autoservice on this channel. The autoservice will automatically be stopped
625 * and restarted before calling applications and functions.
627 * \return This function returns the result of the ast_autoservice_start()
628 * function as a boolean to its lua caller.
630 static int lua_autoservice_start(lua_State *L)
632 struct ast_channel *chan;
633 int res;
635 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
636 chan = lua_touserdata(L, -1);
637 lua_pop(L, 1);
639 res = ast_autoservice_start(chan);
641 lua_pushboolean(L, !res);
642 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
644 lua_pushboolean(L, !res);
645 return 1;
649 * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
650 * this channel (for access from lua, don't call directly)
652 * \param L the lua_State to use
654 * This function will stop any autoservice running and turn off the autoservice
655 * flag. If this function returns false, it's probably because no autoservice
656 * was running to begin with.
658 * \return This function returns the result of the ast_autoservice_stop()
659 * function as a boolean to its lua caller.
661 static int lua_autoservice_stop(lua_State *L)
663 struct ast_channel *chan;
664 int res;
666 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
667 chan = lua_touserdata(L, -1);
668 lua_pop(L, 1);
670 res = ast_autoservice_stop(chan);
672 lua_pushboolean(L, 0);
673 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
675 lua_pushboolean(L, !res);
676 return 1;
680 * \brief [lua_CFunction] Get the status of the autoservice flag (for access
681 * from lua, don't call directly)
683 * \param L the lua_State to use
685 * \return This function returns the status of the autoservice flag as a
686 * boolean to its lua caller.
688 static int lua_autoservice_status(lua_State *L)
690 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
691 return 1;
695 * \brief [lua_CFunction] Check if this channel has been hungup or not (for
696 * access from lua, don't call directly)
698 * \param L the lua_State to use
700 * \return This function returns true if the channel was hungup
702 static int lua_check_hangup(lua_State *L)
704 struct ast_channel *chan;
705 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
706 chan = lua_touserdata(L, -1);
707 lua_pop(L, 1);
709 lua_pushboolean(L, ast_check_hangup(chan));
710 return 1;
714 * \brief Store the sort order of each context
716 * In the event of an error, an error string will be pushed onto the lua stack.
718 * \retval 0 success
719 * \retval 1 failure
721 static int lua_sort_extensions(lua_State *L)
723 int extensions, extensions_order;
725 /* create the extensions_order table */
726 lua_newtable(L);
727 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
728 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
729 extensions_order = lua_gettop(L);
731 /* sort each context in the extensions table */
732 /* load the 'extensions' table */
733 lua_getglobal(L, "extensions");
734 extensions = lua_gettop(L);
735 if (lua_isnil(L, -1)) {
736 lua_pop(L, 1);
737 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
738 return 1;
741 /* iterate through the extensions table and create a
742 * matching table (holding the sort order) in the
743 * extensions_order table for each context that is found
745 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
746 int context = lua_gettop(L);
747 int context_name = context - 1;
748 int context_order;
750 lua_pushvalue(L, context_name);
751 lua_newtable(L);
752 context_order = lua_gettop(L);
754 /* iterate through this context an popluate the corrisponding
755 * table in the extensions_order table */
756 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
757 int exten = lua_gettop(L) - 1;
759 lua_pushinteger(L, lua_objlen(L, context_order) + 1);
760 lua_pushvalue(L, exten);
761 lua_settable(L, context_order);
763 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
765 /* now sort the new table */
767 /* push the table.sort function */
768 lua_getglobal(L, "table");
769 lua_getfield(L, -1, "sort");
770 lua_remove(L, -2); /* remove the 'table' table */
772 /* push the context_order table */
773 lua_pushvalue(L, context_name);
774 lua_gettable(L, extensions_order);
776 /* push the comp function */
777 lua_pushcfunction(L, &lua_extension_cmp);
779 if (lua_pcall(L, 2, 0, 0)) {
780 lua_insert(L, -5);
781 lua_pop(L, 4);
782 return 1;
786 /* remove the extensions table and the extensions_order table */
787 lua_pop(L, 2);
788 return 0;
792 * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
793 * call directly)
795 * This function returns true if the first extension passed should match after
796 * the second. It behaves like the '<' operator.
798 static int lua_extension_cmp(lua_State *L)
800 const char *a = luaL_checkstring(L, -2);
801 const char *b = luaL_checkstring(L, -1);
803 if (ast_extension_cmp(a, b) == -1)
804 lua_pushboolean(L, 1);
805 else
806 lua_pushboolean(L, 0);
808 return 1;
812 * \brief Load the extensions.lua file in to a buffer and execute the file
814 * \param L the lua_State to use
815 * \param size a pointer to store the size of the buffer
817 * \note The caller is expected to free the buffer at some point.
819 * \return a pointer to the buffer
821 static char *lua_read_extensions_file(lua_State *L, long *size)
823 FILE *f;
824 char *data;
825 char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
826 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
828 if (!(f = fopen(path, "r"))) {
829 lua_pushstring(L, "cannot open '");
830 lua_pushstring(L, path);
831 lua_pushstring(L, "' for reading: ");
832 lua_pushstring(L, strerror(errno));
833 lua_concat(L, 4);
835 return NULL;
838 fseek(f, 0l, SEEK_END);
839 *size = ftell(f);
841 fseek(f, 0l, SEEK_SET);
843 if (!(data = ast_malloc(*size))) {
844 *size = 0;
845 fclose(f);
846 lua_pushstring(L, "not enough memory");
847 return NULL;
850 fread(data, sizeof(char), *size, f);
851 fclose(f);
853 if (luaL_loadbuffer(L, data, *size, "extensions.lua")
854 || lua_pcall(L, 0, LUA_MULTRET, 0)
855 || lua_sort_extensions(L)) {
856 ast_free(data);
857 data = NULL;
858 *size = 0;
860 return data;
864 * \brief Load the extensions.lua file from the internal buffer
866 * \param L the lua_State to use
867 * \param chan channel to work on
869 * This function also sets up some constructs used by the extensions.lua file.
870 * In the event of an error, an error string will be pushed onto the lua stack.
872 * \retval 0 success
873 * \retval 1 failure
875 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
878 /* store a pointer to this channel */
879 lua_pushlightuserdata(L, chan);
880 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
882 luaL_openlibs(L);
884 /* load and sort extensions */
885 ast_mutex_lock(&config_file_lock);
886 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
887 || lua_pcall(L, 0, LUA_MULTRET, 0)
888 || lua_sort_extensions(L)) {
889 ast_mutex_unlock(&config_file_lock);
890 return 1;
892 ast_mutex_unlock(&config_file_lock);
894 /* now we setup special tables and functions */
896 lua_create_app_table(L);
897 lua_create_channel_table(L);
899 lua_create_variable_metatable(L);
900 lua_create_application_metatable(L);
902 lua_create_autoservice_functions(L);
903 lua_create_hangup_function(L);
905 return 0;
909 * \brief Reload the extensions file and update the internal buffers if it
910 * loads correctly.
912 * \warning This function should not be called on a lua_State returned from
913 * lua_get_state().
915 * \param L the lua_State to use (must be freshly allocated with
916 * luaL_newstate(), don't use lua_get_state())
918 static int lua_reload_extensions(lua_State *L)
920 long size = 0;
921 char *data = NULL;
923 luaL_openlibs(L);
925 if (!(data = lua_read_extensions_file(L, &size))) {
926 return 1;
929 ast_mutex_lock(&config_file_lock);
931 if (config_file_data)
932 ast_free(config_file_data);
934 config_file_data = data;
935 config_file_size = size;
937 ast_mutex_unlock(&config_file_lock);
938 return 0;
942 * \brief Free the internal extensions buffer.
944 static void lua_free_extensions()
946 ast_mutex_lock(&config_file_lock);
947 config_file_size = 0;
948 ast_free(config_file_data);
949 ast_mutex_unlock(&config_file_lock);
953 * \brief Get the lua_State for this channel
955 * If no channel is passed then a new state is allocated. States with no
956 * channel assocatied with them should only be used for matching extensions.
957 * If the channel does not yet have a lua state associated with it, one will be
958 * created.
960 * \note If no channel was passed then the caller is expected to free the state
961 * using lua_close().
963 * \return a lua_State
965 static lua_State *lua_get_state(struct ast_channel *chan)
967 struct ast_datastore *datastore = NULL;
968 lua_State *L;
970 if (!chan) {
971 lua_State *L = luaL_newstate();
972 if (!L) {
973 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
974 return NULL;
977 if (lua_load_extensions(L, NULL)) {
978 const char *error = lua_tostring(L, -1);
979 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
980 lua_close(L);
981 return NULL;
983 return L;
984 } else {
985 ast_channel_lock(chan);
986 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
987 ast_channel_unlock(chan);
989 if (!datastore) {
990 /* nothing found, allocate a new lua state */
991 datastore = ast_datastore_alloc(&lua_datastore, NULL);
992 if (!datastore) {
993 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
994 return NULL;
997 datastore->data = luaL_newstate();
998 if (!datastore->data) {
999 ast_datastore_free(datastore);
1000 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1001 return NULL;
1004 ast_channel_lock(chan);
1005 ast_channel_datastore_add(chan, datastore);
1006 ast_channel_unlock(chan);
1008 L = datastore->data;
1010 if (lua_load_extensions(L, chan)) {
1011 const char *error = lua_tostring(L, -1);
1012 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
1014 ast_channel_lock(chan);
1015 ast_channel_datastore_remove(chan, datastore);
1016 ast_channel_unlock(chan);
1018 ast_datastore_free(datastore);
1019 return NULL;
1023 return datastore->data;
1027 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1029 int res;
1030 lua_State *L;
1031 struct ast_module_user *u = ast_module_user_add(chan);
1032 if (!u) {
1033 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1034 return 0;
1037 L = lua_get_state(chan);
1038 if (!L) {
1039 ast_module_user_remove(u);
1040 return 0;
1043 res = lua_find_extension(L, context, exten, priority, &exists, 0);
1045 if (!chan) lua_close(L);
1046 ast_module_user_remove(u);
1047 return res;
1050 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1052 int res;
1053 lua_State *L;
1054 struct ast_module_user *u = ast_module_user_add(chan);
1055 if (!u) {
1056 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1057 return 0;
1060 L = lua_get_state(chan);
1061 if (!L) {
1062 ast_module_user_remove(u);
1063 return 0;
1066 res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1068 if (!chan) lua_close(L);
1069 ast_module_user_remove(u);
1070 return res;
1073 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1075 int res;
1076 lua_State *L;
1077 struct ast_module_user *u = ast_module_user_add(chan);
1078 if (!u) {
1079 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1080 return 0;
1083 L = lua_get_state(chan);
1084 if (!L) {
1085 ast_module_user_remove(u);
1086 return 0;
1089 res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1091 if (!chan) lua_close(L);
1092 ast_module_user_remove(u);
1093 return res;
1097 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1099 int res;
1100 lua_State *L;
1101 struct ast_module_user *u = ast_module_user_add(chan);
1102 if (!u) {
1103 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1104 return -1;
1107 L = lua_get_state(chan);
1108 if (!L) {
1109 ast_module_user_remove(u);
1110 return -1;
1113 /* push the extension function onto the stack */
1114 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1115 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1116 if (!chan) lua_close(L);
1117 ast_module_user_remove(u);
1118 return -1;
1121 lua_update_registry(L, context, exten, priority);
1123 lua_pushstring(L, context);
1124 lua_pushstring(L, exten);
1126 res = lua_pcall(L, 2, 0, 0);
1127 if (res) {
1128 if (res == LUA_ERRRUN) {
1129 if (lua_isnumber(L, -1)) {
1130 res = lua_tointeger(L, -1);
1131 } else if (lua_isstring(L, -1)) {
1132 const char *error = lua_tostring(L, -1);
1133 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1134 res = -1;
1136 } else {
1137 res = -1;
1140 if (!chan) lua_close(L);
1141 ast_module_user_remove(u);
1142 return res;
1146 * \brief Locate an extensions and optionally push the matching function on the
1147 * stack
1149 * \param L the lua_State to use
1150 * \param context the context to look in
1151 * \param exten the extension to look up
1152 * \param priority the priority to check, '1' is the only valid priority
1153 * \param func the calling func, used to adjust matching behavior between,
1154 * match, canmatch, and matchmore
1155 * \param push_func whether or not to push the lua function for the given
1156 * extension onto the stack
1158 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1160 int context_table, context_order_table, i;
1162 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1163 if (priority != 1)
1164 return 0;
1166 /* load the 'extensions' table */
1167 lua_getglobal(L, "extensions");
1168 if (lua_isnil(L, -1)) {
1169 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1170 lua_pop(L, 1);
1171 return 0;
1174 /* load the given context */
1175 lua_getfield(L, -1, context);
1176 if (lua_isnil(L, -1)) {
1177 lua_pop(L, 2);
1178 return 0;
1181 /* remove the extensions table */
1182 lua_remove(L, -2);
1184 context_table = lua_gettop(L);
1186 /* load the extensions order table for this context */
1187 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1188 lua_getfield(L, -1, context);
1190 lua_remove(L, -2); /* remove the extensions order table */
1192 context_order_table = lua_gettop(L);
1194 /* step through the extensions looking for a match */
1195 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1196 int e_index, isnumber, match = 0;
1197 const char *e;
1199 lua_pushinteger(L, i);
1200 lua_gettable(L, context_order_table);
1201 e_index = lua_gettop(L);
1202 isnumber = lua_isnumber(L, e_index);
1204 if (!(e = lua_tostring(L, e_index))) {
1205 lua_pop(L, 1);
1206 continue;
1209 /* make sure this is not the 'include' extension */
1210 if (!strcasecmp(e, "include")) {
1211 lua_pop(L, 1);
1212 continue;
1215 if (func == &matchmore)
1216 match = ast_extension_close(e, exten, E_MATCHMORE);
1217 else if (func == &canmatch)
1218 match = ast_extension_close(e, exten, E_CANMATCH);
1219 else
1220 match = ast_extension_match(e, exten);
1222 /* the extension matching functions return 0 on fail, 1 on
1223 * match, 2 on earlymatch */
1225 if (!match) {
1226 lua_pop(L, 1);
1227 continue; /* keep trying */
1230 if (func == &matchmore && match == 2) {
1231 /* We match an extension ending in '!'. The decision in
1232 * this case is final and counts as no match. */
1233 lua_pop(L, 3);
1234 return 0;
1237 /* remove the context table, the context order table, and the
1238 * extension (or replace the extension with the corisponding
1239 * function) */
1240 if (push_func) {
1241 /* here we must convert the exten back to an integer
1242 * because lua_tostring will change the value on the
1243 * stack to a string */
1244 if (isnumber) {
1245 int e_int = lua_tointeger(L, e_index);
1246 lua_pop(L, 1); /* the exten should be the top of the stack */
1247 lua_pushinteger(L, e_int);
1249 lua_gettable(L, context_table);
1250 lua_insert(L, -3);
1251 lua_pop(L, 2);
1252 } else {
1253 lua_pop(L, 3);
1256 return 1;
1259 /* load the includes for this context */
1260 lua_getfield(L, context_table, "include");
1261 if (lua_isnil(L, -1)) {
1262 lua_pop(L, 3);
1263 return 0;
1266 /* remove the context and the order table*/
1267 lua_remove(L, context_order_table);
1268 lua_remove(L, context_table);
1270 /* Now try any includes we have in this context */
1271 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1272 const char *c = lua_tostring(L, -1);
1273 if (!c)
1274 continue;
1276 if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1277 /* remove the value, the key, and the includes table
1278 * from the stack. Leave the function behind if
1279 * necessary */
1281 if (push_func)
1282 lua_insert(L, -4);
1284 lua_pop(L, 3);
1285 return 1;
1289 /* pop the includes table */
1290 lua_pop(L, 1);
1291 return 0;
1294 static struct ast_switch lua_switch = {
1295 .name = "Lua",
1296 .description = "Lua PBX Switch",
1297 .exists = exists,
1298 .canmatch = canmatch,
1299 .exec = exec,
1300 .matchmore = matchmore,
1304 static int load_or_reload_lua_stuff(void)
1306 int res = AST_MODULE_LOAD_SUCCESS;
1308 lua_State *L = luaL_newstate();
1309 if (!L) {
1310 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1311 return AST_MODULE_LOAD_DECLINE;
1314 if (lua_reload_extensions(L)) {
1315 const char *error = lua_tostring(L, -1);
1316 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1317 res = AST_MODULE_LOAD_DECLINE;
1320 lua_close(L);
1321 return res;
1324 static int unload_module(void)
1326 ast_unregister_switch(&lua_switch);
1327 lua_free_extensions();
1328 return 0;
1331 static int reload(void)
1333 return load_or_reload_lua_stuff();
1336 static int load_module(void)
1338 int res;
1340 if ((res = load_or_reload_lua_stuff()))
1341 return res;
1343 if (ast_register_switch(&lua_switch)) {
1344 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1345 return AST_MODULE_LOAD_DECLINE;
1348 return AST_MODULE_LOAD_SUCCESS;
1351 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Lua PBX Switch",
1352 .load = load_module,
1353 .unload = unload_module,
1354 .reload = reload,