]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add learn conditions for classifiers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 30 Apr 2016 11:33:53 +0000 (12:33 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 30 Apr 2016 11:33:53 +0000 (12:33 +0100)
Issue: #613

src/libserver/cfg_file.h
src/libserver/cfg_rcl.c
src/libstat/stat_internal.h

index 01183af352452b5d837b6e5b1aa38156a5ef5818..cd6d25683401e72b88358dcbd137fa053b0cd881 100644 (file)
@@ -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                                                   */
index b35aeacc30b38ddd9e1055c65fff0930cc463257..8be75ea2250eed380deb6d7398a00e954bfff3bc 100644 (file)
@@ -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;
 }
 
index 802c4063a5a1515ba9cdf42a922e5d16a0c47c55..8f06736bf2edf12faf042cce9c643aaec56bd212 100644 (file)
@@ -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;