]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Add configuration for lua classifiers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 6 Oct 2016 17:30:08 +0000 (18:30 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 6 Oct 2016 17:30:08 +0000 (18:30 +0100)
src/libstat/classifiers/lua_classifier.c

index dea0f6a24617a89acfeff9695a3279cbcbad4d24..c1aee7261528368485e3cffa4e5412d4cfab2996 100644 (file)
 #include "classifiers.h"
 #include "cfg_file.h"
 #include "stat_internal.h"
+#include "lua/lua_common.h"
+
+struct rspamd_lua_classifier_ctx {
+       gchar *name;
+       gint classify_ref;
+       gint learn_ref;
+};
+
+static GHashTable *lua_classifiers = NULL;
+
+#define msg_err_luacl(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \
+        "luacl", task->task_pool->tag.uid, \
+        G_STRFUNC, \
+        __VA_ARGS__)
+#define msg_warn_luacl(...)   rspamd_default_log_function (G_LOG_LEVEL_WARNING, \
+        "luacl", task->task_pool->tag.uid, \
+        G_STRFUNC, \
+        __VA_ARGS__)
+#define msg_info_luacl(...)   rspamd_default_log_function (G_LOG_LEVEL_INFO, \
+        "luacl", task->task_pool->tag.uid, \
+        G_STRFUNC, \
+        __VA_ARGS__)
+#define msg_debug_luacl(...)  rspamd_default_log_function (G_LOG_LEVEL_DEBUG, \
+        "luacl", task->task_pool->tag.uid, \
+        G_STRFUNC, \
+        __VA_ARGS__)
 
 gboolean
 lua_classifier_init (rspamd_mempool_t *pool,
                struct rspamd_classifier *cl)
 {
+       struct rspamd_lua_classifier_ctx *ctx;
+       lua_State *L = cl->ctx->cfg->lua_state;
+       gint cb_classify = -1, cb_learn = -1;
+
+       if (lua_classifiers == NULL) {
+               lua_classifiers = g_hash_table_new_full (rspamd_strcase_hash,
+                               rspamd_strcase_equal, g_free, g_free);
+       }
+
+       ctx = g_hash_table_lookup (lua_classifiers, cl->subrs->name);
+
+       if (ctx != NULL) {
+               msg_err_pool ("duplicate lua classifier definition: %s",
+                               cl->subrs->name);
+
+               return FALSE;
+       }
+
+       lua_getglobal (L, "rspamd_classifiers");
+       if (lua_type (L, -1) != LUA_TTABLE) {
+               msg_err_pool ("cannot register classifier %s: no rspamd_classifier global",
+                               cl->subrs->name);
+               lua_pop (L, 1);
+
+               return FALSE;
+       }
+
+       lua_pushstring (L, cl->subrs->name);
+       lua_gettable (L, -2);
+
+       if (lua_type (L, -1) != LUA_TTABLE) {
+               msg_err_pool ("cannot register classifier %s: bad lua type: %s",
+                               cl->subrs->name, lua_typename (L, lua_type (L, -1)));
+               lua_pop (L, 2);
+
+               return FALSE;
+       }
+
+       lua_pushstring (L, "classify");
+       lua_gettable (L, -2);
+
+       if (lua_type (L, -1) != LUA_TFUNCTION) {
+               msg_err_pool ("cannot register classifier %s: bad lua type for classify: %s",
+                               cl->subrs->name, lua_typename (L, lua_type (L, -1)));
+               lua_pop (L, 3);
+
+               return FALSE;
+       }
+
+       cb_classify = luaL_ref (L, LUA_REGISTRYINDEX);
+
+       lua_pushstring (L, "learn");
+       lua_gettable (L, -2);
+
+       if (lua_type (L, -1) != LUA_TFUNCTION) {
+               msg_err_pool ("cannot register classifier %s: bad lua type for learn: %s",
+                               cl->subrs->name, lua_typename (L, lua_type (L, -1)));
+               lua_pop (L, 3);
+
+               return FALSE;
+       }
+
+       cb_learn = luaL_ref (L, LUA_REGISTRYINDEX);
+       lua_pop (L, 2); /* Table + global */
+
+       ctx = g_malloc0 (sizeof (*ctx));
+       ctx->name = g_strdup (cl->subrs->name);
+       ctx->classify_ref = cb_classify;
+       ctx->learn_ref = cb_learn;
        cl->cfg->flags |= RSPAMD_FLAG_CLASSIFIER_NO_BACKEND;
+       g_hash_table_insert (lua_classifiers, ctx->name, ctx);
 
        return TRUE;
 }