]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability to call lua function from regexp expressions
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 21 Feb 2011 13:25:38 +0000 (16:25 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 21 Feb 2011 13:25:38 +0000 (16:25 +0300)
src/plugins/regexp.c

index d20c20a5a93a676a4d92df0d8bb548105b1e122d..c70217b60a50b5dfd18cfacc8d4e96484797c1ce 100644 (file)
@@ -979,6 +979,28 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task, const gchar
        return 0;
 }
 
+static gboolean
+maybe_call_lua_function (const gchar *name, struct worker_task *task)
+{
+       lua_State                      *L = task->cfg->lua_state;
+       struct worker_task            **ptask;
+
+       lua_getglobal (L, name);
+       if (lua_isfunction (L, -1)) {
+               ptask = lua_newuserdata (L, sizeof (struct worker_task *));
+               lua_setclass (L, "rspamd{task}", -1);
+               *ptask = task;
+               /* Call function */
+               if (lua_pcall (L, 1, 1, 0) != 0) {
+                       msg_info ("call to %s failed: %s", (gchar *)name, lua_tostring (L, -1));
+                       return FALSE;
+               }
+               return lua_toboolean (L, -1);
+       }
+
+       return FALSE;
+}
+
 static                          gboolean
 optimize_regexp_expression (struct expression **e, GQueue * stack, gboolean res)
 {
@@ -1068,6 +1090,17 @@ process_regexp_expression (struct expression *expr, gchar *symbol, struct worker
                                g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
                        }
                }
+               else if (it->type == EXPR_STR) {
+                       /* This may be lua function, try to call it */
+                       cur = maybe_call_lua_function ((const gchar*)it->content.operand, task);
+                       debug_task ("function %s returned %s", (const gchar *)it->content.operand, cur ? "true" : "false");
+                       if (try_optimize) {
+                               try_optimize = optimize_regexp_expression (&it, stack, cur);
+                       }
+                       else {
+                               g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
+                       }
+               }
                else if (it->type == EXPR_REGEXP) {
                        /* Compile regexp if it is not parsed */
                        if (it->content.operand == NULL) {