Module: sip-router
Branch: master
Commit: 475a65cbf5b7d2acefd02359f67844fd24870f38
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=475a65c…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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}
};