Kaynağa Gözat

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
Daniel-Constantin Mierla 15 yıl önce
ebeveyn
işleme
475a65cbf5
2 değiştirilmiş dosya ile 148 ekleme ve 3 silme
  1. 1 0
      modules/app_lua/app_lua_api.c
  2. 147 3
      modules/app_lua/app_lua_sr.c

+ 1 - 0
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);

+ 147 - 3
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"
@@ -97,14 +99,156 @@ static int lua_sr_log (lua_State *L)
 	return 0;
 }
 
+/**
+ *
+ */
+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}
 };