@@ -28,6 +28,7 @@ | |||
#include "libutil/map.h" | |||
#include "libstat/stat_api.h" | |||
#include "main.h" | |||
#include "utlist.h" | |||
#ifdef WITH_GPERF_TOOLS | |||
# include <glib/gprintf.h> | |||
@@ -292,10 +293,11 @@ rspamd_controller_handle_symbols (struct rspamd_http_connection_entry *conn_ent, | |||
struct rspamd_http_message *msg) | |||
{ | |||
struct rspamd_controller_session *session = conn_ent->ud; | |||
GList *cur_gr, *cur_sym; | |||
GHashTableIter it; | |||
struct rspamd_symbols_group *gr; | |||
struct rspamd_symbol_def *sym; | |||
struct rspamd_symbol_def *sym, *cur; | |||
ucl_object_t *obj, *top, *sym_obj; | |||
gpointer k, v; | |||
if (!rspamd_controller_check_password (conn_ent, session, msg, FALSE)) { | |||
return 0; | |||
@@ -304,17 +306,17 @@ rspamd_controller_handle_symbols (struct rspamd_http_connection_entry *conn_ent, | |||
top = ucl_object_typed_new (UCL_ARRAY); | |||
/* Go through all symbols groups */ | |||
cur_gr = session->ctx->cfg->symbols_groups; | |||
while (cur_gr) { | |||
gr = cur_gr->data; | |||
g_hash_table_iter_init (&it, session->ctx->cfg->symbols_groups); | |||
while (g_hash_table_iter_next (&it, &k, &v)) { | |||
gr = v; | |||
obj = ucl_object_typed_new (UCL_OBJECT); | |||
ucl_object_insert_key (obj, ucl_object_fromstring ( | |||
gr->name), "group", 0, false); | |||
/* Iterate through all symbols */ | |||
cur_sym = gr->symbols; | |||
while (cur_sym) { | |||
sym = gr->symbols; | |||
LL_FOREACH (sym, cur) { | |||
sym_obj = ucl_object_typed_new (UCL_OBJECT); | |||
sym = cur_sym->data; | |||
ucl_object_insert_key (sym_obj, ucl_object_fromstring (sym->name), | |||
"symbol", 0, false); | |||
@@ -328,9 +330,8 @@ rspamd_controller_handle_symbols (struct rspamd_http_connection_entry *conn_ent, | |||
} | |||
ucl_object_insert_key (obj, sym_obj, "rules", 0, false); | |||
cur_sym = g_list_next (cur_sym); | |||
} | |||
cur_gr = g_list_next (cur_gr); | |||
ucl_array_append (top, obj); | |||
} | |||
@@ -71,21 +71,25 @@ enum lua_var_type { | |||
}; | |||
/** | |||
* Symbol definition | |||
* Symbols group | |||
*/ | |||
struct rspamd_symbol_def { | |||
struct rspamd_symbol_def; | |||
struct rspamd_symbols_group { | |||
gchar *name; | |||
gchar *description; | |||
gdouble *weight_ptr; | |||
gboolean one_shot; | |||
struct rspamd_symbol_def *symbols; | |||
gdouble max_score; | |||
}; | |||
/** | |||
* Symbols group | |||
* Symbol definition | |||
*/ | |||
struct rspamd_symbols_group { | |||
struct rspamd_symbol_def { | |||
gchar *name; | |||
GList *symbols; | |||
gchar *description; | |||
gdouble *weight_ptr; | |||
struct rspamd_symbols_group *gr; | |||
gboolean one_shot; | |||
struct rspamd_symbol_def *next; | |||
}; | |||
@@ -208,7 +212,7 @@ struct rspamd_config { | |||
gchar *filters_str; /**< string of filters */ | |||
ucl_object_t *rcl_obj; /**< rcl object */ | |||
GHashTable * metrics; /**< hash of metrics indexed by metric name */ | |||
GList * symbols_groups; /**< groups of symbols */ | |||
GHashTable * symbols_groups; /**< groups of symbols */ | |||
GList * metrics_list; /**< linked list of metrics */ | |||
GHashTable * metrics_symbols; /**< hash table of metrics indexed by symbol */ | |||
GHashTable * c_modules; /**< hash of c modules indexed by module name */ |
@@ -240,15 +240,6 @@ rspamd_rcl_options_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, | |||
cfg, err); | |||
} | |||
static gint | |||
rspamd_symbols_group_find_func (gconstpointer a, gconstpointer b) | |||
{ | |||
const struct rspamd_symbols_group *gr = a; | |||
const gchar *uv = b; | |||
return g_ascii_strcasecmp (gr->name, uv); | |||
} | |||
/** | |||
* Insert a symbol to the metric | |||
* @param cfg | |||
@@ -259,14 +250,14 @@ rspamd_symbols_group_find_func (gconstpointer a, gconstpointer b) | |||
*/ | |||
static gboolean | |||
rspamd_rcl_insert_symbol (struct rspamd_config *cfg, struct metric *metric, | |||
const ucl_object_t *obj, gboolean is_legacy, GError **err) | |||
const ucl_object_t *obj, const gchar *group, gboolean is_legacy, GError **err) | |||
{ | |||
const gchar *group = "ungrouped", *description = NULL, *sym_name; | |||
const gchar *description = NULL, *sym_name; | |||
gdouble symbol_score, *score_ptr; | |||
const ucl_object_t *val; | |||
struct rspamd_symbols_group *sym_group; | |||
struct rspamd_symbol_def *sym_def; | |||
GList *metric_list, *group_list; | |||
GList *metric_list; | |||
gboolean one_shot = FALSE; | |||
/* | |||
@@ -291,6 +282,11 @@ rspamd_rcl_insert_symbol (struct rspamd_config *cfg, struct metric *metric, | |||
else { | |||
sym_name = ucl_object_key (obj); | |||
} | |||
if (group == NULL) { | |||
group = "ungrouped"; | |||
} | |||
if (ucl_object_todouble_safe (obj, &symbol_score)) { | |||
description = NULL; | |||
} | |||
@@ -311,6 +307,7 @@ rspamd_rcl_insert_symbol (struct rspamd_config *cfg, struct metric *metric, | |||
val = ucl_object_find_key (obj, "group"); | |||
if (val != NULL) { | |||
group = ucl_object_tostring (val); | |||
msg_warn ("legacy 'group' parameter inside symbol definition"); | |||
} | |||
val = ucl_object_find_key (obj, "one_shot"); | |||
if (val != NULL) { | |||
@@ -354,23 +351,18 @@ rspamd_rcl_insert_symbol (struct rspamd_config *cfg, struct metric *metric, | |||
} | |||
/* Search for symbol group */ | |||
group_list = g_list_find_custom (cfg->symbols_groups, | |||
group, | |||
rspamd_symbols_group_find_func); | |||
if (group_list == NULL) { | |||
sym_group = g_hash_table_lookup (cfg->symbols_groups, group); | |||
if (sym_group == NULL) { | |||
/* Create new group */ | |||
sym_group = | |||
rspamd_mempool_alloc (cfg->cfg_pool, | |||
sizeof (struct rspamd_symbols_group)); | |||
sym_group->name = rspamd_mempool_strdup (cfg->cfg_pool, group); | |||
sym_group->symbols = NULL; | |||
cfg->symbols_groups = g_list_prepend (cfg->symbols_groups, sym_group); | |||
g_hash_table_insert (cfg->symbols_groups, sym_group->name, sym_group); | |||
} | |||
else { | |||
sym_group = group_list->data; | |||
} | |||
/* Insert symbol */ | |||
sym_group->symbols = g_list_prepend (sym_group->symbols, sym_def); | |||
LL_PREPEND (sym_group->symbols, sym_def); | |||
return TRUE; | |||
} | |||
@@ -473,7 +465,7 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, | |||
} | |||
it = NULL; | |||
while ((cur = ucl_iterate_object (val, &it, true)) != NULL) { | |||
if (!rspamd_rcl_insert_symbol (cfg, metric, cur, FALSE, err)) { | |||
if (!rspamd_rcl_insert_symbol (cfg, metric, cur, NULL, FALSE, err)) { | |||
return FALSE; | |||
} | |||
} | |||
@@ -489,9 +481,8 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, | |||
"symbols must be an object"); | |||
return FALSE; | |||
} | |||
LL_FOREACH (val, cur) | |||
{ | |||
if (!rspamd_rcl_insert_symbol (cfg, metric, cur, TRUE, err)) { | |||
LL_FOREACH (val, cur) { | |||
if (!rspamd_rcl_insert_symbol (cfg, metric, cur, NULL, TRUE, err)) { | |||
return FALSE; | |||
} | |||
} |
@@ -164,6 +164,7 @@ rspamd_config_defaults (struct rspamd_config *cfg) | |||
rspamd_str_equal); | |||
cfg->cfg_params = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); | |||
cfg->metrics_symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); | |||
cfg->symbols_groups = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); | |||
cfg->map_timeout = DEFAULT_MAP_TIMEOUT; | |||
@@ -176,9 +177,6 @@ rspamd_config_defaults (struct rspamd_config *cfg) | |||
void | |||
rspamd_config_free (struct rspamd_config *cfg) | |||
{ | |||
GList *cur; | |||
struct rspamd_symbols_group *gr; | |||
rspamd_map_remove_all (cfg); | |||
ucl_obj_unref (cfg->rcl_obj); | |||
g_hash_table_remove_all (cfg->metrics); | |||
@@ -190,18 +188,7 @@ rspamd_config_free (struct rspamd_config *cfg) | |||
g_hash_table_unref (cfg->cfg_params); | |||
g_hash_table_destroy (cfg->metrics_symbols); | |||
g_hash_table_destroy (cfg->classifiers_symbols); | |||
/* Free symbols groups */ | |||
cur = cfg->symbols_groups; | |||
while (cur) { | |||
gr = cur->data; | |||
if (gr->symbols) { | |||
g_list_free (gr->symbols); | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
if (cfg->symbols_groups) { | |||
g_list_free (cfg->symbols_groups); | |||
} | |||
g_hash_table_unref (cfg->symbols_groups); | |||
if (cfg->checksum) { | |||
g_free (cfg->checksum); |