From 56b591bcb2c91ab8af7def656f115e2e794a2b8a Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 14 Jun 2012 22:20:50 +0400 Subject: * Allow to use other composites inside a composite's expression Fix for cmake 2.6. --- CMakeLists.txt | 29 ++++++++++++++++++++-------- config.h.in | 1 + src/cfg_xml.c | 6 +++++- src/filter.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/filter.h | 8 ++++++++ 5 files changed, 91 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa5fff1d6..0a4924d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/config.h.in b/config.h.in index eefb541bc..c1ac287cb 100644 --- a/config.h.in +++ b/config.h.in @@ -191,6 +191,7 @@ #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}" diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 6c21fa14d..ad542265d 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -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; diff --git a/src/filter.c b/src/filter.c index 1d6f19e21..d7d2a0c15 100644 --- a/src/filter.c +++ b/src/filter.c @@ -43,6 +43,19 @@ #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); diff --git a/src/filter.h b/src/filter.h index 5cd6e4ff2..5dc141af8 100644 --- a/src/filter.h +++ b/src/filter.h @@ -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 -- cgit v1.2.3