struct rspamd_symbol_def *sym_def;
struct metric *metric;
struct rspamd_config *cfg;
+ const ucl_object_t *elt;
GList *metric_list;
g_assert (key != NULL);
msg_warn_config ("redefining symbol '%s' in metric '%s'", key, metric->name);
}
+ if ((elt = ucl_object_find_key (obj, "one_shot")) != NULL) {
+ if (ucl_object_toboolean (elt)) {
+ sym_def->flags |= RSPAMD_SYMBOL_FLAG_ONESHOT;
+ }
+ }
+
+ if ((elt = ucl_object_find_key (obj, "ignore")) != NULL) {
+ if (ucl_object_toboolean (elt)) {
+ sym_def->flags |= RSPAMD_SYMBOL_FLAG_IGNORE;
+ }
+ }
+
if (!rspamd_rcl_section_parse_defaults (section, pool, obj,
sym_def, err)) {
return FALSE;
const gchar *key, gpointer ud,
struct rspamd_rcl_section *section, GError **err)
{
- const ucl_object_t *val, *cur;
+ const ucl_object_t *val, *cur, *elt;
+ ucl_object_iter_t it;
struct rspamd_config *cfg = ud;
struct metric *metric;
struct rspamd_rcl_section *subsection;
struct rspamd_rcl_symbol_data sd;
+ struct rspamd_symbol_def *sym_def;
g_assert (key != NULL);
}
}
+ /* Handle ignored symbols */
+ val = ucl_object_find_key (obj, "ignore");
+ if (val != NULL && ucl_object_type (val) == UCL_ARRAY) {
+ LL_FOREACH (val, cur) {
+ it = NULL;
+
+ while ((elt = ucl_iterate_object (cur, &it, true)) != NULL) {
+ if (ucl_object_type (elt) == UCL_STRING) {
+ sym_def = g_hash_table_lookup (metric->symbols,
+ ucl_object_tostring (elt));
+
+ if (sym_def != NULL) {
+ sym_def->flags |= RSPAMD_SYMBOL_FLAG_IGNORE;
+ }
+ else {
+ msg_warn ("cannot find symbol %s to set ignore flag",
+ ucl_object_tostring (elt));
+ }
+ }
+ }
+ }
+ }
+
return TRUE;
}
rspamd_rcl_parse_struct_string,
G_STRUCT_OFFSET (struct rspamd_symbol_def, description),
0);
- rspamd_rcl_add_default_handler (ssub,
- "one_shot",
- rspamd_rcl_parse_struct_boolean,
- G_STRUCT_OFFSET (struct rspamd_symbol_def, one_shot),
- 0);
rspamd_rcl_add_default_handler (ssub,
"score",
rspamd_rcl_parse_struct_double,
rspamd_rcl_parse_struct_string,
G_STRUCT_OFFSET (struct rspamd_symbol_def, description),
0);
- rspamd_rcl_add_default_handler (sssub,
- "one_shot",
- rspamd_rcl_parse_struct_boolean,
- G_STRUCT_OFFSET (struct rspamd_symbol_def, one_shot),
- 0);
rspamd_rcl_add_default_handler (sssub,
"score",
rspamd_rcl_parse_struct_double,
gboolean strict)
{
struct cache_item *item;
- GList *cur, *metric_symbols;
+ GHashTableIter it;
+ GList *cur;
+ gpointer k, v;
+ struct rspamd_symbol_def *sym_def;
+ struct metric *metric;
+ gboolean ignore_symbol = FALSE, ret = TRUE;
if (cache == NULL) {
msg_err_cache ("empty cache is invalid");
rspamd_symbols_cache_validate_cb,
cache);
/* Now check each metric item and find corresponding symbol in a cache */
- metric_symbols = g_hash_table_get_keys (cfg->metrics_symbols);
- cur = metric_symbols;
- while (cur) {
- item = g_hash_table_lookup (cache->items_by_symbol, cur->data);
-
- if (item == NULL) {
- msg_warn_cache (
- "symbol '%s' has its score defined but there is no "
- "corresponding rule registered",
- cur->data);
- if (strict) {
- g_list_free (metric_symbols);
- return FALSE;
+ g_hash_table_iter_init (&it, cfg->metrics_symbols);
+
+ while (g_hash_table_iter_next (&it, &k, &v)) {
+ ignore_symbol = FALSE;
+ cur = v;
+
+ while (cur) {
+ metric = cur->data;
+ sym_def = g_hash_table_lookup (metric->symbols, k);
+
+ if (sym_def && (sym_def->flags & RSPAMD_SYMBOL_FLAG_IGNORE)) {
+ ignore_symbol = TRUE;
+ break;
+ }
+
+ cur = g_list_next (cur);
+ }
+
+ if (!ignore_symbol) {
+ item = g_hash_table_lookup (cache->items_by_symbol, k);
+
+ if (item == NULL) {
+ msg_warn_cache (
+ "symbol '%s' has its score defined but there is no "
+ "corresponding rule registered",
+ k);
+ if (strict) {
+ ret = FALSE;
+ }
}
}
- cur = g_list_next (cur);
}
- g_list_free (metric_symbols);
post_cache_init (cache);
- return TRUE;
+ return ret;
}
static gboolean