diff options
Diffstat (limited to 'src/libserver/cfg_utils.c')
-rw-r--r-- | src/libserver/cfg_utils.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 407f6d788..65e6ea9a7 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -924,3 +924,91 @@ rspamd_init_cfg (struct rspamd_config *cfg, gboolean init_lua) (rspamd_mempool_destruct_t)lua_close, cfg->lua_state); } } + +gboolean +rspamd_config_add_metric_symbol (struct rspamd_config *cfg, + const gchar *metric_name, const gchar *symbol, + gdouble score, const gchar *description, const gchar *group, + gboolean one_shot, gboolean rewrite_existing) +{ + struct rspamd_symbols_group *sym_group; + struct rspamd_symbol_def *sym_def; + GList *metric_list; + struct metric *metric; + gdouble *score_ptr; + + g_assert (cfg != NULL); + g_assert (symbol != NULL); + + if (metric_name == NULL) { + metric_name = DEFAULT_METRIC; + } + + metric = g_hash_table_lookup (cfg->metrics, metric_name); + + if (metric == NULL) { + msg_err ("metric %s has not been found", metric_name); + return FALSE; + } + + if (g_hash_table_lookup (cfg->metrics_symbols, symbol) != NULL && + !rewrite_existing) { + msg_debug ("symbol %s has been already registered, do not override"); + return FALSE; + } + + sym_def = + rspamd_mempool_alloc (cfg->cfg_pool, sizeof (struct rspamd_symbol_def)); + score_ptr = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (gdouble)); + + *score_ptr = score; + sym_def->weight_ptr = score_ptr; + sym_def->name = rspamd_mempool_strdup (cfg->cfg_pool, symbol); + sym_def->one_shot = one_shot; + + if (description) { + sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description); + } + + msg_debug ("registered symbol %s with weight %.2f in metric %s and group %s", + sym_def->name, score, metric->name, group); + + g_hash_table_insert (metric->symbols, sym_def->name, sym_def); + + if ((metric_list = + g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) { + metric_list = g_list_prepend (NULL, metric); + rspamd_mempool_add_destructor (cfg->cfg_pool, + (rspamd_mempool_destruct_t)g_list_free, + metric_list); + g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list); + } + else { + /* Slow but keep start element of list in safe */ + if (!g_list_find (metric_list, metric)) { + metric_list = g_list_append (metric_list, metric); + } + } + + /* Search for symbol group */ + if (group == NULL) { + group = "ungrouped"; + } + + sym_group = g_hash_table_lookup (cfg->symbols_groups, group); + if (sym_group == NULL) { + /* Create new group */ + sym_group = + rspamd_mempool_alloc0 (cfg->cfg_pool, + sizeof (struct rspamd_symbols_group)); + sym_group->name = rspamd_mempool_strdup (cfg->cfg_pool, group); + sym_group->symbols = NULL; + g_hash_table_insert (cfg->symbols_groups, sym_group->name, sym_group); + } + + sym_def->gr = sym_group; + + LL_PREPEND (sym_group->symbols, sym_def); + + return TRUE; +} |