Merged revisions 325673 via svnmerge from
[asterisk/asterisk.git] / pbx / pbx_lua.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2007, Digium, Inc.
5  *
6  * Matthew Nicholson <mnicholson@digium.com>
7  *
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.
13  *
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.
17  */
18
19 /*! 
20  * \file
21  *
22  * \author Matthew Nicholson <mnicholson@digium.com>
23  * \brief Lua PBX Switch
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>lua</depend>
29  ***/
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34
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"
43 #include "asterisk/hashtab.h"
44
45 #include <lua.h>
46 #include <lauxlib.h>
47 #include <lualib.h>
48
49 static char *config = "extensions.lua";
50 static char *registrar = "pbx_lua";
51
52 #define LUA_EXT_DATA_SIZE 256
53 #define LUA_BUF_SIZE 4096
54
55 /* This value is used by the lua engine to signal that a Goto or dialplan jump
56  * was detected. Ensure this value does not conflict with any values dialplan
57  * applications might return */
58 #define LUA_GOTO_DETECTED 5
59
60 static char *lua_read_extensions_file(lua_State *L, long *size);
61 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
62 static int lua_reload_extensions(lua_State *L);
63 static void lua_free_extensions(void);
64 static int lua_sort_extensions(lua_State *L);
65 static int lua_register_switches(lua_State *L);
66 static int lua_register_hints(lua_State *L);
67 static int lua_extension_cmp(lua_State *L);
68 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
69 static int lua_pbx_findapp(lua_State *L);
70 static int lua_pbx_exec(lua_State *L);
71
72 static int lua_get_variable_value(lua_State *L);
73 static int lua_set_variable_value(lua_State *L);
74 static int lua_get_variable(lua_State *L);
75 static int lua_set_variable(lua_State *L);
76 static int lua_func_read(lua_State *L);
77
78 static int lua_autoservice_start(lua_State *L);
79 static int lua_autoservice_stop(lua_State *L);
80 static int lua_autoservice_status(lua_State *L);
81 static int lua_check_hangup(lua_State *L);
82 static int lua_error_function(lua_State *L);
83
84 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
85 static void lua_push_variable_table(lua_State *L, const char *name);
86 static void lua_create_app_table(lua_State *L);
87 static void lua_create_channel_table(lua_State *L);
88 static void lua_create_variable_metatable(lua_State *L);
89 static void lua_create_application_metatable(lua_State *L);
90 static void lua_create_autoservice_functions(lua_State *L);
91 static void lua_create_hangup_function(lua_State *L);
92 static void lua_detect_goto(lua_State *L);
93
94 static void lua_state_destroy(void *data);
95 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
96 static lua_State *lua_get_state(struct ast_channel *chan);
97
98 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
99 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
100 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
101 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
102
103 AST_MUTEX_DEFINE_STATIC(config_file_lock);
104 static char *config_file_data = NULL;
105 static long config_file_size = 0;
106
107 static struct ast_context *local_contexts = NULL;
108 static struct ast_hashtab *local_table = NULL;
109
110 static const struct ast_datastore_info lua_datastore = {
111         .type = "lua",
112         .destroy = lua_state_destroy,
113         .chan_fixup = lua_datastore_fixup,
114 };
115
116
117 /*!
118  * \brief The destructor for lua_datastore
119  */
120 static void lua_state_destroy(void *data)
121 {
122         if (data)
123                 lua_close(data);
124 }
125
126 /*!
127  * \brief The fixup function for the lua_datastore.
128  * \param data the datastore data, in this case it will be a lua_State
129  * \param old_chan the channel we are moving from
130  * \param new_chan the channel we are moving to
131  *
132  * This function updates our internal channel pointer.
133  */
134 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
135 {
136         lua_State *L = data;
137         lua_pushlightuserdata(L, new_chan);
138         lua_setfield(L, LUA_REGISTRYINDEX, "channel");
139 }
140
141 /*!
142  * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
143  * call directly)
144  *
145  * This function would be called in the following example as it would be found
146  * in extensions.lua.
147  *
148  * \code
149  * app.dial
150  * \endcode
151  */
152 static int lua_pbx_findapp(lua_State *L)
153 {
154         const char *app_name = luaL_checkstring(L, 2);
155         
156         lua_newtable(L);
157
158         lua_pushstring(L, "name");
159         lua_pushstring(L, app_name);
160         lua_settable(L, -3);
161
162         luaL_getmetatable(L, "application");
163         lua_setmetatable(L, -2);
164
165         return 1;
166 }
167
168 /*!
169  * \brief [lua_CFunction] This function is part of the 'application' metatable
170  * and is used to execute applications similar to pbx_exec() (for access from
171  * lua, don't call directly)
172  *
173  * \param L the lua_State to use
174  * \return nothing
175  *
176  * This funciton is executed as the '()' operator for apps accessed through the
177  * 'app' table.
178  *
179  * \code
180  * app.playback('demo-congrats')
181  * \endcode
182  */
183 static int lua_pbx_exec(lua_State *L)
184 {
185         int res, nargs = lua_gettop(L);
186         char data[LUA_EXT_DATA_SIZE] = "";
187         char *data_next = data, *app_name;
188         char *context, *exten;
189         char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
190         int priority, autoservice;
191         size_t data_left = sizeof(data);
192         struct ast_app *app;
193         struct ast_channel *chan;
194         
195         lua_getfield(L, 1, "name");
196         app_name = ast_strdupa(lua_tostring(L, -1));
197         lua_pop(L, 1);
198         
199         if (!(app = pbx_findapp(app_name))) {
200                 lua_pushstring(L, "application '");
201                 lua_pushstring(L, app_name);
202                 lua_pushstring(L, "' not found");
203                 lua_concat(L, 3);
204                 return lua_error(L);
205         }
206         
207
208         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
209         chan = lua_touserdata(L, -1);
210         lua_pop(L, 1);
211         
212         
213         lua_getfield(L, LUA_REGISTRYINDEX, "context");
214         context = ast_strdupa(lua_tostring(L, -1));
215         lua_pop(L, 1);
216         
217         lua_getfield(L, LUA_REGISTRYINDEX, "exten");
218         exten = ast_strdupa(lua_tostring(L, -1));
219         lua_pop(L, 1);
220         
221         lua_getfield(L, LUA_REGISTRYINDEX, "priority");
222         priority = lua_tointeger(L, -1);
223         lua_pop(L, 1);
224
225
226         if (nargs > 1) {
227                 int i;
228
229                 if (!lua_isnil(L, 2))
230                         ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
231
232                 for (i = 3; i <= nargs; i++) {
233                         if (lua_isnil(L, i))
234                                 ast_build_string(&data_next, &data_left, ",");
235                         else
236                                 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
237                 }
238         }
239         
240         ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
241                         exten, context, priority,
242                         term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
243                         term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
244                         term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
245
246         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
247         autoservice = lua_toboolean(L, -1);
248         lua_pop(L, 1);
249
250         if (autoservice)
251                 ast_autoservice_stop(chan);
252
253         res = pbx_exec(chan, app, data);
254         
255         if (autoservice)
256                 ast_autoservice_start(chan);
257
258         /* error executing an application, report it */
259         if (res) {
260                 lua_pushinteger(L, res);
261                 return lua_error(L);
262         }
263
264         lua_detect_goto(L);
265
266         return 0;
267 }
268
269 /*!
270  * \brief Detect if a Goto or other dialplan jump has been executed and return
271  * control to the pbx engine.
272  */
273 static void lua_detect_goto(lua_State *L)
274 {
275         struct ast_channel *chan;
276
277         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
278         chan = lua_touserdata(L, -1);
279         lua_pop(L, 1);
280
281         /* check context */
282         lua_getfield(L, LUA_REGISTRYINDEX, "context");
283         lua_pushstring(L, chan->context);
284         if (!lua_equal(L, -1, -2)) {
285                 lua_pushliteral(L, "context");
286                 goto e_goto_detected;
287         }
288         lua_pop(L, 2);
289
290         /* check exten */
291         lua_getfield(L, LUA_REGISTRYINDEX, "exten");
292         lua_pushstring(L, chan->exten);
293         if (!lua_equal(L, -1, -2)) {
294                 lua_pushliteral(L, "exten");
295                 goto e_goto_detected;
296         }
297         lua_pop(L, 2);
298
299         /* check priority */
300         lua_getfield(L, LUA_REGISTRYINDEX, "priority");
301         lua_pushinteger(L, chan->priority);
302         if (!lua_equal(L, -1, -2)) {
303                 lua_pushliteral(L, "priority");
304                 goto e_goto_detected;
305         }
306         lua_pop(L, 2);
307         return;
308
309 e_goto_detected:
310         /* format our debug message */
311         lua_insert(L, -3);
312
313         lua_pushliteral(L, " changed from ");
314         lua_insert(L, -3);
315
316         lua_pushliteral(L, " to ");
317         lua_insert(L, -2);
318
319         lua_concat(L, 5);
320
321         ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
322         lua_pop(L, 1);
323
324         /* let the lua engine know it needs to return control to the pbx */
325         lua_pushinteger(L, LUA_GOTO_DETECTED);
326         lua_error(L);
327 }
328
329 /*!
330  * \brief [lua_CFunction] Used to get the value of a variable or dialplan
331  * function (for access from lua, don't call directly)
332  * 
333  * The value of the variable or function is returned.  This function is the
334  * 'get()' function in the following example as would be seen in
335  * extensions.lua.
336  *
337  * \code
338  * channel.variable:get()
339  * \endcode
340  */
341 static int lua_get_variable_value(lua_State *L)
342 {
343         struct ast_channel *chan;
344         char *value = NULL, *name;
345         char *workspace = alloca(LUA_BUF_SIZE);
346         int autoservice;
347
348         workspace[0] = '\0';
349
350         if (!lua_istable(L, 1)) {
351                 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
352                 return lua_error(L);
353         }
354         
355         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
356         chan = lua_touserdata(L, -1);
357         lua_pop(L, 1);
358
359         lua_getfield(L, 1, "name");
360         name = ast_strdupa(lua_tostring(L, -1));
361         lua_pop(L, 1);
362         
363         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
364         autoservice = lua_toboolean(L, -1);
365         lua_pop(L, 1);
366
367         if (autoservice)
368                 ast_autoservice_stop(chan);
369         
370         /* if this is a dialplan function then use ast_func_read(), otherwise
371          * use pbx_retrieve_variable() */
372         if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
373                 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
374         } else {
375                 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
376         }
377         
378         if (autoservice)
379                 ast_autoservice_start(chan);
380
381         if (value) {
382                 lua_pushstring(L, value);
383         } else {
384                 lua_pushnil(L);
385         }
386
387         return 1;
388 }
389
390 /*!
391  * \brief [lua_CFunction] Used to set the value of a variable or dialplan
392  * function (for access from lua, don't call directly)
393  * 
394  * This function is the 'set()' function in the following example as would be
395  * seen in extensions.lua.
396  *
397  * \code
398  * channel.variable:set("value")
399  * \endcode
400  */
401 static int lua_set_variable_value(lua_State *L)
402 {
403         const char *name, *value;
404         struct ast_channel *chan;
405         int autoservice;
406
407         if (!lua_istable(L, 1)) {
408                 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
409                 return lua_error(L);
410         }
411
412         lua_getfield(L, 1, "name");
413         name = ast_strdupa(lua_tostring(L, -1));
414         lua_pop(L, 1);
415
416         value = luaL_checkstring(L, 2);
417         
418         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
419         chan = lua_touserdata(L, -1);
420         lua_pop(L, 1);
421
422         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
423         autoservice = lua_toboolean(L, -1);
424         lua_pop(L, 1);
425
426         if (autoservice)
427                 ast_autoservice_stop(chan);
428
429         pbx_builtin_setvar_helper(chan, name, value);
430         
431         if (autoservice)
432                 ast_autoservice_start(chan);
433
434         return 0;
435 }
436
437 /*!
438  * \brief Update the lua registry with the given context, exten, and priority.
439  *
440  * \param L the lua_State to use
441  * \param context the new context
442  * \param exten the new exten
443  * \param priority the new priority
444  */
445 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
446 {
447         lua_pushstring(L, context);
448         lua_setfield(L, LUA_REGISTRYINDEX, "context");
449
450         lua_pushstring(L, exten);
451         lua_setfield(L, LUA_REGISTRYINDEX, "exten");
452
453         lua_pushinteger(L, priority);
454         lua_setfield(L, LUA_REGISTRYINDEX, "priority");
455 }
456
457 /*!
458  * \brief Push a 'variable' table on the stack for access the channel variable
459  * with the given name.
460  *
461  * \param L the lua_State to use
462  * \param name the name of the variable
463  */
464 static void lua_push_variable_table(lua_State *L, const char *name)
465 {
466         lua_newtable(L);
467         luaL_getmetatable(L, "variable");
468         lua_setmetatable(L, -2);
469
470         lua_pushstring(L, name);
471         lua_setfield(L, -2, "name");
472         
473         lua_pushcfunction(L, &lua_get_variable_value);
474         lua_setfield(L, -2, "get");
475         
476         lua_pushcfunction(L, &lua_set_variable_value);
477         lua_setfield(L, -2, "set");
478 }
479
480 /*!
481  * \brief Create the global 'app' table for executing applications
482  *
483  * \param L the lua_State to use
484  */
485 static void lua_create_app_table(lua_State *L)
486 {
487         lua_newtable(L);
488         luaL_newmetatable(L, "app");
489
490         lua_pushstring(L, "__index");
491         lua_pushcfunction(L, &lua_pbx_findapp);
492         lua_settable(L, -3);
493
494         lua_setmetatable(L, -2);
495         lua_setglobal(L, "app");
496 }
497
498 /*!
499  * \brief Create the global 'channel' table for accesing channel variables
500  *
501  * \param L the lua_State to use
502  */
503 static void lua_create_channel_table(lua_State *L)
504 {
505         lua_newtable(L);
506         luaL_newmetatable(L, "channel_data");
507
508         lua_pushstring(L, "__index");
509         lua_pushcfunction(L, &lua_get_variable);
510         lua_settable(L, -3);
511
512         lua_pushstring(L, "__newindex");
513         lua_pushcfunction(L, &lua_set_variable);
514         lua_settable(L, -3);
515
516         lua_setmetatable(L, -2);
517         lua_setglobal(L, "channel");
518 }
519
520 /*!
521  * \brief Create the 'variable' metatable, used to retrieve channel variables
522  *
523  * \param L the lua_State to use
524  */
525 static void lua_create_variable_metatable(lua_State *L)
526 {
527         luaL_newmetatable(L, "variable");
528
529         lua_pushstring(L, "__call");
530         lua_pushcfunction(L, &lua_func_read);
531         lua_settable(L, -3);
532
533         lua_pop(L, 1);
534 }
535
536 /*!
537  * \brief Create the 'application' metatable, used to execute asterisk
538  * applications from lua 
539  *
540  * \param L the lua_State to use
541  */
542 static void lua_create_application_metatable(lua_State *L)
543 {
544         luaL_newmetatable(L, "application");
545
546         lua_pushstring(L, "__call");
547         lua_pushcfunction(L, &lua_pbx_exec);
548         lua_settable(L, -3);
549
550         lua_pop(L, 1);
551 }
552
553 /*!
554  * \brief Create the autoservice functions
555  *
556  * \param L the lua_State to use
557  */
558 static void lua_create_autoservice_functions(lua_State *L)
559 {
560         lua_pushcfunction(L, &lua_autoservice_start);
561         lua_setglobal(L, "autoservice_start");
562         
563         lua_pushcfunction(L, &lua_autoservice_stop);
564         lua_setglobal(L, "autoservice_stop");
565
566         lua_pushcfunction(L, &lua_autoservice_status);
567         lua_setglobal(L, "autoservice_status");
568
569         lua_pushboolean(L, 1);
570         lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
571 }
572
573 /*!
574  * \brief Create the hangup check function
575  *
576  * \param L the lua_State to use
577  */
578 static void lua_create_hangup_function(lua_State *L)
579 {
580         lua_pushcfunction(L, &lua_check_hangup);
581         lua_setglobal(L, "check_hangup");
582 }
583
584 /*!
585  * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
586  * directly)
587  * 
588  * This function is called to lookup a variable construct a 'variable' object.
589  * It would be called in the following example as would be seen in
590  * extensions.lua.
591  *
592  * \code
593  * channel.variable
594  * \endcode
595  */
596 static int lua_get_variable(lua_State *L)
597 {
598         struct ast_channel *chan;
599         char *name = ast_strdupa(luaL_checkstring(L, 2));
600         char *value = NULL;
601         char *workspace = alloca(LUA_BUF_SIZE);
602         workspace[0] = '\0';
603         
604         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
605         chan = lua_touserdata(L, -1);
606         lua_pop(L, 1);
607
608         lua_push_variable_table(L, name);
609         
610         /* if this is not a request for a dialplan funciton attempt to retrieve
611          * the value of the variable */
612         if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
613                 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
614         }
615
616         if (value) {
617                 lua_pushstring(L, value);
618                 lua_setfield(L, -2, "value");
619         }
620
621         return 1;       
622 }
623
624 /*!
625  * \brief [lua_CFunction] Set the value of a channel variable or dialplan
626  * function (for access from lua, don't call directly)
627  * 
628  * This function is called to set a variable or dialplan function.  It would be
629  * called in the following example as would be seen in extensions.lua.
630  *
631  * \code
632  * channel.variable = "value"
633  * \endcode
634  */
635 static int lua_set_variable(lua_State *L)
636 {
637         struct ast_channel *chan;
638         int autoservice;
639         const char *name = luaL_checkstring(L, 2);
640         const char *value = luaL_checkstring(L, 3);
641
642         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
643         chan = lua_touserdata(L, -1);
644         lua_pop(L, 1);
645
646         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
647         autoservice = lua_toboolean(L, -1);
648         lua_pop(L, 1);
649
650         if (autoservice)
651                 ast_autoservice_stop(chan);
652
653         pbx_builtin_setvar_helper(chan, name, value);
654         
655         if (autoservice)
656                 ast_autoservice_start(chan);
657
658         return 0;
659 }
660
661 /*!
662  * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
663  * function (for access from lua, don't call directly)
664  * 
665  * This function is called to create a 'variable' object to access a dialplan
666  * function.  It would be called in the following example as would be seen in
667  * extensions.lua.
668  *
669  * \code
670  * channel.func("arg1", "arg2", "arg3")
671  * \endcode
672  *
673  * To actually do anything with the resulting value you must use the 'get()'
674  * and 'set()' methods (the reason is the resulting value is not a value, but
675  * an object in the form of a lua table).
676  */
677 static int lua_func_read(lua_State *L)
678 {
679         int nargs = lua_gettop(L);
680         char fullname[LUA_EXT_DATA_SIZE] = "";
681         char *fullname_next = fullname, *name;
682         size_t fullname_left = sizeof(fullname);
683         
684         lua_getfield(L, 1, "name");
685         name = ast_strdupa(lua_tostring(L, -1));
686         lua_pop(L, 1);
687
688         ast_build_string(&fullname_next, &fullname_left, "%s(", name);
689         
690         if (nargs > 1) {
691                 int i;
692
693                 if (!lua_isnil(L, 2))
694                         ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
695
696                 for (i = 3; i <= nargs; i++) {
697                         if (lua_isnil(L, i))
698                                 ast_build_string(&fullname_next, &fullname_left, ",");
699                         else
700                                 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
701                 }
702         }
703
704         ast_build_string(&fullname_next, &fullname_left, ")");
705         
706         lua_push_variable_table(L, fullname);
707         
708         return 1;
709 }
710
711 /*!
712  * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
713  * channel (for access from lua, don't call directly)
714  *
715  * \param L the lua_State to use
716  *
717  * This function will set a flag that will cause pbx_lua to maintain an
718  * autoservice on this channel.  The autoservice will automatically be stopped
719  * and restarted before calling applications and functions.
720  */
721 static int lua_autoservice_start(lua_State *L)
722 {
723         struct ast_channel *chan;
724
725         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
726         if (lua_toboolean(L, -1)) {
727                 /* autservice already running */
728                 lua_pop(L, 1);
729                 return 0;
730         }
731         lua_pop(L, 1);
732
733         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
734         chan = lua_touserdata(L, -1);
735         lua_pop(L, 1);
736
737         ast_autoservice_start(chan);
738
739         lua_pushboolean(L, 1);
740         lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
741         return 0;
742 }
743
744 /*!
745  * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
746  * this channel (for access from lua, don't call directly)
747  *
748  * \param L the lua_State to use
749  *
750  * This function will stop any autoservice running and turn off the autoservice
751  * flag.  If this function returns false, it's probably because no autoservice
752  * was running to begin with.
753  */
754 static int lua_autoservice_stop(lua_State *L)
755 {
756         struct ast_channel *chan;
757
758         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
759         if (!lua_toboolean(L, -1)) {
760                 /* no autservice running */
761                 lua_pop(L, 1);
762                 return 0;
763         }
764         lua_pop(L, 1);
765
766         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
767         chan = lua_touserdata(L, -1);
768         lua_pop(L, 1);
769
770         ast_autoservice_stop(chan);
771
772         lua_pushboolean(L, 0);
773         lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
774         return 0;
775 }
776
777 /*!
778  * \brief [lua_CFunction] Get the status of the autoservice flag (for access
779  * from lua, don't call directly)
780  *
781  * \param L the lua_State to use
782  *
783  * \return This function returns the status of the autoservice flag as a
784  * boolean to its lua caller.
785  */
786 static int lua_autoservice_status(lua_State *L)
787 {
788         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
789         return 1;
790 }
791
792 /*!
793  * \brief [lua_CFunction] Check if this channel has been hungup or not (for
794  * access from lua, don't call directly)
795  *
796  * \param L the lua_State to use
797  *
798  * \return This function returns true if the channel was hungup
799  */
800 static int lua_check_hangup(lua_State *L)
801 {
802         struct ast_channel *chan;
803         lua_getfield(L, LUA_REGISTRYINDEX, "channel");
804         chan = lua_touserdata(L, -1);
805         lua_pop(L, 1);
806
807         lua_pushboolean(L, ast_check_hangup(chan));
808         return 1;
809 }
810
811 /*!
812  * \brief [lua_CFunction] Handle lua errors (for access from lua, don't call
813  * directly)
814  *
815  * \param L the lua_State to use
816  */
817 static int lua_error_function(lua_State *L)
818 {
819         int message_index;
820
821         /* pass number arguments right through back to asterisk*/
822         if (lua_isnumber(L, -1)) {
823                 return 1;
824         }
825
826         /* if we are here then we have a string error message, let's attach a
827          * backtrace to it */
828         message_index = lua_gettop(L);
829
830         /* prepare to prepend a new line to the traceback */
831         lua_pushliteral(L, "\n");
832
833         lua_getglobal(L, "debug");
834         lua_getfield(L, -1, "traceback");
835         lua_remove(L, -2); /* remove the 'debug' table */
836
837         lua_pushvalue(L, message_index);
838         lua_remove(L, message_index);
839
840         lua_pushnumber(L, 2);
841
842         lua_call(L, 2, 1);
843
844         /* prepend the new line we prepared above */
845         lua_concat(L, 2);
846
847         return 1;
848 }
849
850 /*!
851  * \brief Store the sort order of each context
852  
853  * In the event of an error, an error string will be pushed onto the lua stack.
854  *
855  * \retval 0 success
856  * \retval 1 failure
857  */
858 static int lua_sort_extensions(lua_State *L)
859 {
860         int extensions, extensions_order;
861
862         /* create the extensions_order table */
863         lua_newtable(L);
864         lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
865         lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
866         extensions_order = lua_gettop(L);
867
868         /* sort each context in the extensions table */
869         /* load the 'extensions' table */
870         lua_getglobal(L, "extensions");
871         extensions = lua_gettop(L);
872         if (lua_isnil(L, -1)) {
873                 lua_pop(L, 1);
874                 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
875                 return 1;
876         }
877
878         /* iterate through the extensions table and create a
879          * matching table (holding the sort order) in the
880          * extensions_order table for each context that is found
881          */
882         for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
883                 int context = lua_gettop(L);
884                 int context_name = context - 1;
885                 int context_order;
886
887                 /* copy the context_name to be used as the key for the
888                  * context_order table in the extensions_order table later */
889                 lua_pushvalue(L, context_name);
890
891                 /* create the context_order table */
892                 lua_newtable(L);
893                 context_order = lua_gettop(L);
894
895                 /* iterate through this context an popluate the corrisponding
896                  * table in the extensions_order table */
897                 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
898                         int exten = lua_gettop(L) - 1;
899
900                         lua_pushinteger(L, lua_objlen(L, context_order) + 1);
901                         lua_pushvalue(L, exten);
902                         lua_settable(L, context_order);
903                 }
904                 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
905
906                 /* now sort the new table */
907
908                 /* push the table.sort function */
909                 lua_getglobal(L, "table");
910                 lua_getfield(L, -1, "sort");
911                 lua_remove(L, -2); /* remove the 'table' table */
912
913                 /* push the context_order table */
914                 lua_pushvalue(L, context_name);
915                 lua_gettable(L, extensions_order);
916
917                 /* push the comp function */
918                 lua_pushcfunction(L, &lua_extension_cmp);
919
920                 if (lua_pcall(L, 2, 0, 0)) {
921                         lua_insert(L, -5);
922                         lua_pop(L, 4);
923                         return 1;
924                 }
925         }
926         
927         /* remove the extensions table and the extensions_order table */
928         lua_pop(L, 2);
929         return 0;
930 }
931
932 /*!
933  * \brief Register dialplan switches for our pbx_lua contexs.
934  *
935  * In the event of an error, an error string will be pushed onto the lua stack.
936  *
937  * \retval 0 success
938  * \retval 1 failure
939  */
940 static int lua_register_switches(lua_State *L)
941 {
942         int extensions;
943         struct ast_context *con = NULL;
944
945         /* create the hash table for our contexts */
946         /* XXX do we ever need to destroy this? pbx_config does not */
947         if (!local_table)
948                 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
949
950         /* load the 'extensions' table */
951         lua_getglobal(L, "extensions");
952         extensions = lua_gettop(L);
953         if (lua_isnil(L, -1)) {
954                 lua_pop(L, 1);
955                 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
956                 return 1;
957         }
958
959         /* iterate through the extensions table and register a context and
960          * dialplan switch for each lua context
961          */
962         for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
963                 int context = lua_gettop(L);
964                 int context_name = context - 1;
965                 const char *context_str = lua_tostring(L, context_name);
966
967                 /* find or create this context */
968                 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
969                 if (!con) {
970                         /* remove extensions table and context key and value */
971                         lua_pop(L, 3);
972                         lua_pushstring(L, "Failed to find or create context\n");
973                         return 1;
974                 }
975
976                 /* register the switch */
977                 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
978                         /* remove extensions table and context key and value */
979                         lua_pop(L, 3);
980                         lua_pushstring(L, "Unable to create switch for context\n");
981                         return 1;
982                 }
983         }
984         
985         /* remove the extensions table */
986         lua_pop(L, 1);
987         return 0;
988 }
989
990 /*!
991  * \brief Register dialplan hints for our pbx_lua contexs.
992  *
993  * In the event of an error, an error string will be pushed onto the lua stack.
994  *
995  * \retval 0 success
996  * \retval 1 failure
997  */
998 static int lua_register_hints(lua_State *L)
999 {
1000         int hints;
1001         struct ast_context *con = NULL;
1002
1003         /* create the hash table for our contexts */
1004         /* XXX do we ever need to destroy this? pbx_config does not */
1005         if (!local_table)
1006                 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
1007
1008         /* load the 'hints' table */
1009         lua_getglobal(L, "hints");
1010         hints = lua_gettop(L);
1011         if (lua_isnil(L, -1)) {
1012                 /* hints table not found, move along */
1013                 lua_pop(L, 1);
1014                 return 0;
1015         }
1016
1017         /* iterate through the hints table and register each context and
1018          * the hints that go along with it
1019          */
1020         for (lua_pushnil(L); lua_next(L, hints); lua_pop(L, 1)) {
1021                 int context = lua_gettop(L);
1022                 int context_name = context - 1;
1023                 const char *context_str = lua_tostring(L, context_name);
1024
1025                 /* find or create this context */
1026                 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
1027                 if (!con) {
1028                         /* remove hints table and context key and value */
1029                         lua_pop(L, 3);
1030                         lua_pushstring(L, "Failed to find or create context\n");
1031                         return 1;
1032                 }
1033
1034                 /* register each hint */
1035                 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
1036                         const char *hint_value = lua_tostring(L, -1);
1037                         const char *hint_name;
1038
1039                         /* the hint value is not a string, ignore it */
1040                         if (!hint_value) {
1041                                 continue;
1042                         }
1043
1044                         /* copy the name then convert it to a string */
1045                         lua_pushvalue(L, -2);
1046                         if (!(hint_name = lua_tostring(L, -1))) {
1047                                 /* ignore non-string value */
1048                                 lua_pop(L, 1);
1049                                 continue;
1050                         }
1051
1052                         if (ast_add_extension2(con, 0, hint_name, PRIORITY_HINT, NULL, NULL, hint_value, NULL, NULL, registrar)) {
1053                                 /* remove hints table, hint name, hint value,
1054                                  * key copy, context name, and contex table */
1055                                 lua_pop(L, 6);
1056                                 lua_pushstring(L, "Error creating hint\n");
1057                                 return 1;
1058                         }
1059
1060                         /* pop the name copy */
1061                         lua_pop(L, 1);
1062                 }
1063         }
1064
1065         /* remove the hints table */
1066         lua_pop(L, 1);
1067
1068         return 0;
1069 }
1070
1071 /*!
1072  * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
1073  * call directly)
1074  *
1075  * This function returns true if the first extension passed should match after
1076  * the second.  It behaves like the '<' operator.
1077  */
1078 static int lua_extension_cmp(lua_State *L)
1079 {
1080         const char *a = luaL_checkstring(L, -2);
1081         const char *b = luaL_checkstring(L, -1);
1082
1083         if (ast_extension_cmp(a, b) == -1)
1084                 lua_pushboolean(L, 1);
1085         else
1086                 lua_pushboolean(L, 0);
1087
1088         return 1;
1089 }
1090
1091 /*!
1092  * \brief Load the extensions.lua file in to a buffer and execute the file
1093  *
1094  * \param L the lua_State to use
1095  * \param size a pointer to store the size of the buffer
1096  *
1097  * \note The caller is expected to free the buffer at some point.
1098  *
1099  * \return a pointer to the buffer
1100  */
1101 static char *lua_read_extensions_file(lua_State *L, long *size)
1102 {
1103         FILE *f;
1104         int error_func;
1105         char *data;
1106         char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
1107         sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
1108
1109         if (!(f = fopen(path, "r"))) {
1110                 lua_pushstring(L, "cannot open '");
1111                 lua_pushstring(L, path);
1112                 lua_pushstring(L, "' for reading: ");
1113                 lua_pushstring(L, strerror(errno));
1114                 lua_concat(L, 4);
1115
1116                 return NULL;
1117         }
1118
1119         if (fseek(f, 0l, SEEK_END)) {
1120                 fclose(f);
1121                 lua_pushliteral(L, "error determining the size of the config file");
1122                 return NULL;
1123         }
1124
1125         *size = ftell(f);
1126
1127         if (fseek(f, 0l, SEEK_SET)) {
1128                 *size = 0;
1129                 fclose(f);
1130                 lua_pushliteral(L, "error reading config file");
1131                 return NULL;
1132         }
1133
1134         if (!(data = ast_malloc(*size))) {
1135                 *size = 0;
1136                 fclose(f);
1137                 lua_pushstring(L, "not enough memory");
1138                 return NULL;
1139         }
1140
1141         if (fread(data, sizeof(char), *size, f) != *size) {
1142                 *size = 0;
1143                 fclose(f);
1144                 lua_pushliteral(L, "problem reading configuration file");
1145                 return NULL;
1146         }
1147         fclose(f);
1148
1149         lua_pushcfunction(L, &lua_error_function);
1150         error_func = lua_gettop(L);
1151
1152         if (luaL_loadbuffer(L, data, *size, "extensions.lua")
1153                         || lua_pcall(L, 0, LUA_MULTRET, error_func)
1154                         || lua_sort_extensions(L)
1155                         || lua_register_switches(L)
1156                         || lua_register_hints(L)) {
1157                 ast_free(data);
1158                 data = NULL;
1159                 *size = 0;
1160         }
1161
1162         lua_remove(L, error_func);
1163         return data;
1164 }
1165
1166 /*!
1167  * \brief Load the extensions.lua file from the internal buffer
1168  *
1169  * \param L the lua_State to use
1170  * \param chan channel to work on
1171  *
1172  * This function also sets up some constructs used by the extensions.lua file.
1173  * In the event of an error, an error string will be pushed onto the lua stack.
1174  *
1175  * \retval 0 success
1176  * \retval 1 failure
1177  */
1178 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
1179 {
1180         
1181         /* store a pointer to this channel */
1182         lua_pushlightuserdata(L, chan);
1183         lua_setfield(L, LUA_REGISTRYINDEX, "channel");
1184         
1185         luaL_openlibs(L);
1186
1187         /* load and sort extensions */
1188         ast_mutex_lock(&config_file_lock);
1189         if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
1190                         || lua_pcall(L, 0, LUA_MULTRET, 0)
1191                         || lua_sort_extensions(L)) {
1192                 ast_mutex_unlock(&config_file_lock);
1193                 return 1;
1194         }
1195         ast_mutex_unlock(&config_file_lock);
1196
1197         /* now we setup special tables and functions */
1198
1199         lua_create_app_table(L);
1200         lua_create_channel_table(L);
1201
1202         lua_create_variable_metatable(L);
1203         lua_create_application_metatable(L);
1204
1205         lua_create_autoservice_functions(L);
1206         lua_create_hangup_function(L);
1207
1208         return 0;
1209 }
1210
1211 /*!
1212  * \brief Reload the extensions file and update the internal buffers if it
1213  * loads correctly.
1214  *
1215  * \warning This function should not be called on a lua_State returned from
1216  * lua_get_state().
1217  *
1218  * \param L the lua_State to use (must be freshly allocated with
1219  * luaL_newstate(), don't use lua_get_state())
1220  */
1221 static int lua_reload_extensions(lua_State *L)
1222 {
1223         long size = 0;
1224         char *data = NULL;
1225
1226         luaL_openlibs(L);
1227
1228         if (!(data = lua_read_extensions_file(L, &size))) {
1229                 return 1;
1230         }
1231
1232         ast_mutex_lock(&config_file_lock);
1233
1234         if (config_file_data)
1235                 ast_free(config_file_data);
1236
1237         config_file_data = data;
1238         config_file_size = size;
1239         
1240         /* merge our new contexts */
1241         ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
1242         /* merge_contexts_and_delete will actually, at the correct moment, 
1243            set the global dialplan pointers to your local_contexts and local_table.
1244            It then will free up the old tables itself. Just be sure not to
1245            hang onto the pointers. */
1246         local_table = NULL;
1247         local_contexts = NULL;
1248
1249         ast_mutex_unlock(&config_file_lock);
1250         return 0;
1251 }
1252
1253 /*!
1254  * \brief Free the internal extensions buffer.
1255  */
1256 static void lua_free_extensions()
1257 {
1258         ast_mutex_lock(&config_file_lock);
1259         config_file_size = 0;
1260         ast_free(config_file_data);
1261         ast_mutex_unlock(&config_file_lock);
1262 }
1263
1264 /*!
1265  * \brief Get the lua_State for this channel
1266  *
1267  * If no channel is passed then a new state is allocated.  States with no
1268  * channel assocatied with them should only be used for matching extensions.
1269  * If the channel does not yet have a lua state associated with it, one will be
1270  * created.
1271  *
1272  * \note If no channel was passed then the caller is expected to free the state
1273  * using lua_close().
1274  *
1275  * \return a lua_State
1276  */
1277 static lua_State *lua_get_state(struct ast_channel *chan)
1278 {
1279         struct ast_datastore *datastore = NULL;
1280         lua_State *L;
1281
1282         if (!chan) {
1283                 lua_State *L = luaL_newstate();
1284                 if (!L) {
1285                         ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1286                         return NULL;
1287                 }
1288
1289                 if (lua_load_extensions(L, NULL)) {
1290                         const char *error = lua_tostring(L, -1);
1291                         ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1292                         lua_close(L);
1293                         return NULL;
1294                 }
1295                 return L;
1296         } else {
1297                 ast_channel_lock(chan);
1298                 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
1299                 ast_channel_unlock(chan);
1300
1301                 if (!datastore) {
1302                         /* nothing found, allocate a new lua state */
1303                         datastore = ast_datastore_alloc(&lua_datastore, NULL);
1304                         if (!datastore) {
1305                                 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
1306                                 return NULL;
1307                         }
1308
1309                         datastore->data = luaL_newstate();
1310                         if (!datastore->data) {
1311                                 ast_datastore_free(datastore);
1312                                 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1313                                 return NULL;
1314                         }
1315
1316                         ast_channel_lock(chan);
1317                         ast_channel_datastore_add(chan, datastore);
1318                         ast_channel_unlock(chan);
1319
1320                         L = datastore->data;
1321
1322                         if (lua_load_extensions(L, chan)) {
1323                                 const char *error = lua_tostring(L, -1);
1324                                 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
1325
1326                                 ast_channel_lock(chan);
1327                                 ast_channel_datastore_remove(chan, datastore);
1328                                 ast_channel_unlock(chan);
1329
1330                                 ast_datastore_free(datastore);
1331                                 return NULL;
1332                         }
1333                 }
1334
1335                 return datastore->data;
1336         }
1337 }
1338
1339 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1340 {
1341         int res;
1342         lua_State *L;
1343         struct ast_module_user *u = ast_module_user_add(chan);
1344         if (!u) {
1345                 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1346                 return 0;
1347         }
1348
1349         L = lua_get_state(chan);
1350         if (!L) {
1351                 ast_module_user_remove(u);
1352                 return 0;
1353         }
1354
1355         res = lua_find_extension(L, context, exten, priority, &exists, 0);
1356
1357         if (!chan) lua_close(L);
1358         ast_module_user_remove(u);
1359         return res;
1360 }
1361
1362 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1363 {
1364         int res;
1365         lua_State *L;
1366         struct ast_module_user *u = ast_module_user_add(chan);
1367         if (!u) {
1368                 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1369                 return 0;
1370         }
1371
1372         L = lua_get_state(chan);
1373         if (!L) {
1374                 ast_module_user_remove(u);
1375                 return 0;
1376         }
1377
1378         res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1379
1380         if (!chan) lua_close(L);
1381         ast_module_user_remove(u);
1382         return res;
1383 }
1384
1385 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1386 {
1387         int res;
1388         lua_State *L;
1389         struct ast_module_user *u = ast_module_user_add(chan);
1390         if (!u) {
1391                 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1392                 return 0;
1393         }
1394
1395         L = lua_get_state(chan);
1396         if (!L) {
1397                 ast_module_user_remove(u);
1398                 return 0;
1399         }
1400         
1401         res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1402
1403         if (!chan) lua_close(L);
1404         ast_module_user_remove(u);
1405         return res;
1406 }
1407
1408
1409 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1410 {
1411         int res, error_func;
1412         lua_State *L;
1413         struct ast_module_user *u = ast_module_user_add(chan);
1414         if (!u) {
1415                 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1416                 return -1;
1417         }
1418         
1419         L = lua_get_state(chan);
1420         if (!L) {
1421                 ast_module_user_remove(u);
1422                 return -1;
1423         }
1424
1425         lua_pushcfunction(L, &lua_error_function);
1426         error_func = lua_gettop(L);
1427
1428         /* push the extension function onto the stack */
1429         if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1430                 lua_pop(L, 1); /* pop the debug function */
1431                 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1432                 if (!chan) lua_close(L);
1433                 ast_module_user_remove(u);
1434                 return -1;
1435         }
1436
1437         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1438         if (lua_toboolean(L, -1)) {
1439                 ast_autoservice_start(chan);
1440         }
1441         lua_pop(L, 1);
1442
1443         lua_update_registry(L, context, exten, priority);
1444         
1445         lua_pushstring(L, context);
1446         lua_pushstring(L, exten);
1447         
1448         res = lua_pcall(L, 2, 0, error_func);
1449         if (res) {
1450                 if (res == LUA_ERRRUN) {
1451                         res = -1;
1452                         if (lua_isnumber(L, -1)) {
1453                                 res = lua_tointeger(L, -1);
1454
1455                                 if (res == LUA_GOTO_DETECTED) {
1456                                         res = 0;
1457                                 }
1458                         } else if (lua_isstring(L, -1)) {
1459                                 const char *error = lua_tostring(L, -1);
1460                                 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1461                         }
1462                 } else if (res == LUA_ERRERR) {
1463                         res = -1;
1464                         ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
1465                 } else if (res == LUA_ERRMEM) {
1466                         res = -1;
1467                         ast_log(LOG_ERROR, "Memory allocation error\n");
1468                 }
1469                 lua_pop(L, 1);
1470         }
1471         lua_remove(L, error_func);
1472
1473         lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1474         if (lua_toboolean(L, -1)) {
1475                 ast_autoservice_stop(chan);
1476         }
1477         lua_pop(L, 1);
1478
1479         if (!chan) lua_close(L);
1480         ast_module_user_remove(u);
1481         return res;
1482 }
1483
1484 /*!
1485  * \brief Locate an extensions and optionally push the matching function on the
1486  * stack
1487  *
1488  * \param L the lua_State to use
1489  * \param context the context to look in
1490  * \param exten the extension to look up
1491  * \param priority the priority to check, '1' is the only valid priority
1492  * \param func the calling func, used to adjust matching behavior between,
1493  * match, canmatch, and matchmore
1494  * \param push_func whether or not to push the lua function for the given
1495  * extension onto the stack
1496  */
1497 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1498 {
1499         int context_table, context_order_table, i;
1500
1501         ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1502         if (priority != 1)
1503                 return 0;
1504
1505         /* load the 'extensions' table */
1506         lua_getglobal(L, "extensions");
1507         if (lua_isnil(L, -1)) {
1508                 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1509                 lua_pop(L, 1);
1510                 return 0;
1511         }
1512
1513         /* load the given context */
1514         lua_getfield(L, -1, context);
1515         if (lua_isnil(L, -1)) {
1516                 lua_pop(L, 2);
1517                 return 0;
1518         }
1519
1520         /* remove the extensions table */
1521         lua_remove(L, -2);
1522
1523         context_table = lua_gettop(L);
1524
1525         /* load the extensions order table for this context */
1526         lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1527         lua_getfield(L, -1, context);
1528
1529         lua_remove(L, -2);  /* remove the extensions order table */
1530
1531         context_order_table = lua_gettop(L);
1532         
1533         /* step through the extensions looking for a match */
1534         for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1535                 int e_index_copy, match = 0;
1536                 const char *e;
1537
1538                 lua_pushinteger(L, i);
1539                 lua_gettable(L, context_order_table);
1540                 lua_gettop(L);
1541
1542                 /* copy the key at the top of the stack for use later */
1543                 lua_pushvalue(L, -1);
1544                 e_index_copy = lua_gettop(L);
1545
1546                 if (!(e = lua_tostring(L, e_index_copy))) {
1547                         lua_pop(L, 2);
1548                         continue;
1549                 }
1550
1551                 /* make sure this is not the 'include' extension */
1552                 if (!strcasecmp(e, "include")) {
1553                         lua_pop(L, 2);
1554                         continue;
1555                 }
1556
1557                 if (func == &matchmore)
1558                         match = ast_extension_close(e, exten, E_MATCHMORE);
1559                 else if (func == &canmatch)
1560                         match = ast_extension_close(e, exten, E_CANMATCH);
1561                 else
1562                         match = ast_extension_match(e, exten);
1563
1564                 /* the extension matching functions return 0 on fail, 1 on
1565                  * match, 2 on earlymatch */
1566
1567                 if (!match) {
1568                         /* pop the copy and the extension */
1569                         lua_pop(L, 2);
1570                         continue;       /* keep trying */
1571                 }
1572
1573                 if (func == &matchmore && match == 2) {
1574                         /* We match an extension ending in '!'. The decision in
1575                          * this case is final and counts as no match. */
1576                         lua_pop(L, 4);
1577                         return 0;
1578                 }
1579
1580                 /* remove the context table, the context order table, the
1581                  * extension, and the extension copy (or replace the extension
1582                  * with the corresponding function) */
1583                 if (push_func) {
1584                         lua_pop(L, 1);  /* pop the copy */
1585                         lua_gettable(L, context_table);
1586                         lua_insert(L, -3);
1587                         lua_pop(L, 2);
1588                 } else {
1589                         lua_pop(L, 4);
1590                 }
1591
1592                 return 1;
1593         }
1594
1595         /* load the includes for this context */
1596         lua_getfield(L, context_table, "include");
1597         if (lua_isnil(L, -1)) {
1598                 lua_pop(L, 3);
1599                 return 0;
1600         }
1601
1602         /* remove the context and the order table*/
1603         lua_remove(L, context_order_table);
1604         lua_remove(L, context_table);
1605
1606         /* Now try any includes we have in this context */
1607         for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1608                 const char *c = lua_tostring(L, -1);
1609                 if (!c)
1610                         continue;
1611
1612                 if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1613                         /* remove the value, the key, and the includes table
1614                          * from the stack.  Leave the function behind if
1615                          * necessary */
1616
1617                         if (push_func)
1618                                 lua_insert(L, -4);
1619
1620                         lua_pop(L, 3);
1621                         return 1;
1622                 }
1623         }
1624
1625         /* pop the includes table */
1626         lua_pop(L, 1);
1627         return 0;
1628 }
1629
1630 static struct ast_switch lua_switch = {
1631         .name           = "Lua",
1632         .description    = "Lua PBX Switch",
1633         .exists         = exists,
1634         .canmatch       = canmatch,
1635         .exec           = exec,
1636         .matchmore      = matchmore,
1637 };
1638
1639
1640 static int load_or_reload_lua_stuff(void)
1641 {
1642         int res = AST_MODULE_LOAD_SUCCESS;
1643
1644         lua_State *L = luaL_newstate();
1645         if (!L) {
1646                 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1647                 return AST_MODULE_LOAD_DECLINE;
1648         }
1649
1650         if (lua_reload_extensions(L)) {
1651                 const char *error = lua_tostring(L, -1);
1652                 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1653                 res = AST_MODULE_LOAD_DECLINE;
1654         }
1655
1656         lua_close(L);
1657         return res;
1658 }
1659
1660 static int unload_module(void)
1661 {
1662         ast_context_destroy(NULL, registrar);
1663         ast_unregister_switch(&lua_switch);
1664         lua_free_extensions();
1665         return 0;
1666 }
1667
1668 static int reload(void)
1669 {
1670         return load_or_reload_lua_stuff();
1671 }
1672
1673 static int load_module(void)
1674 {
1675         int res;
1676
1677         if ((res = load_or_reload_lua_stuff()))
1678                 return res;
1679
1680         if (ast_register_switch(&lua_switch)) {
1681                 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1682                 return AST_MODULE_LOAD_DECLINE;
1683         }
1684
1685         return AST_MODULE_LOAD_SUCCESS;
1686 }
1687
1688 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Lua PBX Switch",
1689                 .load = load_module,
1690                 .unload = unload_module,
1691                 .reload = reload,
1692                );
1693