From d14307b475a7f08b1035df32c8b7da7d0898ff55 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 13 Jun 2019 15:44:25 +0100 Subject: [PATCH] [Project] Add methods to manipulate with allowed ids --- src/libserver/rspamd_symcache.c | 156 +++++++++++++++++++++++++++++++- src/libserver/rspamd_symcache.h | 45 +++++++++ 2 files changed, 200 insertions(+), 1 deletion(-) diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c index 42e40b68c..377ac7d59 100644 --- a/src/libserver/rspamd_symcache.c +++ b/src/libserver/rspamd_symcache.c @@ -89,7 +89,7 @@ struct rspamd_symcache_id_list { union { guint32 st[4]; struct { - guint32 e; + guint32 e; /* First element */ guint32 dynlen; guint *n; } dyn; @@ -272,6 +272,12 @@ rspamd_symcache_order_unref (gpointer p) REF_RELEASE (ord); } +static gint +rspamd_id_cmp (const void * a, const void * b) +{ + return (*(guint32*)a - *(guint32*)b); +} + static struct symcache_order * rspamd_symcache_order_new (struct rspamd_symcache *cache, gsize nelts) @@ -2889,4 +2895,152 @@ rspamd_symcache_composites_foreach (struct rspamd_task *task, SET_FINISH_BIT (task->checkpoint, dyn_item); } } +} + +bool +rspamd_symcache_set_allowed_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + const guint32 *ids, + guint nids) +{ + struct rspamd_symcache_item *item; + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item == NULL) { + return false; + } + + if (nids <= G_N_ELEMENTS (item->allowed_ids.st)) { + /* Use static version */ + memset (&item->allowed_ids, 0, sizeof (item->allowed_ids)); + for (guint i = 0; i < nids; i++) { + item->allowed_ids.st[i] = ids[i]; + } + } + else { + /* Need to use a separate list */ + item->allowed_ids.dyn.e = -1; /* Flag */ + item->allowed_ids.dyn.n = rspamd_mempool_alloc (cache->static_pool, + sizeof (guint32) * nids); + item->allowed_ids.dyn.dynlen = nids; + + for (guint i = 0; i < nids; i++) { + item->allowed_ids.dyn.n[i] = ids[i]; + } + + /* Keep sorted */ + qsort (item->allowed_ids.dyn.n, nids, sizeof (guint32), rspamd_id_cmp); + } + + return true; +} + +bool +rspamd_symcache_set_forbidden_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + const guint32 *ids, + guint nids) +{ + struct rspamd_symcache_item *item; + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item == NULL) { + return false; + } + + if (nids <= G_N_ELEMENTS (item->forbidden_ids.st)) { + /* Use static version */ + memset (&item->forbidden_ids, 0, sizeof (item->forbidden_ids)); + for (guint i = 0; i < nids; i++) { + item->forbidden_ids.st[i] = ids[i]; + } + } + else { + /* Need to use a separate list */ + item->forbidden_ids.dyn.e = -1; /* Flag */ + item->forbidden_ids.dyn.n = rspamd_mempool_alloc (cache->static_pool, + sizeof (guint32) * nids); + item->forbidden_ids.dyn.dynlen = nids; + + for (guint i = 0; i < nids; i++) { + item->forbidden_ids.dyn.n[i] = ids[i]; + } + + /* Keep sorted */ + qsort (item->forbidden_ids.dyn.n, nids, sizeof (guint32), rspamd_id_cmp); + } + + return true; +} + +const guint32* +rspamd_symcache_get_allowed_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + guint *nids) +{ + struct rspamd_symcache_item *item; + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item == NULL) { + return NULL; + } + + if (item->allowed_ids.dyn.e == -1) { + /* Dynamic list */ + *nids = item->allowed_ids.dyn.dynlen; + + return item->allowed_ids.dyn.n; + } + else { + guint cnt = 0; + + while (item->allowed_ids.st[cnt] != 0) { + cnt ++; + + g_assert (cnt < G_N_ELEMENTS (item->allowed_ids.st)); + } + + + *nids = cnt; + + return item->allowed_ids.st; + } +} + +const guint32* +rspamd_symcache_get_forbidden_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + guint *nids) +{ + struct rspamd_symcache_item *item; + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item == NULL) { + return NULL; + } + + if (item->forbidden_ids.dyn.e == -1) { + /* Dynamic list */ + *nids = item->forbidden_ids.dyn.dynlen; + + return item->forbidden_ids.dyn.n; + } + else { + guint cnt = 0; + + while (item->forbidden_ids.st[cnt] != 0) { + cnt ++; + + g_assert (cnt < G_N_ELEMENTS (item->allowed_ids.st)); + } + + + *nids = cnt; + + return item->forbidden_ids.st; + } } \ No newline at end of file diff --git a/src/libserver/rspamd_symcache.h b/src/libserver/rspamd_symcache.h index 728b7636c..3be2ab2ec 100644 --- a/src/libserver/rspamd_symcache.h +++ b/src/libserver/rspamd_symcache.h @@ -423,4 +423,49 @@ void rspamd_symcache_composites_foreach (struct rspamd_task *task, struct rspamd_symcache *cache, GHFunc func, gpointer fd); + +/** + * Sets allowed settings ids for a symbol + * @param cache + * @param symbol + * @param ids + * @param nids + */ +bool rspamd_symcache_set_allowed_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + const guint32 *ids, + guint nids); +/** + * Sets denied settings ids for a symbol + * @param cache + * @param symbol + * @param ids + * @param nids + */ +bool rspamd_symcache_set_forbidden_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + const guint32 *ids, + guint nids); + +/** + * Returns allowed ids for a symbol as a constant array + * @param cache + * @param symbol + * @param nids + * @return + */ +const guint32* rspamd_symcache_get_allowed_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + guint *nids); +/** + * Returns denied ids for a symbol as a constant array + * @param cache + * @param symbol + * @param nids + * @return + */ +const guint32* rspamd_symcache_get_forbidden_settings_ids (struct rspamd_symcache *cache, + const gchar *symbol, + guint *nids); + #endif -- 2.39.5