]> source.dussan.org Git - rspamd.git/commitdiff
* Allow to use other composites inside a composite's expression
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 14 Jun 2012 18:20:50 +0000 (22:20 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 14 Jun 2012 18:20:50 +0000 (22:20 +0400)
Fix for cmake 2.6.

CMakeLists.txt
config.h.in
src/cfg_xml.c
src/filter.c
src/filter.h

index fa5fff1d662a559e6b8276042e49dd0787202e61..0a4924d9327877f33f2d2f89ad5f56089f3e90d9 100644 (file)
@@ -55,26 +55,38 @@ MACRO(_AddModulesForced MLIST WLIST)
        STRING(RANDOM LENGTH 8 _MODULES_ID)
        SET(MODULES_ID ${_MODULES_ID} CACHE INTERNAL "Modules ID" FORCE)
        FILE(WRITE "src/modules.c" "/* ${MODULES_ID} */\n#include \"config.h\"\n")
-       FOREACH(MOD IN LISTS ${MLIST})
+       
+       # Handle even old cmake
+       LIST(LENGTH ${MLIST} MLIST_COUNT)
+       LIST(LENGTH ${WLIST} WLIST_COUNT)
+       MATH(EXPR MLIST_MAX ${MLIST_COUNT}-1)
+       MATH(EXPR WLIST_MAX ${WLIST_COUNT}-1)
+       
+       FOREACH(MOD_IDX RANGE ${MLIST_MAX})
+               LIST(GET ${MLIST} ${MOD_IDX} MOD)
                FILE(APPEND "src/modules.c" "extern module_t ${MOD}_module;\n")
-       ENDFOREACH(MOD IN LISTS ${MLIST})
+       ENDFOREACH(MOD_IDX RANGE ${MLIST_MAX})
                 
        FILE(APPEND "src/modules.c" "\n\nmodule_t *modules[] = {\n")
        
-       FOREACH(MOD IN LISTS ${MLIST})
+       FOREACH(MOD_IDX RANGE ${MLIST_MAX})
+               LIST(GET ${MLIST} ${MOD_IDX} MOD)
                FILE(APPEND "src/modules.c" "&${MOD}_module,\n")
-       ENDFOREACH(MOD IN LISTS ${MLIST})
+       ENDFOREACH(MOD_IDX RANGE ${MLIST_MAX})
+       
        FILE(APPEND "src/modules.c" "NULL\n};\n")
        
-       FOREACH(WRK IN LISTS ${WLIST})
+       FOREACH(MOD_IDX RANGE ${WLIST_MAX})
+               LIST(GET ${WLIST} ${MOD_IDX} WRK)
                FILE(APPEND "src/modules.c" "extern worker_t ${WRK}_worker;\n")
-       ENDFOREACH(WRK IN LISTS ${WLIST})
+       ENDFOREACH(MOD_IDX RANGE ${WLIST_MAX})
         
        FILE(APPEND "src/modules.c" "\n\nworker_t *workers[] = {\n")
        
-       FOREACH(WRK IN LISTS ${WLIST})
+       FOREACH(MOD_IDX RANGE ${WLIST_MAX})
+               LIST(GET ${WLIST} ${MOD_IDX} WRK)
                FILE(APPEND "src/modules.c" "&${WRK}_worker,\n")
-       ENDFOREACH(WRK IN LISTS ${WLIST})
+       ENDFOREACH(MOD_IDX RANGE ${WLIST_MAX})
        FILE(APPEND "src/modules.c" "NULL\n};\n")
 ENDMACRO(_AddModulesForced MLIST WLIST)
 
@@ -814,6 +826,7 @@ CHECK_SYMBOL_EXISTS(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE)
 CHECK_SYMBOL_EXISTS(fallocate fcntl.h HAVE_FALLOCATE)
 CHECK_SYMBOL_EXISTS(fdatasync unistd.h HAVE_FDATASYNC)
 CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
+CHECK_SYMBOL_EXISTS(setbit sys/param.h PARAM_H_HAS_BITSET)
 IF(HAVE_SIGINFO_H)
        CHECK_SYMBOL_EXISTS(SA_SIGINFO "signal.h;siginfo.h" HAVE_SA_SIGINFO)
 ELSE(HAVE_SIGINFO_H)
index eefb541bcd13e35033f7bdadfa373f5e4bc738de..c1ac287cbc027969a11d1904f73a61995f4a50c0 100644 (file)
 #cmakedefine GLIB_RE_COMPAT             1
 #cmakedefine GLIB_UNISCRIPT_COMPAT              1
 #cmakedefine GLIB_HASH_COMPAT           1
+#cmakedefine PARAM_H_HAS_BITSET  1
 
 #define RVERSION          "${RSPAMD_VERSION}"
 #define RID               "${ID}"
index 6c21fa14db9b97596f2dafc58d35c391959e7bb9..ad542265d6561141dee69bddcafe556797b90c57 100644 (file)
@@ -1276,6 +1276,7 @@ handle_composite (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHas
 {
        gchar                        *val;
        struct expression            *expr;
+       struct rspamd_composite      *composite;
        
        if (attrs == NULL || (val = g_hash_table_lookup (attrs, "name")) == NULL) {
                msg_err ("'name' attribute is required for tag 'composite'");
@@ -1286,7 +1287,10 @@ handle_composite (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHas
                msg_err ("cannot parse composite expression: %s", data);
                return FALSE;
        }
-       g_hash_table_insert (cfg->composite_symbols, val, expr);
+       composite = memory_pool_alloc (cfg->cfg_pool, sizeof (struct rspamd_composite));
+       composite->expr = expr;
+       composite->id = g_hash_table_size (cfg->composite_symbols) + 1;
+       g_hash_table_insert (cfg->composite_symbols, val, composite);
        register_virtual_symbol (&cfg->cache, val, 1);
 
        return TRUE;
index 1d6f19e21b99a6117cd5a7d52ab20fced55212e7..d7d2a0c156b904ff8a9ea42df413ca6b31be3084 100644 (file)
 
 #define COMMON_PART_FACTOR 95
 
+#ifndef PARAM_H_HAS_BITSET
+/* Bit map related macros. */
+#define NBBY    8               /* number of bits in a byte */
+#define setbit(a,i)     (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i)     (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i)                                                      \
+        (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i)                                                      \
+        ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#endif
+#define BITSPERBYTE    (8*sizeof (gchar))
+#define NBYTES(nbits)  (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
+
 static inline                   GQuark
 filter_error_quark (void)
 {
@@ -286,10 +299,12 @@ process_filters (struct worker_task *task)
        return 1;
 }
 
+
 struct composites_data {
        struct worker_task             *task;
        struct metric_result           *metric_res;
        GTree                          *symbols_to_remove;
+       guint8                                             *checked;
 };
 
 struct symbol_remove_data {
@@ -310,15 +325,23 @@ static void
 composites_foreach_callback (gpointer key, gpointer value, void *data)
 {
        struct composites_data         *cd = (struct composites_data *)data;
-       struct expression              *expr = (struct expression *)value;
+       struct rspamd_composite        *composite = value, *ncomp;
+       struct expression              *expr;
        GQueue                         *stack;
        GList                          *symbols = NULL, *s;
        gsize                           cur, op1, op2;
-       gchar                           logbuf[256], *sym;
+       gchar                           logbuf[256], *sym, *check_sym;
        gint                            r;
        struct symbol                  *ms;
        struct symbol_remove_data      *rd;
 
+
+       expr = composite->expr;
+       if (isset (cd->checked, composite->id)) {
+               /* Symbol was already checked */
+               return;
+       }
+
        stack = g_queue_new ();
 
        while (expr) {
@@ -330,6 +353,16 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
                        }
                        if (g_hash_table_lookup (cd->metric_res->symbols, sym) == NULL) {
                                cur = 0;
+                               if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, sym)) != NULL) {
+                                       /* Set checked for this symbol to avoid cyclic references */
+                                       if (isclr (cd->checked, ncomp->id)) {
+                                               setbit (cd->checked, composite->id);
+                                               composites_foreach_callback (sym, ncomp, cd);
+                                               if (g_hash_table_lookup (cd->metric_res->symbols, sym) != NULL) {
+                                                       cur = 1;
+                                               }
+                                       }
+                               }
                        }
                        else {
                                cur = 1;
@@ -342,6 +375,7 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
                                /* Queue has no operands for operation, exiting */
                                g_list_free (symbols);
                                g_queue_free (stack);
+                               setbit (cd->checked, composite->id);
                                return;
                        }
                        switch (expr->content.operation) {
@@ -376,10 +410,23 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
                        while (s) {
                                sym = s->data;
                                if (*sym == '~' || *sym == '-') {
-                                       ms = g_hash_table_lookup (cd->metric_res->symbols, sym + 1);
+                                       check_sym = sym + 1;
                                }
                                else {
-                                       ms = g_hash_table_lookup (cd->metric_res->symbols, sym);
+                                       check_sym = sym;
+                               }
+                               ms = g_hash_table_lookup (cd->metric_res->symbols, check_sym);
+
+                               if (ms == NULL) {
+                                       /* Try to process other composites */
+                                       if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, check_sym)) != NULL) {
+                                               /* Set checked for this symbol to avoid cyclic references */
+                                               if (isclr (cd->checked, ncomp->id)) {
+                                                       setbit (cd->checked, composite->id);
+                                                       composites_foreach_callback (check_sym, ncomp, cd);
+                                                       ms = g_hash_table_lookup (cd->metric_res->symbols, check_sym);
+                                               }
+                                       }
                                }
 
                                if (ms != NULL) {
@@ -401,6 +448,9 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
                                                g_tree_insert (cd->symbols_to_remove, (gpointer)ms->name, rd);
                                        }
                                }
+                               else {
+
+                               }
 
                                if (s->next) {
                                        r += rspamd_snprintf (logbuf + r, sizeof (logbuf) -r, "%s, ", s->data);
@@ -416,6 +466,7 @@ composites_foreach_callback (gpointer key, gpointer value, void *data)
                }
        }
 
+       setbit (cd->checked, composite->id);
        g_queue_free (stack);
        g_list_free (symbols);
 
@@ -517,6 +568,7 @@ composites_metric_callback (gpointer key, gpointer value, gpointer data)
        cd->task = task;
        cd->metric_res = (struct metric_result *)metric_res;
        cd->symbols_to_remove = g_tree_new (remove_compare_data);
+       cd->checked = memory_pool_alloc0 (task->task_pool, NBYTES (g_hash_table_size (task->cfg->composite_symbols)));
 
        /* Process hash table */
        g_hash_table_foreach (task->cfg->composite_symbols, composites_foreach_callback, cd);
index 5cd6e4ff2be8ce2a5576e1342dfc4694f9875bc0..5dc141af8cac296f6f45db04afc6246b82eb5c24 100644 (file)
@@ -80,6 +80,14 @@ struct metric_result {
        struct rspamd_settings *domain_settings;                /**< settings for metric                                        */
 };
 
+/**
+ * Composite structure
+ */
+struct rspamd_composite {
+       struct expression *expr;
+       gint id;
+};
+
 /**
  * Process all filters
  * @param task worker's task that present message from user