summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-04-08 19:24:36 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-04-08 19:24:36 +0400
commit01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a (patch)
tree1eb7dade443d154c4827ffa6a354228340201a34 /src
parentda502b854015fe2053689249323e1228afd1460b (diff)
downloadrspamd-01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a.tar.gz
rspamd-01e37900750a8bf7aaf7c52057ea73c4d7c6aa2a.zip
* Call lua functions like C functions in expressions
Diffstat (limited to 'src')
-rw-r--r--src/expressions.c16
-rw-r--r--src/lua/lua_common.c54
-rw-r--r--src/lua/lua_common.h1
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 */