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