]> source.dussan.org Git - rspamd.git/commitdiff
Add replacement method for expressions in the confi
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 5 Dec 2015 00:44:00 +0000 (00:44 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 5 Dec 2015 00:44:00 +0000 (00:44 +0000)
src/libserver/re_cache.c
src/libserver/re_cache.h

index 40428b6f190e3418052fe035fc08b1c819fe2587..d8fdc6b58d2c45dc4d2627beaa8f9d6ac33292f2 100644 (file)
@@ -36,8 +36,7 @@ struct rspamd_re_class {
        enum rspamd_re_type type;
        gpointer type_data;
        gsize type_len;
-       GHashTable *re_ids;
-       GPtrArray *all_re;
+       GHashTable *re;
        gchar hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
 };
 
@@ -77,7 +76,6 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache)
        GHashTableIter it;
        gpointer k, v;
        struct rspamd_re_class *re_class;
-       rspamd_regexp_t *re;
        guint i;
 
        g_assert (cache != NULL);
@@ -86,14 +84,7 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache)
        while (g_hash_table_iter_next (&it, &k, &v)) {
                re_class = v;
                g_hash_table_iter_steal (&it);
-
-               for (i = 0; i < re_class->all_re->len; i++) {
-                       re = g_ptr_array_index (re_class->all_re, i);
-
-                       rspamd_regexp_set_cache_id (re, RSPAMD_INVALID_ID);
-                       rspamd_regexp_unref (re);
-               }
-
+               g_hash_table_unref (re_class->re);
                g_slice_free1 (sizeof (*re_class), re_class);
        }
 
@@ -120,6 +111,7 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re,
 {
        guint64 class_id;
        struct rspamd_re_class *re_class;
+       rspamd_regexp_t *nre;
 
        g_assert (cache != NULL);
        g_assert (re != NULL);
@@ -132,29 +124,60 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re,
                re_class->id = class_id;
                re_class->type_len = datalen;
                re_class->type = type;
-               re_class->re_ids = g_hash_table_new (rspamd_regexp_hash,
-                               rspamd_regexp_equal);
+               re_class->re = g_hash_table_new_full (rspamd_regexp_hash,
+                               rspamd_regexp_equal, NULL, (GDestroyNotify)rspamd_regexp_unref);
 
                if (datalen > 0) {
                        re_class->type_data = g_slice_alloc (datalen);
                        memcpy (re_class->type_data, type_data, datalen);
                }
 
-               re_class->all_re = g_ptr_array_new ();
                g_hash_table_insert (cache->re_classes, &re_class->id, re_class);
        }
 
-       g_ptr_array_add (re_class->all_re, rspamd_regexp_ref (re));
        /*
         * We set re id based on the global position in the cache
         */
        rspamd_regexp_set_cache_id (re, cache->nre ++);
+       nre = rspamd_regexp_ref (re);
+       g_hash_table_insert (re_class->re, re, re);
+}
+
+void
+rspamd_re_cache_replace (struct rspamd_re_cache *cache,
+               rspamd_regexp_t *what,
+               enum rspamd_re_type type,
+               gpointer type_data,
+               gsize datalen,
+               rspamd_regexp_t *with)
+{
+       guint64 class_id, re_id;
+       struct rspamd_re_class *re_class;
+       rspamd_regexp_t *src;
+
+       g_assert (cache != NULL);
+       g_assert (what != NULL);
+       g_assert (with != NULL);
+
+       class_id = rspamd_re_cache_class_id (type, type_data, datalen);
+       re_class = g_hash_table_lookup (cache->re_classes, &class_id);
+
+       if (re_class != NULL) {
+               re_id = rspamd_regexp_get_cache_id (what);
+
+               g_assert (re_id != RSPAMD_INVALID_ID);
+               src = g_hash_table_lookup (re_class->re, what);
+
+               if (src) {
+                       g_hash_table_replace (re_class->re, what, with);
+               }
+       }
 }
 
 void
 rspamd_re_cache_init (struct rspamd_re_cache *cache)
 {
-       GHashTableIter it;
+       GHashTableIter it, cit;
        gpointer k, v;
        struct rspamd_re_class *re_class;
        rspamd_cryptobox_hash_state_t st;
@@ -171,9 +194,10 @@ rspamd_re_cache_init (struct rspamd_re_cache *cache)
                rspamd_cryptobox_hash_init (&st, NULL, 0);
                rspamd_cryptobox_hash_update (&st, (gpointer)&re_class->id,
                                sizeof (re_class->id));
+               g_hash_table_iter_init (&cit, re_class->re);
 
-               for (i = 0; i < re_class->all_re->len; i ++) {
-                       re = g_ptr_array_index (re_class->all_re, i);
+               while (g_hash_table_iter_next (&cit, &k, &v)) {
+                       re = v;
                        rspamd_cryptobox_hash_update (&st, rspamd_regexp_get_id (re),
                                        rspamd_cryptobox_HASHBYTES);
                }
index 4fa3fc28634054527fffa8699229584a4023c6d5..6f2c0f3121df7dc0091370f7b65ebe0f86440521 100644 (file)
@@ -55,6 +55,22 @@ struct rspamd_re_cache *rspamd_re_cache_new (void);
 void rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re,
                enum rspamd_re_type type, gpointer type_data, gsize datalen);
 
+/**
+ * Replace regexp in the cache with another regexp
+ * @param cache cache object
+ * @param what re to replace
+ * @param type type of object
+ * @param type_data associated data with the type (e.g. header name)
+ * @param datalen associated data length
+ * @param with regexp object to replace the origin
+ */
+void rspamd_re_cache_replace (struct rspamd_re_cache *cache,
+               rspamd_regexp_t *what,
+               enum rspamd_re_type type,
+               gpointer type_data,
+               gsize datalen,
+               rspamd_regexp_t *with);
+
 /**
  * Initialize and optimize re cache structure
  */