diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-04-08 19:24:36 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-04-08 19:24:36 +0400 |
commit | 01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a (patch) | |
tree | 1eb7dade443d154c4827ffa6a354228340201a34 /src | |
parent | da502b854015fe2053689249323e1228afd1460b (diff) | |
download | rspamd-01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a.tar.gz rspamd-01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a.zip |
* Call lua functions like C functions in expressions
Diffstat (limited to 'src')
-rw-r--r-- | src/expressions.c | 16 | ||||
-rw-r--r-- | src/lua/lua_common.c | 54 | ||||
-rw-r--r-- | src/lua/lua_common.h | 1 |
3 files changed, 70 insertions, 1 deletions
diff --git a/src/expressions.c b/src/expressions.c index 34e7b0e28..e52745541 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -30,6 +30,7 @@ #include "fuzzy.h" #include "expressions.h" #include "html.h" +#include "lua/lua_common.h" gboolean rspamd_compare_encoding (struct worker_task *task, GList * args, void *unused); gboolean rspamd_header_exists (struct worker_task *task, GList * args, void *unused); @@ -721,13 +722,26 @@ gboolean call_expression_function (struct expression_function * func, struct worker_task * task) { struct _fl *selected, key; +#ifdef RSPAMD_MAIN + gboolean res; +#endif key.name = func->name; selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp); if (selected == NULL) { - msg_warn ("call to undefined function %s", key.name); + /* Try to check lua function */ +#ifdef RSPAMD_MAIN + if (! lua_call_expression_func (func->name, task, func->args, &res)) { + msg_warn ("call to undefined function %s", key.name); + return FALSE; + } + else { + return res; + } +#else return FALSE; +#endif } return selected->func (task, func->args, selected->user_data); diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index c73b663bb..ac3d3074b 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -23,6 +23,7 @@ */ #include "lua_common.h" +#include "../expressions.h" /* Lua module init function */ #define MODULE_INIT_FUNC "module_init" @@ -262,6 +263,7 @@ lua_call_filter (const char *function, struct worker_task *task) { int result; struct worker_task **ptask; + lua_State *L = task->cfg->lua_state; lua_getglobal (L, function); ptask = lua_newuserdata (L, sizeof (struct worker_task *)); @@ -285,6 +287,7 @@ int lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number) { int result, i; + lua_State *L = task->cfg->lua_state; lua_getglobal (L, function); @@ -304,6 +307,56 @@ lua_call_chain_filter (const char *function, struct worker_task *task, int *mark return result; } +/* Call custom lua function in rspamd expression */ +gboolean +lua_call_expression_func (const char *function, struct worker_task *task, GList *args, gboolean *res) +{ + lua_State *L = task->cfg->lua_state; + struct worker_task **ptask; + GList *cur; + struct expression_argument *arg; + int nargs = 0; + + lua_getglobal (L, function); + ptask = lua_newuserdata (L, sizeof (struct worker_task *)); + lua_setclass (L, "rspamd{task}", -1); + *ptask = task; + + /* Now push all arguments */ + cur = args; + while (cur) { + arg = get_function_arg (cur->data, task, FALSE); + if (arg) { + switch (arg->type) { + case EXPRESSION_ARGUMENT_NORMAL: + lua_pushstring (L, (const gchar *)arg->data); + break; + case EXPRESSION_ARGUMENT_BOOL: + lua_pushboolean (L, (gboolean) GPOINTER_TO_SIZE (arg->data)); + break; + default: + msg_err ("cannot pass custom params to lua function"); + return FALSE; + } + } + nargs ++; + cur = g_list_next (cur); + } + + if (lua_pcall (L, nargs, 1, 0) != 0) { + msg_info ("call to %s failed", function); + return FALSE; + } + + if (!lua_isboolean (L, -1)) { + msg_info ("function %s must return a boolean", function); + return FALSE; + } + *res = lua_toboolean (L, -1); + + return TRUE; +} + /* * LUA custom consolidation function */ @@ -319,6 +372,7 @@ lua_consolidation_callback (gpointer key, gpointer value, gpointer arg) double res; struct symbol *s = (struct symbol *)value; struct consolidation_callback_data *data = (struct consolidation_callback_data *)arg; + lua_State *L = data->task->cfg->lua_state; lua_getglobal (L, data->func); diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index 4c8ff2585..dd4e75a8f 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -37,6 +37,7 @@ void init_lua_filters (struct config_file *cfg); int lua_call_filter (const char *function, struct worker_task *task); int lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number); double lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name); +gboolean lua_call_expression_func (const char *function, struct worker_task *task, GList *args, gboolean *res); void add_luabuf (const char *line); /* Classify functions */ |