aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-30 12:33:53 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-30 12:33:53 +0100
commitdad973b08ce91f4d1219ac3c17692128d92ec579 (patch)
treeb5ac1ad50d6f3c289d216981857dfb310e2851ce /src/libserver
parent69c9402d15216fce58494083f4b8a16c44ede31f (diff)
downloadrspamd-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.h1
-rw-r--r--src/libserver/cfg_rcl.c65
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;
}