summaryrefslogtreecommitdiffstats
path: root/src/expressions.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-28 16:45:05 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-28 16:45:05 +0300
commitbbe772242e96fc37167a33a3f894d7f04e6b4087 (patch)
treed7c0550c5bdbc58baf2fdb9b9fd6a230bff9f378 /src/expressions.c
parent5d37c7aab50278a996a16390ef7a5ad65f799cd7 (diff)
downloadrspamd-bbe772242e96fc37167a33a3f894d7f04e6b4087.tar.gz
rspamd-bbe772242e96fc37167a33a3f894d7f04e6b4087.zip
* Add ability for plugins to register its own functions in expression's parser
Diffstat (limited to 'src/expressions.c')
-rw-r--r--src/expressions.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/expressions.c b/src/expressions.c
index e706fc938..d4db580e2 100644
--- a/src/expressions.c
+++ b/src/expressions.c
@@ -30,8 +30,6 @@
#include "fuzzy.h"
#include "expressions.h"
-typedef gboolean (*rspamd_internal_func_t)(struct worker_task *, GList *args);
-
gboolean rspamd_compare_encoding (struct worker_task *task, GList *args);
gboolean rspamd_header_exists (struct worker_task *task, GList *args);
gboolean rspamd_content_type_compare_param (struct worker_task *task, GList *args);
@@ -45,7 +43,7 @@ gboolean rspamd_parts_distance (struct worker_task *task, GList *args);
* Sorted by name to use bsearch
*/
static struct _fl {
- char *name;
+ const char *name;
rspamd_internal_func_t func;
} rspamd_functions_list[] = {
{ "compare_encoding", rspamd_compare_encoding },
@@ -57,6 +55,10 @@ static struct _fl {
{ "header_exists", rspamd_header_exists },
};
+static struct _fl *list_ptr = &rspamd_functions_list[0];
+static uint32_t functions_number = sizeof (rspamd_functions_list) / sizeof (struct _fl);
+static gboolean list_allocated = FALSE;
+
/* Bsearch routine */
static int
fl_cmp (const void *s1, const void *s2)
@@ -595,7 +597,7 @@ call_expression_function (struct expression_function *func, struct worker_task *
key.name = func->name;
- selected = bsearch (&key, rspamd_functions_list, sizeof (rspamd_functions_list) / sizeof (struct _fl),
+ selected = bsearch (&key, list_ptr, functions_number,
sizeof (struct _fl), fl_cmp);
if (selected == NULL) {
msg_warn ("call_expression_function: call to undefined function %s", key.name);
@@ -605,6 +607,26 @@ call_expression_function (struct expression_function *func, struct worker_task *
return selected->func (task, func->args);
}
+void
+register_expression_function (const char *name, rspamd_internal_func_t func)
+{
+ static struct _fl *new;
+
+ functions_number ++;
+
+ new = g_new (struct _fl, functions_number);
+ memcpy (new, rspamd_functions_list, (functions_number - 1) * sizeof (struct _fl));
+ if (list_allocated) {
+ g_free (list_ptr);
+ }
+
+ list_allocated = TRUE;
+ new[functions_number - 1].name = name;
+ new[functions_number - 1].func = func;
+ qsort (new, functions_number, sizeof (struct _fl), fl_cmp);
+ list_ptr = new;
+}
+
gboolean
rspamd_compare_encoding (struct worker_task *task, GList *args)
{