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