]> source.dussan.org Git - rspamd.git/commitdiff
* Reorganze lua support in rspamd
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 31 Aug 2009 11:34:09 +0000 (15:34 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 31 Aug 2009 11:34:09 +0000 (15:34 +0400)
13 files changed:
CMakeLists.txt
src/cfg_file.h
src/cfg_file.y
src/filter.c
src/lua-rspamd.h [deleted file]
src/lua.c [deleted file]
src/lua/CMakeLists.txt [new file with mode: 0644]
src/lua/lua_common.c [new file with mode: 0644]
src/lua/lua_common.h [new file with mode: 0644]
src/lua/lua_config.c [new file with mode: 0644]
src/lua/lua_message.c [new file with mode: 0644]
src/lua/lua_task.c [new file with mode: 0644]
src/main.c

index dbc49de28dbb7805af9d91c897a4a74e3d02f4b7..a753e2e4fb1de02ab94d4c1fdfed969bbcd89675 100644 (file)
@@ -19,7 +19,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
 OPTION(DEBUG_MODE          "Enable debug output [default: ON]"                  ON)
 OPTION(ENABLE_OPTIMIZATION "Enable optimization [default: OFF]"                 OFF)
 OPTION(ENABLE_PERL         "Enable perl support [default: OFF]"                 OFF)
-OPTION(ENABLE_LUA          "Enable lua support [default: OFF]"                  OFF)
+OPTION(ENABLE_LUA          "Enable lua support [default: ON]"                  ON)
 OPTION(SKIP_RELINK_RPATH   "Skip relinking and full RPATH for the install tree" OFF)
 OPTION(ENABLE_REDIRECTOR   "Enable redirector install [default: OFF]"           OFF)
 OPTION(ENABLE_PROFILING    "Enable profiling [default: OFF]"                    OFF)
@@ -77,7 +77,8 @@ IF(ENABLE_LUA MATCHES "ON")
                IF(LUA_INCLUDE_DIR)
                        INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
                ELSE(LUA_INCLUDE_DIR)
-                       MESSAGE(FATAL_ERROR "Error: Lua not found but its support is enabled")
+                       SET(ENABLE_LUA "OFF")
+                       MESSAGE(STATUS "Lua not found, lua support disabled")
                ENDIF(LUA_INCLUDE_DIR)
        ELSE(NOT LUA_FOUND)
                INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
@@ -361,7 +362,7 @@ IF(ENABLE_PERL MATCHES "ON")
        LIST(APPEND RSPAMDSRC src/perl.c)
 ENDIF(ENABLE_PERL MATCHES "ON")
 IF(ENABLE_LUA MATCHES "ON")
-       LIST(APPEND RSPAMDSRC src/lua.c)
+       ADD_SUBDIRECTORY(src/lua)
 ENDIF(ENABLE_LUA MATCHES "ON")
 
 SET(TOKENIZERSSRC  src/tokenizers/tokenizers.c
@@ -459,6 +460,11 @@ IF(ENABLE_PERL MATCHES "ON")
 
 ENDIF(ENABLE_PERL MATCHES "ON")
 
+IF(ENABLE_LUA MATCHES "ON")
+       TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}")
+       TARGET_LINK_LIBRARIES(rspamd rspamd_lua)
+ENDIF(ENABLE_LUA MATCHES "ON")
+
 TARGET_LINK_LIBRARIES(rspamd m)
 IF(LIBUTIL_LIBRARY)
        TARGET_LINK_LIBRARIES(rspamd util)
@@ -466,9 +472,6 @@ ENDIF(LIBUTIL_LIBRARY)
 TARGET_LINK_LIBRARIES(rspamd event)
 TARGET_LINK_LIBRARIES(rspamd ${GLIB2_LIBRARIES})
 TARGET_LINK_LIBRARIES(rspamd ${GMIME2_LIBRARIES})
-IF(ENABLE_LUA MATCHES "ON")
-       TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}")
-ENDIF(ENABLE_LUA MATCHES "ON")
 
 IF(ENABLE_GPERF_TOOLS MATCHES "ON")
        TARGET_LINK_LIBRARIES(rspamd profiler)
index 6529fea5105d42a6fe2fa813909f4e933dcb0766..7e3f035bca25d815dcf9d4d38454df3d76350565 100644 (file)
@@ -92,9 +92,9 @@ struct memcached_server {
 };
 
 /**
- * Perl module list item
+ * script module list item
  */
