diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-11-07 18:30:40 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-11-07 18:30:40 +0000 |
commit | 8082b0292b52e4cd5dfc229cb6b93b6e1a7d56f2 (patch) | |
tree | 54e31c5f607859a4e56513eb062fd765b2c305d9 | |
parent | 8dc300fc2cc5a0df82d59bf4f6b3e7b0e2e79bdf (diff) | |
download | rspamd-8082b0292b52e4cd5dfc229cb6b93b6e1a7d56f2.tar.gz rspamd-8082b0292b52e4cd5dfc229cb6b93b6e1a7d56f2.zip |
Parse classifiers and statfiles in ucl.
-rw-r--r-- | src/cfg_rcl.c | 135 | ||||
-rw-r--r-- | src/cfg_xml.c | 1 | ||||
-rw-r--r-- | src/classifiers/classifiers.c | 2 | ||||
-rw-r--r-- | src/classifiers/classifiers.h | 2 | ||||
-rw-r--r-- | src/tokenizers/tokenizers.c | 2 | ||||
-rw-r--r-- | src/tokenizers/tokenizers.h | 2 |
6 files changed, 139 insertions, 5 deletions
diff --git a/src/cfg_rcl.c b/src/cfg_rcl.c index 0a251e7e1..6cdad1b63 100644 --- a/src/cfg_rcl.c +++ b/src/cfg_rcl.c @@ -24,7 +24,10 @@ #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; } diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 147232b5e..47ab8aca3 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -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" diff --git a/src/classifiers/classifiers.c b/src/classifiers/classifiers.c index acd48dc9c..fb294379c 100644 --- a/src/classifiers/classifiers.c +++ b/src/classifiers/classifiers.c @@ -48,7 +48,7 @@ struct classifier classifiers[] = { }; struct classifier * -get_classifier (char *name) +get_classifier (const char *name) { guint i; diff --git a/src/classifiers/classifiers.h b/src/classifiers/classifiers.h index c70a71cc6..fa9b60ad6 100644 --- a/src/classifiers/classifiers.h +++ b/src/classifiers/classifiers.h @@ -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); diff --git a/src/tokenizers/tokenizers.c b/src/tokenizers/tokenizers.c index b8d9c933d..43dcfac82 100644 --- a/src/tokenizers/tokenizers.c +++ b/src/tokenizers/tokenizers.c @@ -77,7 +77,7 @@ const gchar t_delimiters[255] = { }; struct tokenizer * -get_tokenizer (char *name) +get_tokenizer (const char *name) { guint i; diff --git a/src/tokenizers/tokenizers.h b/src/tokenizers/tokenizers.h index 51893ca43..f2e8c9a4f 100644 --- a/src/tokenizers/tokenizers.h +++ b/src/tokenizers/tokenizers.h @@ -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 */ |