Module: sip-router Branch: master Commit: 475a65cbf5b7d2acefd02359f67844fd24870f38 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=475a65cb...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Tue Apr 20 12:12:54 2010 +0200
app_lua: added sr.modf(func, param1, param2, ...)
- new function in Lua sr package to execute functions exported by modules - disabled for functions without free fixup, to avoid memleaks
---
modules/app_lua/app_lua_api.c | 1 + modules/app_lua/app_lua_sr.c | 150 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 3 deletions(-)
diff --git a/modules/app_lua/app_lua_api.c b/modules/app_lua/app_lua_api.c index 5e35436..1673f5e 100644 --- a/modules/app_lua/app_lua_api.c +++ b/modules/app_lua/app_lua_api.c @@ -423,6 +423,7 @@ void app_lua_dump_stack(lua_State *L)
top = lua_gettop(L);
+ LM_DBG("lua stack top index: %d\n", top); for (i = 1; i <= top; i++) { t = lua_type(L, i); diff --git a/modules/app_lua/app_lua_sr.c b/modules/app_lua/app_lua_sr.c index 0cf935d..0900bd4 100644 --- a/modules/app_lua/app_lua_sr.c +++ b/modules/app_lua/app_lua_sr.c @@ -28,6 +28,8 @@
#include "../../sr_module.h" #include "../../dprint.h" +#include "../../route_struct.h" +#include "../../action.h" #include "../../ut.h" #include "../../mem/mem.h" #include "../../data_lump.h" @@ -100,11 +102,153 @@ static int lua_sr_log (lua_State *L) /** * */ +static int lua_sr_modf (lua_State *L) +{ + int ret; + char *luav[MAX_ACTIONS]; + char *argv[MAX_ACTIONS]; + int argc; + int i; + struct run_act_ctx ra_ctx; + unsigned modver; + struct action *act; + union cmd_export_u* expf; + sr_lua_env_t *env_L; + + ret = 1; + act = NULL; + argc = 0; + memset(luav, 0, MAX_ACTIONS*sizeof(char*)); + memset(argv, 0, MAX_ACTIONS*sizeof(char*)); + env_L = sr_lua_env_get(); + if(env_L->msg==NULL) + goto error; + +#if 0 + app_lua_dump_stack(L); +#endif + argc = lua_gettop(L); + if(argc==0) + { + LM_ERR("name of module function not provided\n"); + goto error; + } + if(argc>=MAX_ACTIONS) + { + LM_ERR("too many parameters\n"); + goto error; + } + /* first is function name, then parameters */ + for(i=1; i<=argc; i++) + { + if (!lua_isstring(L, i)) + { + LM_ERR("invalid parameter type (%d)\n", i); + goto error; + } + luav[i-1] = (char*)lua_tostring(L, i); + } + /* pkg copy only parameters */ + for(i=1; i<MAX_ACTIONS; i++) + { + if(luav[i]!=NULL) + { + argv[i] = (char*)pkg_malloc(strlen(luav[i])+1); + if(argv[i]==NULL) + { + LM_ERR("no more pkg\n"); + goto error; + } + strcpy(argv[i], luav[i]); + } + } + + expf = find_export_record(luav[0], argc-1, 0, &modver); + if (expf==NULL) { + LM_ERR("function '%s' is not available\n", luav[0]); + goto error; + } + /* check fixups */ + if (expf->v1.fixup!=NULL && (modver!=1 || expf->v1.free_fixup==NULL)) { + LM_ERR("function '%s' has fixup - cannot be used\n", luav[0]); + goto error; + } + + act = mk_action(MODULE_T, argc+1 /* number of (type, value) pairs */, + MODEXP_ST, expf, /* function */ + NUMBER_ST, argc-1, /* parameter number */ + STRING_ST, argv[1], /* param. 1 */ + STRING_ST, argv[2], /* param. 2 */ + STRING_ST, argv[3], /* param. 3 */ + STRING_ST, argv[4], /* param. 4 */ + STRING_ST, argv[5], /* param. 5 */ + STRING_ST, argv[6] /* param. 6 */ + ); + + if (act==NULL) { + LM_ERR("action structure could not be created for '%s'\n", luav[0]); + goto error; + } + + /* handle fixups */ + if (expf->v1.fixup) { + if(argc==1) + { /* no parameters */ + if(expf->v1.fixup(0, 0)<0) + { + LM_ERR("Error in fixup (0) for '%s'\n", luav[0]); + goto error; + } + } else { + for(i=1; i<=argc; i++) + { + if(expf->v1.fixup(&(act->val[i+1].u.data), i)<0) + { + LM_ERR("Error in fixup (%d) for '%s'\n", i, luav[0]); + goto error; + } + act->val[i+1].type = MODFIXUP_ST; + } + } + } + init_run_actions_ctx(&ra_ctx); + ret = do_action(&ra_ctx, act, env_L->msg); + + /* free fixups */ + if (expf->v1.fixup) { + for(i=1; i<=argc; i++) + { + if ((act->val[i+1].type == MODFIXUP_ST) && (act->val[i+1].u.data)) + { + expf->v1.free_fixup(&(act->val[i+1].u.data), i); + } + } + } + pkg_free(act); + lua_pushinteger(L, ret); + return 1; + +error: + if(act!=NULL) + pkg_free(act); + for(i=0; i<MAX_ACTIONS; i++) + { + if(argv[i]!=NULL) pkg_free(argv[i]); + argv[i] = 0; + } + lua_pushinteger(L, -1); + return 1; +} + +/** + * + */ static const luaL_reg _sr_core_Map [] = { {"probe", lua_sr_probe}, - {"dbg", lua_sr_dbg}, - {"err", lua_sr_err}, - {"log", lua_sr_log}, + {"dbg", lua_sr_dbg}, + {"err", lua_sr_err}, + {"log", lua_sr_log}, + {"modf", lua_sr_modf}, {NULL, NULL} };