]> source.dussan.org Git - rspamd.git/commitdiff
Parse classifiers and statfiles in ucl.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 7 Nov 2013 18:30:40 +0000 (18:30 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 7 Nov 2013 18:30:40 +0000 (18:30 +0000)
src/cfg_rcl.c
src/cfg_xml.c
src/classifiers/classifiers.c
src/classifiers/classifiers.h
src/tokenizers/tokenizers.c
src/tokenizers/tokenizers.h

index 0a251e7e1c1e8322910661617152c64109300820..6cdad1b63009fc99f864906651a464adc945aad0 100644 (file)
 #include "cfg_rcl.h"
 #include "main.h"
 #include "settings.h"
+#include "cfg_file.h"
 #include "lua/lua_common.h"
+#include "classifiers/classifiers.h"
+#include "tokenizers/tokenizers.h"
 
 /*
  * Common section handlers
@@ -675,6 +678,118 @@ rspamd_rcl_modules_handler (struct config_file *cfg, ucl_object_t *obj,
        return TRUE;
 }
 
+static gboolean
+rspamd_rcl_statfile_handler (struct config_file *cfg, ucl_object_t *obj,
+               gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+       struct classifier_config *ccf = ud;
+       ucl_object_t *val;
+       struct statfile *st;
+       const gchar *data;
+       gdouble binlog_rotate;
+       GList *labels;
+
+       st = check_statfile_conf (cfg, NULL);
+
+       val = ucl_object_find_key (obj, "binlog");
+       if (val != NULL && ucl_object_tostring_safe (val, &data)) {
+               if (st->binlog == NULL) {
+                       st->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params));
+               }
+               if (g_ascii_strcasecmp (data, "master") == 0) {
+                       st->binlog->affinity = AFFINITY_MASTER;
+               }
+               else if (g_ascii_strcasecmp (data, "slave") == 0) {
+                       st->binlog->affinity = AFFINITY_SLAVE;
+               }
+               else {
+                       st->binlog->affinity = AFFINITY_NONE;
+               }
+               /* Parse remaining binlog attributes */
+               val = ucl_object_find_key (obj, "binlog_rotate");
+               if (val != NULL && ucl_object_todouble_safe (val, &binlog_rotate)) {
+                       st->binlog->rotate_time = binlog_rotate;
+               }
+               val = ucl_object_find_key (obj, "binlog_master");
+               if (val != NULL && ucl_object_tostring_safe (val, &data)) {
+                       if (!parse_host_port (cfg->cfg_pool, data, &st->binlog->master_addr, &st->binlog->master_port)) {
+                               msg_err ("cannot parse master address: %s", data);
+                               return FALSE;
+                       }
+               }
+       }
+
+       if (rspamd_rcl_section_parse_defaults (section, cfg, obj, st, err)) {
+               ccf->statfiles = g_list_prepend (ccf->statfiles, st);
+               if (st->label != NULL) {
+                       labels = g_hash_table_lookup (ccf->labels, st->label);
+                       if (labels != NULL) {
+                               labels = g_list_append (labels, st);
+                       }
+                       else {
+                               g_hash_table_insert (ccf->labels, st->label, g_list_prepend (NULL, st));
+                       }
+               }
+               if (st->symbol != NULL) {
+                       g_hash_table_insert (cfg->classifiers_symbols, st->symbol, st);
+               }
+               else {
+                       g_set_error (err, CFG_RCL_ERROR, EINVAL, "statfile must have a symbol defined");
+                       return FALSE;
+               }
+
+               if (st->path == NULL) {
+                       g_set_error (err, CFG_RCL_ERROR, EINVAL, "statfile must have a path defined");
+                       return FALSE;
+               }
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static gboolean
+rspamd_rcl_classifier_handler (struct config_file *cfg, ucl_object_t *obj,
+               gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+       ucl_object_t *val, *cur;
+       ucl_object_iter_t it = NULL;
+       const gchar *key;
+       struct classifier_config *ccf;
+       gboolean res = TRUE;
+       struct rspamd_rcl_section *stat_section;
+
+       ccf = check_classifier_conf (cfg, NULL);
+       HASH_FIND_STR (section->subsections, "statfile", stat_section);
+
+       while ((val = ucl_iterate_object (obj, &it, true)) != NULL && res) {
+               key = ucl_object_key (val);
+               if (key != NULL) {
+                       if (g_ascii_strcasecmp (key, "statfile") == 0) {
+                               LL_FOREACH (val, cur) {
+                                       res = rspamd_rcl_statfile_handler (cfg, cur, ccf, stat_section, err);
+                               }
+                       }
+                       else if (g_ascii_strcasecmp (key, "type") == 0 && val->type == UCL_STRING) {
+                               ccf->classifier = get_classifier (ucl_object_tostring (val));
+                       }
+                       else if (g_ascii_strcasecmp (key, "tokenizer") == 0 && val->type == UCL_STRING) {
+                               ccf->tokenizer = get_tokenizer (ucl_object_tostring (val));
+                       }
+                       else {
+                               /* Just insert a value of option to the hash */
+                               g_hash_table_insert (ccf->opts, (gpointer)key, (gpointer)ucl_object_tostring_forced (val));
+                       }
+               }
+       }
+
+       cfg->classifiers = g_list_prepend (cfg->classifiers, ccf);
+
+
+       return res;
+}
+
 /**
  * Fake handler to parse default options only, uses struct cfg_file as pointer
  * for default handlers
@@ -741,7 +856,7 @@ rspamd_rcl_add_default_handler (struct rspamd_rcl_section *section, const gchar
 struct rspamd_rcl_section*
 rspamd_rcl_config_init (void)
 {
-       struct rspamd_rcl_section *new = NULL, *sub;
+       struct rspamd_rcl_section *new = NULL, *sub, *ssub;
 
        /* TODO: add all known rspamd sections here */
        /**
@@ -834,6 +949,24 @@ rspamd_rcl_config_init (void)
        sub = rspamd_rcl_add_section (&new, "modules", rspamd_rcl_modules_handler, UCL_OBJECT,
                        FALSE, TRUE);
 
+       /**
+        * Classifiers handler
+        */
+       sub = rspamd_rcl_add_section (&new, "classifier", rspamd_rcl_classifier_handler, UCL_OBJECT,
+                       FALSE, TRUE);
+       ssub = rspamd_rcl_add_section (&sub->subsections, "statfile", rspamd_rcl_statfile_handler,
+                       UCL_OBJECT, TRUE, TRUE);
+       rspamd_rcl_add_default_handler (ssub, "symbol", rspamd_rcl_parse_struct_string,
+                       G_STRUCT_OFFSET (struct statfile, symbol), 0);
+       rspamd_rcl_add_default_handler (ssub, "path", rspamd_rcl_parse_struct_string,
+                       G_STRUCT_OFFSET (struct statfile, path), 0);
+       rspamd_rcl_add_default_handler (ssub, "label", rspamd_rcl_parse_struct_string,
+                               G_STRUCT_OFFSET (struct statfile, label), 0);
+       rspamd_rcl_add_default_handler (ssub, "size", rspamd_rcl_parse_struct_integer,
+                       G_STRUCT_OFFSET (struct statfile, size), RSPAMD_CL_FLAG_INT_SIZE);
+       rspamd_rcl_add_default_handler (ssub, "spam", rspamd_rcl_parse_struct_boolean,
+                       G_STRUCT_OFFSET (struct statfile, is_spam), 0);
+
        return new;
 }
 
