From c72912310c575a5ba7e7e50a5fdd425f3a4e4dbc Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 29 Mar 2009 14:02:01 +0400 Subject: [PATCH] * Make regexp cache functions public for using them in other places * Add function regexp_match_number that checks number of matched arguments: e.g.: regexp_match_number(2, ${__RE1}, ${__RE2}, header_exists(Subject)) --- src/expressions.c | 4 ++-- src/expressions.h | 14 ++++++++++++++ src/plugins/regexp.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/expressions.c b/src/expressions.c index d4db580e2..957c43c5c 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -71,7 +71,7 @@ fl_cmp (const void *s1, const void *s2) /* Cache for regular expressions that are used in functions */ static GHashTable *re_cache = NULL; -static inline void * +void * re_cache_check (const char *line) { if (re_cache == NULL) { @@ -81,7 +81,7 @@ re_cache_check (const char *line) return g_hash_table_lookup (re_cache, line); } -static inline void +void re_cache_add (char *line, void *pointer) { if (re_cache == NULL) { diff --git a/src/expressions.h b/src/expressions.h index 4b5ccce5e..5c2a391eb 100644 --- a/src/expressions.h +++ b/src/expressions.h @@ -74,4 +74,18 @@ gboolean call_expression_function (struct expression_function *func, struct work */ void register_expression_function (const char *name, rspamd_internal_func_t func); +/** + * Add regexp to regexp cache + * @param line symbolic representation + * @param pointer regexp data + */ +void re_cache_add (char *line, void *pointer); + +/** + * Check regexp in cache + * @param line symbolic representation + * @return pointer to regexp data or NULL if regexp is not found + */ +void * re_cache_check (const char *line); + #endif diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 15edb7d70..3b3328f3e 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -57,6 +57,7 @@ struct regexp_ctx { static struct regexp_ctx *regexp_module_ctx = NULL; static int regexp_common_filter (struct worker_task *task); +static gboolean rspamd_regexp_match_number (struct worker_task *task, GList *args); int regexp_module_init (struct config_file *cfg, struct module_ctx **ctx) @@ -71,6 +72,7 @@ regexp_module_init (struct config_file *cfg, struct module_ctx **ctx) regexp_module_ctx->items = NULL; *ctx = (struct module_ctx *)regexp_module_ctx; + register_expression_function ("regexp_match_number", rspamd_regexp_match_number); return 0; } @@ -382,3 +384,47 @@ regexp_common_filter (struct worker_task *task) return 0; } + +static gboolean +rspamd_regexp_match_number (struct worker_task *task, GList *args) +{ + char *param_pattern; + int param_count, res = 0; + struct rspamd_regexp *re; + struct expression_argument *arg; + GList *cur; + + if (args == NULL) { + msg_warn ("rspamd_regexp_match_number: no parameters to function"); + return FALSE; + } + + arg = args->data; + param_count = strtoul (arg->data, NULL, 10); + + cur = g_list_next (args); + while (cur) { + arg = args->data; + if (arg->type == EXPRESSION_ARGUMENT_FUNCTION) { + if (call_expression_function ((struct expression_function *)arg->data, task)) { + res ++; + } + } + else { + param_pattern = (char *)arg->data; + /* This is regexp, so compile and create g_regexp object */ + if ((re = re_cache_check (param_pattern)) == NULL) { + re = parse_regexp (task->task_pool, param_pattern); + if (re == NULL) { + msg_warn ("rspamd_regexp_match_number: cannot compile regexp for function"); + return FALSE; + } + re_cache_add (param_pattern, re); + } + res += process_regexp (re, task); + } + cur = g_list_next (args); + } + + return res >= param_count; +} -- 2.39.5