From: Vsevolod Stakhov Date: Sat, 30 Apr 2016 11:33:53 +0000 (+0100) Subject: [Feature] Add learn conditions for classifiers X-Git-Tag: 1.3.0~587 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=dad973b08ce91f4d1219ac3c17692128d92ec579;p=rspamd.git [Feature] Add learn conditions for classifiers Issue: #613 --- 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; } diff --git a/src/libstat/stat_internal.h b/src/libstat/stat_internal.h index 802c4063a..8f06736bf 100644 --- a/src/libstat/stat_internal.h +++ b/src/libstat/stat_internal.h @@ -34,7 +34,7 @@ struct rspamd_statfile_runtime { /* Common classifier structure */ struct rspamd_classifier { struct rspamd_stat_ctx *ctx; - GArray *statfiles_ids; + GArray *statfiles_ids; /* int */ struct rspamd_stat_cache *cache; gpointer cachecf; gulong spam_learns;