-struct perl_module {
+struct script_module {
        char *path;                                                                             /**< path to module                                                                             */
 };
 
@@ -140,7 +140,7 @@ struct statfile {
 };
 
 /**
- * Config option for importing to perl module
+ * Config option for importing to script module
  */
 struct config_scalar {
     void *pointer;                                                                     /**< pointer to data                                                                    */
@@ -210,7 +210,7 @@ struct config_file {
        char *deliver_agent_path;                                               /**< deliver to pipe instead of socket                                  */
        gboolean deliver_lmtp;                                                  /**< use LMTP instead of SMTP                                                   */
 
-       GList *perl_modules;                                                    /**< linked list of perl modules to load                                */
+       GList *script_modules;                                                  /**< linked list of script modules to load                              */
 
        GList *filters;                                                                 /**< linked list of all filters                                                 */
        GList *workers;                                                                 /**< linked list of all workers params                                  */
index 7a2aa3cb7e53a097fd4e17e4b66971dc18afdc3b..777a9367e05b692c3a8e3c885d2ae5c065de2f05 100644 (file)
@@ -10,7 +10,7 @@
 #include "tokenizers/tokenizers.h"
 #include "view.h"
 #ifdef WITH_LUA
-#include "lua-rspamd.h"
+#include "lua/lua_common.h"
 #else
 #include "perl.h"
 #endif
@@ -460,18 +460,18 @@ requirecmd:
        MODULE EQSIGN QUOTEDSTRING {
 #if !defined(WITHOUT_PERL) || defined(WITH_LUA)
                struct stat st;
-               struct perl_module *cur;
+               struct script_module *cur;
                if (stat ($3, &st) == -1) {
                        yyerror ("yyparse: cannot stat file %s, %s", $3, strerror (errno));
                        YYERROR;
                }
-               cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct perl_module));
+               cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct script_module));
                if (cur == NULL) {
                        yyerror ("yyparse: g_malloc: %s", strerror(errno));
                        YYERROR;
                }
                cur->path = $3;
-               cfg->perl_modules = g_list_prepend (cfg->perl_modules, cur);
+               cfg->script_modules = g_list_prepend (cfg->script_modules, cur);
 #else
                yyerror ("require command is not available when perl support is not compiled");
                YYERROR;
index b75dd145fe222f612ef99e281803d739fdb4bcd3..f35ed1dd690a71a3d0453a3de9a1623c2a8c908b 100644 (file)
@@ -41,7 +41,7 @@
 #include "perl.h"
 #endif
 #ifdef WITH_LUA
-#include "lua-rspamd.h"
+#include "lua/lua_common.h"
 #endif
 
 void
