summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-29 14:02:01 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-29 14:02:01 +0400
commitc72912310c575a5ba7e7e50a5fdd425f3a4e4dbc (patch)
tree541e2b4917027886a4054cb118c41c0f7e5513e6 /src
parentbbe772242e96fc37167a33a3f894d7f04e6b4087 (diff)
downloadrspamd-c72912310c575a5ba7e7e50a5fdd425f3a4e4dbc.tar.gz
rspamd-c72912310c575a5ba7e7e50a5fdd425f3a4e4dbc.zip
* 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))
Diffstat (limited to 'src')
-rw-r--r--src/expressions.c4
-rw-r--r--src/expressions.h14
-rw-r--r--src/plugins/regexp.c46
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;
+}