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