diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-04-30 12:33:53 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-04-30 12:33:53 +0100 |
commit | dad973b08ce91f4d1219ac3c17692128d92ec579 (patch) | |
tree | b5ac1ad50d6f3c289d216981857dfb310e2851ce /src/libserver | |
parent | 69c9402d15216fce58494083f4b8a16c44ede31f (diff) | |
download | rspamd-dad973b08ce91f4d1219ac3c17692128d92ec579.tar.gz rspamd-dad973b08ce91f4d1219ac3c17692128d92ec579.zip |
[Feature] Add learn conditions for classifiers
Issue: #613
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/cfg_file.h | 1 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.c | 65 |
2 files changed, 65 insertions, 1 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 01183af35..cd6d25683 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -150,6 +150,7 @@ struct rspamd_classifier_config { ucl_object_t *opts; /**< other options */ GList *pre_callbacks; /**< list of callbacks that are called before classification */ GList *post_callbacks; /**< list of callbacks that are called after classification */ + GList *learn_conditions; /**< list of learn condition callbacks */ gchar *name; /**< unique name of classifier */ guint32 min_tokens; /**< minimal number of tokens to process classifier */ guint32 max_tokens; /**< maximum number of tokens */ diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index b35aeacc3..8be75ea22 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -1235,6 +1235,7 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool, gboolean res = TRUE; struct rspamd_rcl_section *stat_section; struct rspamd_tokenizer_config *tkcf = NULL; + lua_State *L; g_assert (key != NULL); ccf = rspamd_config_new_classifier (cfg, NULL); @@ -1304,10 +1305,72 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool, } ccf->tokenizer = tkcf; + + /* Handle lua conditions */ + val = ucl_object_lookup (obj, "condition"); + + if (val) { + LL_FOREACH (val, cur) { + if (ucl_object_type (cur) == UCL_STRING) { + const gchar *lua_script; + gsize slen; + gint err_idx, ref_idx; + GString *tb = NULL; + + lua_script = ucl_object_tolstring (cur, &slen); + L = cfg->lua_state; + lua_pushcfunction (L, &rspamd_lua_traceback); + err_idx = lua_gettop (L); + + + /* Load file */ + if (luaL_loadbuffer (L, lua_script, slen, "learn_condition") != 0) { + g_set_error (err, + CFG_RCL_ERROR, + EINVAL, + "cannot load lua condition script: %s", + lua_tostring (L, -1)); + lua_settop (L, 0); /* Error function */ + + return FALSE; + } + + /* Now do it */ + if (lua_pcall (L, 0, 1, err_idx) != 0) { + tb = lua_touserdata (L, -1); + g_set_error (err, + CFG_RCL_ERROR, + EINVAL, + "cannot init lua condition script: %s", + tb->str); + g_string_free (tb, TRUE); + lua_settop (L, 0); + + return FALSE; + } + + if (!lua_isfunction (L, -1)) { + g_set_error (err, + CFG_RCL_ERROR, + EINVAL, + "cannot init lua condition script: " + "must return function"); + lua_settop (L, 0); + + return FALSE; + } + + ref_idx = luaL_ref (L, LUA_REGISTRYINDEX); + ccf->learn_conditions = g_list_append (ccf->learn_conditions, + GINT_TO_POINTER (ref_idx)); + lua_settop (L, 0); + } + } + } + ccf->opts = (ucl_object_t *)obj; cfg->classifiers = g_list_prepend (cfg->classifiers, ccf); - return res; } |