index 147232b5ede6a100e2be8cbab332a30d3897b5d4..47ab8aca3a1ded054ea7e359166fef8ba0495ff2 100644 (file)
@@ -33,6 +33,7 @@
 #include "util.h"
 #include "classifiers/classifiers.h"
 #include "tokenizers/tokenizers.h"
+#include "cfg_file.h"
 
 #include "view.h"
 #include "map.h"
index acd48dc9c3f1cd8e9a9fa83763a0aff89fe5e1b6..fb294379c65ee39b8e36e77d523d38c1764ba623 100644 (file)
@@ -48,7 +48,7 @@ struct classifier               classifiers[] = {
 };
 
 struct classifier              *
-get_classifier (char *name)
+get_classifier (const char *name)
 {
        guint                             i;
 
index c70a71cc67447312cb1194e6881d6b976a8b17af..fa9b60ad6f8c51ad78ba4d236ffe75ace14781ac 100644 (file)
@@ -39,7 +39,7 @@ struct classifier {
 };
 
 /* Get classifier structure by name or return NULL if this name is not found */
-struct classifier* get_classifier (char *name);
+struct classifier* get_classifier (const char *name);
 
 /* Winnow algorithm */
 struct classifier_ctx* winnow_init (memory_pool_t *pool, struct classifier_config *cf);
index b8d9c933dc9a6593e478afb29bd9dcd4e9d42f45..43dcfac82abbd5077609e64489e31f96e83d9acd 100644 (file)
@@ -77,7 +77,7 @@ const gchar t_delimiters[255] = {
 };
 
 struct tokenizer               *
-get_tokenizer (char *name)
+get_tokenizer (const char *name)
 {
        guint                            i;
 
index 51893ca4310df654b90e20ccd9cd21c81640db35..f2e8c9a4fd0d6f20ac76bfa8ec0bb745680d45f3 100644 (file)
@@ -27,7 +27,7 @@ struct tokenizer {
 /* Compare two token nodes */
 int token_node_compare_func (gconstpointer a, gconstpointer b);
 /* Get tokenizer structure by name or return NULL if this name is not found */
-struct tokenizer* get_tokenizer (char *name);
+struct tokenizer* get_tokenizer (const char *name);
 /* Get next word from specified f_str_t buf */
 gchar* get_next_word (f_str_t *buf, f_str_t *token, GList **exceptions);
 /* OSB tokenize function */