diff --git a/src/lua-rspamd.h b/src/lua-rspamd.h
deleted file mode 100644 (file)
index 2a56925..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef RSPAMD_LUA_H
-#define RSPAMD_LUA_H
-
-#include "config.h"
-
-struct uri;
-struct worker_task;
-struct config_file;
-
-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);
-void add_luabuf (const char *line);
-
-#endif
diff --git a/src/lua.c b/src/lua.c
deleted file mode 100644 (file)
index df03eaf..0000000
--- a/src/lua.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2009, Rambler media
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *      * Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
- *      * Redistributions in binary form must reproduce the above copyright
- *        notice, this list of conditions and the following disclaimer in the
- *        documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "url.h"
-#include "main.h"
-#include "message.h"
-#include "lua-rspamd.h"
-#include "cfg_file.h"
-
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-
-/* Lua module init function */
-#define MODULE_INIT_FUNC "module_init"
-
-/* Interface definitions */
-#define LUA_FUNCTION_DEF(class, name) static int lua_##class##_##name(lua_State *L)
-#define LUA_INTERFACE_DEF(class, name) { #name, lua_##class##_##name }
-
-#define LUA_GMIME_BRIDGE_GET(class, name, mime_class)                                                                  \
-static int                                                                                                                                                             \
-lua_##class##_##name(lua_State *L)                                                                                                             \
-{                                                                                                                                                                              \
-       GMime##mime_class *obj = lua_check_##class(L);                                                                          \
-       if (obj != NULL) {                                                                                                                                      \
-               lua_pushstring (L, g_mime_##class##_##name(obj));                                                               \
-       }                                                                                                                                                                       \
-       else {                                                                                                                                                          \
-               lua_pushnil (L);                                                                                                                                \
-       }                                                                                                                                                                       \
-       return 1;                                                                                                                                                       \
-}                                                                                                                                                      
-
-#define LUA_GMIME_BRIDGE_SET(class, name, mime_class)                                                                  \
-static int                                                                                                                                                             \
-lua_##class##_##name(lua_State *L)                                                                                                             \
-{                                                                                                                                                                              \
-       const char *str;                                                                                                                                        \
-       GMime##mime_class *obj = lua_check_##class(L);                                                                          \
-       if (obj != NULL) {                                                                                                                                      \
-               str = luaL_checkstring (L, 2);                                                                                                  \
-               g_mime_##class##_##name(obj, str);                                                                                              \
-       }                                                                                                                                                                       \
-       else {                                                                                                                                                          \
-               lua_pushnil (L);                                                                                                                                \
-       }                                                                                                                                                                       \
-       return 1;                                                                                                                                                       \
-}                                                                                                                                                      
-
-lua_State *L = NULL;
-
-/* Task methods */
-LUA_FUNCTION_DEF(task, get_message);
-LUA_FUNCTION_DEF(task, insert_result);
-LUA_FUNCTION_DEF(task, get_urls);
-
-static const struct luaL_reg tasklib_m[] = {
-       LUA_INTERFACE_DEF(task, get_message),
-       LUA_INTERFACE_DEF(task, insert_result),
-       LUA_INTERFACE_DEF(task, get_urls),
-       {NULL, NULL},
-};
-
-/*  Message methods */
-LUA_FUNCTION_DEF(message, get_subject);
-LUA_FUNCTION_DEF(message, set_subject);
-LUA_FUNCTION_DEF(message, get_message_id);
-LUA_FUNCTION_DEF(message, set_message_id);
-LUA_FUNCTION_DEF(message, get_sender);
-LUA_FUNCTION_DEF(message, set_sender);
-LUA_FUNCTION_DEF(message, get_reply_to);
-LUA_FUNCTION_DEF(message, set_reply_to);
-LUA_FUNCTION_DEF(message, get_header);
-LUA_FUNCTION_DEF(message, set_header);
-
-static const struct luaL_reg msglib_m[] = {
-       LUA_INTERFACE_DEF(message, get_subject),
-       LUA_INTERFACE_DEF(message, set_subject),
-       LUA_INTERFACE_DEF(message, get_message_id),
-       LUA_INTERFACE_DEF(message, set_message_id),
-       LUA_INTERFACE_DEF(message, get_sender),
-       LUA_INTERFACE_DEF(message, set_sender),
-       LUA_INTERFACE_DEF(message, get_reply_to),
-       LUA_INTERFACE_DEF(message, set_reply_to),
-       LUA_INTERFACE_DEF(message, get_header),
-       LUA_INTERFACE_DEF(message, set_header),
-       {NULL, NULL}
-};
-
-void 
-lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func) 
-{
-       luaL_newmetatable (L, classname); /* mt */
-       /* create __index table to place methods */
-       lua_pushstring (L, "__index");    /* mt,"__index" */
-       lua_newtable (L);                 /* mt,"__index",it */
-       /* put class name into class metatable */
-       lua_pushstring (L, "class");      /* mt,"__index",it,"class" */
-       lua_pushstring (L, classname);    /* mt,"__index",it,"class",classname */
-       lua_rawset (L, -3);               /* mt,"__index",it */
-       /* pass all methods that start with _ to the metatable, and all others
-        * to the index table */
-       for (; func->name; func++) {     /* mt,"__index",it */
-               lua_pushstring (L, func->name);
-               lua_pushcfunction (L, func->func);
-               lua_rawset (L, func->name[0] == '_' ? -5: -3);
-       }
-       lua_rawset (L, -3);               /* mt */
-       lua_pop (L, 1);
-}
-
-void lua_setclass (lua_State *L, const char *classname, int objidx) 
-{
-       luaL_getmetatable (L, classname);
-       if (objidx < 0) {
-               objidx--;
-       }
-       lua_setmetatable (L, objidx);
-}
-
-static struct worker_task *
-lua_check_task (lua_State *L) 
-{
-       void *ud = luaL_checkudata (L, 1, "Rspamd.task");
-       luaL_argcheck (L, ud != NULL, 1, "'task' expected");
-       return (struct worker_task *)ud;
-}
-
-static GMimeMessage *
-lua_check_message (lua_State *L)
-{
-       void *ud = luaL_checkudata (L, 1, "Rspamd.message");
-       luaL_argcheck (L, ud != NULL, 1, "'message' expected");
-       return (GMimeMessage *)ud;
-}
-/*** Task interface    ***/
-static int
-lua_task_get_message (lua_State *L)
-{
-       GMimeMessage **pmsg;
-       struct worker_task *task = lua_check_task (L);
-
-       if (task != NULL) {
-               /* XXX write handler for message object */
-               pmsg = lua_newuserdata (L, sizeof (GMimeMessage *));
-               lua_setclass (L, "Rspamd.message", -1);
-               *pmsg = task->message;
-       }
-       return 1;
-}
-
-static int 
-lua_task_insert_result (lua_State *L)
-{
-       struct worker_task *task = lua_check_task (L);
-       const char *metric_name, *symbol_name;
-       double flag;
-
-       if (task != NULL) {
-               metric_name = luaL_checkstring (L, 2);
-               symbol_name = luaL_checkstring (L, 3);
-               flag = luaL_checknumber (L, 4);
-               insert_result (task, metric_name, symbol_name, flag, NULL);
-       }
-       return 1;
-}
-
-static int 
-lua_task_get_urls (lua_State *L)
-{
-       struct worker_task *task = lua_check_task (L);
-       struct uri *url;
-
-       if (task != NULL) {
-               TAILQ_FOREACH (url, &task->urls, next) {        
-                       lua_pushstring (L, struri (url));       
-               }
-       }
-       return 1;
-}
-
-/*** Message interface ***/
-
-LUA_GMIME_BRIDGE_GET(message, get_subject, Message)
-LUA_GMIME_BRIDGE_SET(message, set_subject, Message)
-LUA_GMIME_BRIDGE_GET(message, get_message_id, Message)
-LUA_GMIME_BRIDGE_SET(message, set_message_id, Message)
-LUA_GMIME_BRIDGE_GET(message, get_sender, Message)
-LUA_GMIME_BRIDGE_SET(message, set_sender, Message)
-LUA_GMIME_BRIDGE_GET(message, get_reply_to, Message)
-LUA_GMIME_BRIDGE_SET(message, set_reply_to, Message)
-
-static int
-lua_message_get_header (lua_State *L)
-{
-       const char *headern;
-       GMimeMessage *obj = lua_check_message (L);
-       GList *res = NULL, *cur;
-
-       if (obj != NULL) {
-               headern = luaL_checkstring (L, 2);
-               if (headern) {
-                       res = message_get_header (NULL, obj, headern);
-                       if (res) {
-                               cur = res;
-                               while (cur) {
-                                       lua_pushstring (L, (const char *)cur->data);
-                                       g_free (cur->data);
-                                       cur = g_list_next (cur);
-                               }
-                               g_free (res);
-                       }
-                       else {
-                               lua_pushnil (L);
-                       }
-               }
-               else {
-                       lua_pushnil (L);
-               }
-       }
-       else {
-               lua_pushnil (L);
-       }
-
-       return 1;
-}
-
-static int
-lua_message_set_header (lua_State *L)
-{
-       const char *headern, *headerv;
-       GMimeMessage *obj = lua_check_message (L);
-
-       if (obj != NULL) {
-               headern = luaL_checkstring (L, 2);
-               headerv = luaL_checkstring (L, 3);
-               if (headern && headerv) {
-                       message_set_header (obj, headern, headerv);
-               }
-               else {
-                       lua_pushnil (L);
-               }
-       }
-       else {
-               lua_pushnil (L);
-       }
-       
-       return 1;
-}
-
-/*** Init functions ***/
-static int
-luaopen_task (lua_State *L)
-{
-       lua_newclass (L, "Rspamd.task", tasklib_m);
-    
-       luaL_openlib (L, "task", tasklib_m, 0);
-    
-       return 1;
-}
-
-static int
-luaopen_message (lua_State *L)
-{
-       lua_newclass (L, "Rspamd.message", msglib_m);
-    
-       luaL_openlib (L, "message", msglib_m, 0);
-    
-       return 1;
-}
-
-static void
-init_lua ()
-{
-       if (L == NULL) {
-               L = lua_open ();
-               luaL_openlibs (L);
-
-               luaopen_task (L);
-               luaopen_message (L);
-       }
-}
-
-void
-init_lua_filters (struct config_file *cfg)
-{
-       struct perl_module *module;
-       char *init_func;
-       size_t funclen;
-       struct config_file **pcfg;
-       
-       init_lua ();
-       LIST_FOREACH (module, &cfg->perl_modules, next) {
-               if (module->path) {
-                       luaL_loadfile (L, module->path);
-
-                       /* Call module init function */
-                       funclen = strlen (module->path) + sizeof (":") + sizeof (MODULE_INIT_FUNC) - 1;
-                       init_func = g_malloc (funclen);
-                       snprintf (init_func, funclen, "%s:%s", module->path, MODULE_INIT_FUNC);
-                       lua_getglobal (L, init_func);
-                       pcfg = lua_newuserdata (L, sizeof (struct config_file *));
-                       lua_setclass (L, "Rspamd.config", -1);
-                       *pcfg = cfg;
-                       /* do the call (1 arguments, 1 result) */
-                       if (lua_pcall (L, 1, 1, 0) != 0) {
-                               msg_info ("lua_init_filters: call to %s failed", init_func);
-                       }
-               }
-       }
-}
-
-
-int
-lua_call_filter (const char *function, struct worker_task *task)
-{
-       int result;
-       struct worker_task **ptask;
-
-       lua_getglobal (L, function);
-       ptask = lua_newuserdata (L, sizeof (struct worker_task *));
-       lua_setclass (L, "Rspamd.task", -1);
-       *ptask = task;
-       
-       if (lua_pcall (L, 1, 1, 0) != 0) {
-               msg_info ("lua_init_filters: call to %s failed", function);
-       }
-
-       /* retrieve result */
-       if (!lua_isnumber (L, -1)) {
-               msg_info ("lua_call_header_filter: function %s must return a number", function);
-       }
-       result = lua_tonumber (L, -1);
-       lua_pop (L, 1);  /* pop returned value */
-       return result;
-}
-
-int
-lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number)
-{
-       int result, i;
-
-       lua_getglobal (L, function);
-
-       for (i = 0; i < number; i ++) {
-               lua_pushnumber (L, marks[i]);
-       }
-       if (lua_pcall (L, number, 1, 0) != 0) {
-               msg_info ("lua_init_filters: call to %s failed", function);
-       }
-
-       /* retrieve result */
-       if (!lua_isnumber (L, -1)) {
-               msg_info ("lua_call_header_filter: function %s must return a number", function);
-       }
-       result = lua_tonumber (L, -1);
-       lua_pop (L, 1);  /* pop returned value */
-       return result;
-}
-
-/*
- * LUA custom consolidation function
- */
-struct consolidation_callback_data {
-       struct worker_task *task;
-       double score;
-       const char *func;
-};
-
-static void
-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_getglobal (L, data->func);
-
-       lua_pushstring (L, (const char *)key);
-       lua_pushnumber (L, s->score);
-       if (lua_pcall (L, 2, 1, 0) != 0) {
-               msg_info ("lua_consolidation_callback: call to %s failed", data->func);
-       }
-
-       /* retrieve result */
-       if (!lua_isnumber (L, -1)) {
-               msg_info ("lua_consolidation_callback: function %s must return a number", data->func);
-       }
-       res = lua_tonumber (L, -1);
-       lua_pop (L, 1);  /* pop returned value */
-       data->score += res;
-}
-
-double
-lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name)
-{
-       struct metric_result *metric_res;
-       double res = 0.;
-       struct consolidation_callback_data data = { task, 0, function_name };
-
-       if (function_name == NULL) {
-               return 0;
-       }
-
-       metric_res = g_hash_table_lookup (task->results, metric_name);
-       if (metric_res == NULL) {
-               return res;
-       }
-
-       g_hash_table_foreach (metric_res->symbols, lua_consolidation_callback, &data);
-
-       return data.score;
-}
-
-void
-add_luabuf (const char *line)
-{
-       int error;
-       init_lua ();
-
-       error = luaL_loadbuffer(L, line, strlen(line), "config")  ||
-                       lua_pcall(L, 0, 0, 0);
-       if (error) {
-               yyerror ("lua error: %s", lua_tostring(L, -1));
-               lua_pop(L, 1);  /* pop error message from the stack */
-       }
-}
diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5ae12c4
--- /dev/null
@@ -0,0 +1,8 @@
+# Lua support makefile
+SET(LUASRC                       lua_common.c
+                                         lua_task.c
+                                         lua_message.c
+                                         lua_config.c)
+
+ADD_LIBRARY(rspamd_lua STATIC ${LUASRC})
+TARGET_LINK_LIBRARIES(rspamd_lua ${LUALIB})
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
new file mode 100644 (file)
index 0000000..eb93dce
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2009, Rambler media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *      * Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ *      * Redistributions in binary form must reproduce the above copyright
+ *        notice, this list of conditions and the following disclaimer in the
+ *        documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "lua_common.h"
+
+/* Lua module init function */
+#define MODULE_INIT_FUNC "module_init"
+
+lua_State *L = NULL;
+
+/* Logger methods */
+LUA_FUNCTION_DEF(logger, err);
+LUA_FUNCTION_DEF(logger, warn);
+LUA_FUNCTION_DEF(logger, info);
+LUA_FUNCTION_DEF(logger, debug);
+
+static const struct luaL_reg loggerlib_m[] = {
+    LUA_INTERFACE_DEF(logger, err),
+    LUA_INTERFACE_DEF(logger, warn),
+    LUA_INTERFACE_DEF(logger, info),
+    LUA_INTERFACE_DEF(logger, debug),
+    {NULL, NULL}
+};
+
+
+void 
+lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func) 
+{
+       luaL_newmetatable (L, classname); /* mt */
+       /* create __index table to place methods */
+       lua_pushstring (L, "__index");    /* mt,"__index" */
+       lua_newtable (L);                 /* mt,"__index",it */
+       /* put class name into class metatable */
+       lua_pushstring (L, "class");      /* mt,"__index",it,"class" */
+       lua_pushstring (L, classname);    /* mt,"__index",it,"class",classname */
+       lua_rawset (L, -3);               /* mt,"__index",it */
+       /* pass all methods that start with _ to the metatable, and all others
+        * to the index table */
+       for (; func->name; func++) {     /* mt,"__index",it */
+               lua_pushstring (L, func->name);
+               lua_pushcfunction (L, func->func);
+               lua_rawset (L, func->name[0] == '_' ? -5: -3);
+       }
+       lua_rawset (L, -3);               /* mt */
+       lua_pop (L, 1);
+}
+
+void lua_setclass (lua_State *L, const char *classname, int objidx) 
+{
+       luaL_getmetatable (L, classname);
+       if (objidx < 0) {
+               objidx--;
+       }
+       lua_setmetatable (L, objidx);
+}
+
+
+
+/*** Logger interface ***/
+static int
+lua_logger_err (lua_State *L)
+{
+    const char *msg;
+    msg = luaL_checkstring (L, 2);
+    msg_err (msg);
+    return 1;
+}
+
+static int
+lua_logger_warn (lua_State *L)
+{
+    const char *msg;
+    msg = luaL_checkstring (L, 2);
+    msg_warn (msg);
+    return 1;
+}
+
+static int
+lua_logger_info (lua_State *L)
+{
+    const char *msg;
+    msg = luaL_checkstring (L, 2);
+    msg_info (msg);
+    return 1;
+}
+
+static int
+lua_logger_debug (lua_State *L)
+{
+    const char *msg;
+    msg = luaL_checkstring (L, 2);
+    msg_debug (msg);
+    return 1;
+}
+
+
+/*** Init functions ***/
+
+int
+luaopen_logger (lua_State *L)
+{
+    lua_newclass (L, "Rspamd.logger", loggerlib_m);
+       luaL_openlib (L, "logger", loggerlib_m, 0);
+
+    return 1;
+}
+
+static void
+init_lua ()
+{
+       if (L == NULL) {
+               L = lua_open ();
+               luaL_openlibs (L);
+
+               luaopen_task (L);
+               luaopen_message (L);
+        luaopen_logger (L);
+       }
+}
+
+void
+init_lua_filters (struct config_file *cfg)
+{
+       char *init_func;
+       size_t funclen;
+       struct config_file **pcfg;
+       GList *cur;
+       struct script_module *module;
+       
+       init_lua ();
+       cur = g_list_first (cfg->script_modules);
+       while (cur) {
+               module = cur->data;
+               if (module->path) {
+                       luaL_loadfile (L, module->path);
+
+                       /* Call module init function */
+                       funclen = strlen (module->path) + sizeof (":") + sizeof (MODULE_INIT_FUNC) - 1;
+                       init_func = g_malloc (funclen);
+                       snprintf (init_func, funclen, "%s:%s", module->path, MODULE_INIT_FUNC);
+            lua_getglobal (L, init_func);
+                       pcfg = lua_newuserdata (L, sizeof (struct config_file *));
+                       lua_setclass (L, "Rspamd.config", -1);
+                       *pcfg = cfg;
+                       /* do the call (1 arguments, 1 result) */
+                       if (lua_pcall (L, 1, 1, 0) != 0) {
+                               msg_info ("lua_init_filters: call to %s failed", init_func);
+                       }
+               }
+               cur = g_list_next (cur);
+       }
+}
+
+/* Callback functions */
+
+int
+lua_call_filter (const char *function, struct worker_task *task)
+{
+       int result;
+       struct worker_task **ptask;
+
+       lua_getglobal (L, function);
+       ptask = lua_newuserdata (L, sizeof (struct worker_task *));
+       lua_setclass (L, "Rspamd.task", -1);
+       *ptask = task;
+       
+       if (lua_pcall (L, 1, 1, 0) != 0) {
+               msg_info ("lua_call_filter: call to %s failed", function);
+       }
+
+       /* retrieve result */
+       if (!lua_isnumber (L, -1)) {
+               msg_info ("lua_call_filter: function %s must return a number", function);
+       }
+       result = lua_tonumber (L, -1);
+       lua_pop (L, 1);  /* pop returned value */
+       return result;
+}
+
+int
+lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number)
+{
+       int result, i;
+
+       lua_getglobal (L, function);
+
+       for (i = 0; i < number; i ++) {
+               lua_pushnumber (L, marks[i]);
+       }
+       if (lua_pcall (L, number, 1, 0) != 0) {
+               msg_info ("lua_init_filters: call to %s failed", function);
+       }
+
+       /* retrieve result */
+       if (!lua_isnumber (L, -1)) {
+               msg_info ("lua_call_header_filter: function %s must return a number", function);
+       }
+       result = lua_tonumber (L, -1);
+       lua_pop (L, 1);  /* pop returned value */
+       return result;
+}
+
+/*
+ * LUA custom consolidation function
+ */
+struct consolidation_callback_data {
+       struct worker_task *task;
+       double score;
+       const char *func;
+};
+
+static void
+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_getglobal (L, data->func);
+
+       lua_pushstring (L, (const char *)key);
+       lua_pushnumber (L, s->score);
+       if (lua_pcall (L, 2, 1, 0) != 0) {
+               msg_info ("lua_consolidation_callback: call to %s failed", data->func);
+       }
+
+       /* retrieve result */
+       if (!lua_isnumber (L, -1)) {
+               msg_info ("lua_consolidation_callback: function %s must return a number", data->func);
+       }
+       res = lua_tonumber (L, -1);
+       lua_pop (L, 1);  /* pop returned value */
+       data->score += res;
+}
+
+double
+lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name)
+{
+       struct metric_result *metric_res;
+       double res = 0.;
+       struct consolidation_callback_data data = { task, 0, function_name };
+
+       if (function_name == NULL) {
+               return 0;
+       }
+
+       metric_res = g_hash_table_lookup (task->results, metric_name);
+       if (metric_res == NULL) {
+               return res;
+       }
+
+       g_hash_table_foreach (metric_res->symbols, lua_consolidation_callback, &data);
+
+       return data.score;
+}
+
+void
+add_luabuf (const char *line)
+{
+       int error;
+       init_lua ();
+
+       error = luaL_loadbuffer(L, line, strlen(line), "config")  ||
+                       lua_pcall(L, 0, 0, 0);
+       if (error) {
+               yyerror ("lua error: %s", lua_tostring(L, -1));
+               lua_pop(L, 1);  /* pop error message from the stack */
+       }
+}
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h
new file mode 100644 (file)
index 0000000..b72171e
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef RSPAMD_LUA_H
+#define RSPAMD_LUA_H
+
+#include "../config.h"
+#include "../main.h"
+#include "../cfg_file.h"
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+/* Interface definitions */
+#define LUA_FUNCTION_DEF(class, name) static int lua_##class##_##name(lua_State *L)
+#define LUA_INTERFACE_DEF(class, name) { #name, lua_##class##_##name }
+
+void lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func);
+void lua_setclass (lua_State *L, const char *classname, int objidx);
+int luaopen_message (lua_State *L);
+int luaopen_task (lua_State *L);
+int luaopen_config (lua_State *L);
+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);
+void add_luabuf (const char *line);
+
+#endif
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
new file mode 100644 (file)
index 0000000..e88e53d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, Rambler media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "lua_common.h"
+
+/* Config file methods */
+LUA_FUNCTION_DEF(config, get_module_opt);
+LUA_FUNCTION_DEF(config, get_metric);
+LUA_FUNCTION_DEF(config, get_all_opt);
+
+static const struct luaL_reg configlib_m[] = {
+    LUA_INTERFACE_DEF(config, get_module_opt),
+    LUA_INTERFACE_DEF(config, get_metric),
+    LUA_INTERFACE_DEF(config, get_all_opt),
+    {NULL, NULL}
+};
+
+static struct config_file *
+lua_check_config (lua_State *L)
+{
+       void *ud = luaL_checkudata (L, 1, "Rspamd.config");
+       luaL_argcheck (L, ud != NULL, 1, "'config' expected");
+       return (struct config_file *)ud;
+}
+
+
+/*** Config functions ***/
+static int
+lua_config_get_module_opt (lua_State *L)
+{
+    struct config_file *cfg = lua_check_config (L);
+    const char *mname, *optname, *val;
+
+    if (cfg) {
+        mname = luaL_checkstring (L, 2);
+        optname = luaL_checkstring (L, 3);
+
+        if (mname && optname) {
+            val = get_module_opt (cfg, (char *)mname, (char *)optname);
+            if (val) {
+                lua_pushstring (L, val);
+                return 1;
+            }
+        }
+    }
+    lua_pushnil (L);
+    return 1;
+}
+
+static int
+lua_config_get_metric (lua_State *L)
+{
+    struct config_file *cfg = lua_check_config (L);
+    struct metric *metric, **pmetric;
+    const char *name;
+
+    if (cfg) {
+        name = luaL_checkstring (L, 2);
+        metric = g_hash_table_lookup (cfg->metrics, name);
+        if (metric) {
+            pmetric = lua_newuserdata (L, sizeof (struct metric *));
+                   lua_setclass (L, "Rspamd.metric", -1);
+                   *pmetric = metric;
+        }
+    }
+    lua_pushnil (L);
+    return 1;
+    
+}
+
+int
+luaopen_config (lua_State *L)
+{
+    lua_newclass (L, "Rspamd.config", configlib_m);
+       luaL_openlib (L, "config", configlib_m, 0);
+
+    return 1;
+}
+
diff --git a/src/lua/lua_message.c b/src/lua/lua_message.c
new file mode 100644 (file)
index 0000000..499945c
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2009, Rambler media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "lua_common.h"
+#include "../message.h"
+
+#define LUA_GMIME_BRIDGE_GET(class, name, mime_class)                                                                  \
+static int                                                                                                                                                             \
+lua_##class##_##name(lua_State *L)                                                                                                             \
+{                                                                                                                                                                              \
+       GMime##mime_class *obj = lua_check_##class(L);                                                                          \
+       if (obj != NULL) {                                                                                                                                      \
+               lua_pushstring (L, g_mime_##class##_##name(obj));                                                               \
+       }                                                                                                                                                                       \
+       else {                                                                                                                                                          \
+               lua_pushnil (L);                                                                                                                                \
+       }                                                                                                                                                                       \
+       return 1;                                                                                                                                                       \
+}                                                                                                                                                      
+
+#define LUA_GMIME_BRIDGE_SET(class, name, mime_class)                                                                  \
+static int                                                                                                                                                             \
+lua_##class##_##name(lua_State *L)                                                                                                             \
+{                                                                                                                                                                              \
+       const char *str;                                                                                                                                        \
+       GMime##mime_class *obj = lua_check_##class(L);                                                                          \
+       if (obj != NULL) {                                                                                                                                      \
+               str = luaL_checkstring (L, 2);                                                                                                  \
+               g_mime_##class##_##name(obj, str);                                                                                              \
+       }                                                                                                                                                                       \
+       else {                                                                                                                                                          \
+               lua_pushnil (L);                                                                                                                                \
+       }                                                                                                                                                                       \
+       return 1;                                                                                                                                                       \
+}                                                                                                                                                      
+
+/*  Message methods */
+LUA_FUNCTION_DEF(message, get_subject);
+LUA_FUNCTION_DEF(message, set_subject);
+LUA_FUNCTION_DEF(message, get_message_id);
+LUA_FUNCTION_DEF(message, set_message_id);
+LUA_FUNCTION_DEF(message, get_sender);
+LUA_FUNCTION_DEF(message, set_sender);
+LUA_FUNCTION_DEF(message, get_reply_to);
+LUA_FUNCTION_DEF(message, set_reply_to);
+LUA_FUNCTION_DEF(message, get_header);
+LUA_FUNCTION_DEF(message, set_header);
+
+static const struct luaL_reg msglib_m[] = {
+       LUA_INTERFACE_DEF(message, get_subject),
+       LUA_INTERFACE_DEF(message, set_subject),
+       LUA_INTERFACE_DEF(message, get_message_id),
+       LUA_INTERFACE_DEF(message, set_message_id),
+       LUA_INTERFACE_DEF(message, get_sender),
+       LUA_INTERFACE_DEF(message, set_sender),
+       LUA_INTERFACE_DEF(message, get_reply_to),
+       LUA_INTERFACE_DEF(message, set_reply_to),
+       LUA_INTERFACE_DEF(message, get_header),
+       LUA_INTERFACE_DEF(message, set_header),
+       {NULL, NULL}
+};
+
+
+
+static GMimeMessage *
+lua_check_message (lua_State *L)
+{
+       void *ud = luaL_checkudata (L, 1, "Rspamd.message");
+       luaL_argcheck (L, ud != NULL, 1, "'message' expected");
+       return (GMimeMessage *)ud;
+}
+
+
+/*** Message interface ***/
+
+LUA_GMIME_BRIDGE_GET(message, get_subject, Message)
+LUA_GMIME_BRIDGE_SET(message, set_subject, Message)
+LUA_GMIME_BRIDGE_GET(message, get_message_id, Message)
+LUA_GMIME_BRIDGE_SET(message, set_message_id, Message)
+LUA_GMIME_BRIDGE_GET(message, get_sender, Message)
+LUA_GMIME_BRIDGE_SET(message, set_sender, Message)
+LUA_GMIME_BRIDGE_GET(message, get_reply_to, Message)
+LUA_GMIME_BRIDGE_SET(message, set_reply_to, Message)
+
+static int
+lua_message_get_header (lua_State *L)
+{
+       const char *headern;
+       GMimeMessage *obj = lua_check_message (L);
+       GList *res = NULL, *cur;
+
+       if (obj != NULL) {
+               headern = luaL_checkstring (L, 2);
+               if (headern) {
+                       res = message_get_header (NULL, obj, headern);
+                       if (res) {
+                               cur = res;
+                               while (cur) {
+                                       lua_pushstring (L, (const char *)cur->data);
+                                       g_free (cur->data);
+                                       cur = g_list_next (cur);
+                               }
+                               g_free (res);
+                       }
+                       else {
+                               lua_pushnil (L);
+                       }
+               }
+               else {
+                       lua_pushnil (L);
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_message_set_header (lua_State *L)
+{
+       const char *headern, *headerv;
+       GMimeMessage *obj = lua_check_message (L);
+
+       if (obj != NULL) {
+               headern = luaL_checkstring (L, 2);
+               headerv = luaL_checkstring (L, 3);
+               if (headern && headerv) {
+                       message_set_header (obj, headern, headerv);
+               }
+               else {
+                       lua_pushnil (L);
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+       
+       return 1;
+}
+
+int
+luaopen_message (lua_State *L)
+{
+       lua_newclass (L, "Rspamd.message", msglib_m);
+       luaL_openlib (L, "message", msglib_m, 0);
+    
+       return 1;
+}
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
new file mode 100644 (file)
index 0000000..2e29912
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, Rambler media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "lua_common.h"
+
+/* Task methods */
+LUA_FUNCTION_DEF(task, get_message);
+LUA_FUNCTION_DEF(task, insert_result);
+LUA_FUNCTION_DEF(task, get_urls);
+
+static const struct luaL_reg tasklib_m[] = {
+       LUA_INTERFACE_DEF(task, get_message),
+       LUA_INTERFACE_DEF(task, insert_result),
+       LUA_INTERFACE_DEF(task, get_urls),
+       {NULL, NULL}
+};
+
+static struct worker_task *
+lua_check_task (lua_State *L) 
+{
+       void *ud = luaL_checkudata (L, 1, "Rspamd.task");
+       luaL_argcheck (L, ud != NULL, 1, "'task' expected");
+       return (struct worker_task *)ud;
+}
+
+/*** Task interface    ***/
+static int
+lua_task_get_message (lua_State *L)
+{
+       GMimeMessage **pmsg;
+       struct worker_task *task = lua_check_task (L);
+
+       if (task != NULL) {
+               /* XXX write handler for message object */
+               pmsg = lua_newuserdata (L, sizeof (GMimeMessage *));
+               lua_setclass (L, "Rspamd.message", -1);
+               *pmsg = task->message;
+       }
+       return 1;
+}
+
+static int 
+lua_task_insert_result (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+       const char *metric_name, *symbol_name;
+       double flag;
+
+       if (task != NULL) {
+               metric_name = luaL_checkstring (L, 2);
+               symbol_name = luaL_checkstring (L, 3);
+               flag = luaL_checknumber (L, 4);
+               insert_result (task, metric_name, symbol_name, flag, NULL);
+       }
+       return 1;
+}
+
+static int 
+lua_task_get_urls (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+       GList *cur;
+       struct uri *url;
+
+       if (task != NULL) {
+               cur = g_list_first (task->urls);
+               while (cur) {
+                       url = cur->data;
+                       lua_pushstring (L, struri (url));
+                       cur = g_list_next (cur);
+               }
+       }
+
+       return 1;
+}
+
+
+int
+luaopen_task (lua_State *L)
+{
+       lua_newclass (L, "Rspamd.task", tasklib_m);
+       luaL_openlib (L, "task", tasklib_m, 0);
+    
+       return 1;
+}
+
index b2de3bf981d87c960754090e5ba412df5ad751b9..c39553b202b6bf1c734e67cc0a7285f69cb7b50d 100644 (file)
@@ -41,7 +41,7 @@
 #include "perl.h"
 
 #elif defined(WITH_LUA)
-#include "lua-rspamd.h"
+#include "lua/lua_common.h"
 #endif
 
 /* 2 seconds to fork new process in place of dead one */