]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability for plugins to register its own functions in expression's parser
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Sat, 28 Mar 2009 13:45:05 +0000 (16:45 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Sat, 28 Mar 2009 13:45:05 +0000 (16:45 +0300)
src/expressions.c
src/expressions.h

index e706fc9382f3400c0f27186f1506592cc544fd33..d4db580e2ebc82d745dafc520cbeb8d1b5841e82 100644 (file)
@@ -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)
 {
index 65b555566707a2fcbfb8e37d32ad9089576e291e..4b5ccce5e77df2c61f174d9bf2a52bca6e9e393f 100644 (file)
@@ -41,6 +41,8 @@ struct expression {
        struct expression *next;                                                                        /**< chain link                                                                         */
 };
 
+typedef gboolean (*rspamd_internal_func_t)(struct worker_task *, GList *args);
+
 /**
  * Parse regexp line to regexp structure
  * @param pool memory pool to use
@@ -65,5 +67,11 @@ struct expression* parse_expression (memory_pool_t *pool, char *line);
  */
 gboolean call_expression_function (struct expression_function *func, struct worker_task *task);
 
+/**
+ * Register specified function to rspamd internal functions list
+ * @param name name of function
+ * @param func pointer to function
+ */
+void register_expression_function (const char *name, rspamd_internal_func_t func);
 
 #endif