]> source.dussan.org Git - rspamd.git/commitdiff
* Add C api for calling perl filters
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 25 Jun 2008 11:17:06 +0000 (15:17 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 25 Jun 2008 11:17:06 +0000 (15:17 +0400)
configure
main.h
perl.c [new file with mode: 0644]
perl.h [new file with mode: 0644]
worker.c

index 472b4c4bd813d632e480dc3a1e4473318a752862..7748a2daf2070a0fc28f6cc2959cccfd5e7e0e74 100755 (executable)
--- a/configure
+++ b/configure
@@ -20,7 +20,7 @@ LEX_SRC="cfg_file.l"
 YACC_OUTPUT="cfg_yacc.c"
 LEX_OUTPUT="cfg_lex.c"
 
-SOURCES="upstream.c cfg_utils.c memcached.c main.c util.c worker.c fstring.c url.c ${LEX_OUTPUT} ${YACC_OUTPUT}"
+SOURCES="upstream.c cfg_utils.c memcached.c main.c util.c worker.c fstring.c url.c perl.c ${LEX_OUTPUT} ${YACC_OUTPUT}"
 
 CFLAGS="$CFLAGS -W -Wpointer-arith -Wno-unused-parameter"
 CFLAGS="$CFLAGS -Wno-unused-function -Wunused-variable -Wno-sign-compare"
@@ -28,7 +28,7 @@ CFLAGS="$CFLAGS -Wunused-value -ggdb -I${LOCALBASE}/include"
 CFLAGS="$CFLAGS "
 LDFLAGS="$LDFLAGS -L/usr/lib -L${LOCALBASE}/lib"
 OPT_FLAGS="-O -pipe -fno-omit-frame-pointer"
-DEPS="cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h ${LEX_OUTPUT} ${YACC_OUTPUT}"
+DEPS="cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h perl.h ${LEX_OUTPUT} ${YACC_OUTPUT}"
 EXEC=rspamd
 USER=postfix
 GROUP=postfix
diff --git a/main.h b/main.h
index 9ed0bc2ecc47b4964b4fa88d2ee1f25ba271c7c0..3eaad29c558e169f93dbb6d59183a0732e751285 100644 (file)
--- a/main.h
+++ b/main.h
@@ -51,6 +51,7 @@ struct rspamd_worker {
 
 struct pidfh;
 struct config_file;
+struct filter_chain;
 
 /* Struct that determine main server object (for logging purposes) */
 struct rspamd_main {
@@ -64,6 +65,13 @@ struct rspamd_main {
        TAILQ_HEAD (workq, rspamd_worker) workers;
 };
 
+struct filter_result {
+       const char *symbol;
+       struct filter_chain *chain;
+       int mark;
+       TAILQ_ENTRY (filter_result) next;
+};
+
 struct worker_task {
        struct rspamd_worker *worker;
        enum {
@@ -80,6 +88,8 @@ struct worker_task {
        int parts_count;
        /* URLs extracted from message */
        TAILQ_HEAD (uriq, uri) urls;
+       /* List of filter results */
+       TAILQ_HEAD (resultsq, filter_result) results;
 };
 
 void start_worker (struct rspamd_worker *worker, int listen_sock);
diff --git a/perl.c b/perl.c
new file mode 100644 (file)
index 0000000..78a2c76
--- /dev/null
+++ b/perl.c
@@ -0,0 +1,163 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <glib.h>
+
+#include <EXTERN.h>               /* from the Perl distribution     */
+#include <perl.h>                 /* from the Perl distribution     */
+
+#include "url.h"
+#include "main.h"
+#include "perl.h"
+
+extern PerlInterpreter *my_perl;
+
+int
+call_header_filter (const char *function, const char *header_name, const char *header_value)
+{
+       int result;
+       dSP;
+
+       ENTER;
+       SAVETMPS;
+
+       PUSHMARK (SP);
+       XPUSHs (sv_2mortal (newSVpv (header_name, 0)));
+       XPUSHs (sv_2mortal (newSVpv (header_value, 0)));
+       PUTBACK;
+       
+       call_pv (function, G_SCALAR);
+
+       SPAGAIN;
+
+       result = POPi;
+       msg_debug ("header_filter: call of %s with header %s returned mark %d\n", function, header_name, result);
+
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+
+       return result;
+}
+
+int
+call_mime_filter (const char *function, GByteArray *content)
+{
+       int result;
+       dSP;
+
+       ENTER;
+       SAVETMPS;
+
+       PUSHMARK (SP);
+       XPUSHs (sv_2mortal (newSVpv (content->data, content->len)));
+       PUTBACK;
+       
+       call_pv (function, G_SCALAR);
+
+       SPAGAIN;
+
+       result = POPi;
+       msg_debug ("mime_filter: call of %s returned mark %d\n", function, result);
+
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+
+       return result;
+}
+
+int
+call_message_filter (const char *function, GByteArray *content)
+{
+       int result;
+       dSP;
+
+       ENTER;
+       SAVETMPS;
+
+       PUSHMARK (SP);
+       XPUSHs (sv_2mortal (newSVpv (content->data, content->len)));
+       PUTBACK;
+       
+       call_pv (function, G_SCALAR);
+
+       SPAGAIN;
+
+       result = POPi;
+       msg_debug ("message_filter: call of %s returned mark %d\n", function, result);
+
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+
+       return result;
+}
+
+int
+call_url_filter (const char *function, struct uri *uri)
+{
+       int result;
+       dSP;
+
+       ENTER;
+       SAVETMPS;
+       
+       /* URL:
+        * url,
+        * host,
+        * data
+        */
+       PUSHMARK (SP);
+       XPUSHs (sv_2mortal (newSVpv (uri->string, 0)));
+       XPUSHs (sv_2mortal (newSVpv (uri->host, uri->hostlen)));
+       XPUSHs (sv_2mortal (newSVpv (uri->data, uri->datalen)));
+       PUTBACK;
+       
+       call_pv (function, G_SCALAR);
+
+       SPAGAIN;
+
+       result = POPi;
+       msg_debug ("url_filter: call of %s for url '%s' returned mark %d\n", function, uri->string, result);
+
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+
+       return result;
+}
+
+int
+call_chain_filter (const char *function, GArray *results)
+{
+       int result, i;
+
+       dSP;
+
+       ENTER;
+       SAVETMPS;
+       PUSHMARK (SP);
+       for (i = 0; i < results->len; i ++) {
+               XPUSHs (sv_2mortal (newSViv (g_array_index (results, int, i))));
+       }
+       PUTBACK;
+       
+       call_pv (function, G_SCALAR);
+
+       SPAGAIN;
+
+       result = POPi;
+       msg_debug ("chain_filter: call of %s returned mark %d\n", function, result);
+
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+
+
+       return result;
+}
diff --git a/perl.h b/perl.h
new file mode 100644 (file)
index 0000000..6f74cae
--- /dev/null
+++ b/perl.h
@@ -0,0 +1,15 @@
+#ifndef RSPAM_PERL_H
+#define RSPAM_PERL_H
+
+#include <sys/types.h>
+#include <glib.h>
+
+struct uri;
+
+int call_header_filter (const char *function, const char *header_name, const char *header_value);
+int call_mime_filter (const char *function, GByteArray *content);
+int call_message_filter (const char *function, GByteArray *content);
+int call_url_filter (const char *function, struct uri *uri);
+int call_chain_filter (const char *function, GArray *results);
+
+#endif
index 0409f5c43ae1819bfe98580a3ee1713792907dfa..c9ed1f9f427550f1387902c0ccd47998631d9b6c 100644 (file)
--- a/worker.c
+++ b/worker.c
@@ -67,17 +67,24 @@ static void
 free_task (struct worker_task *task)
 {
        struct uri *cur;
+       struct filter_result *res;
+
        if (task) {
                if (task->msg) {
                        fstrfree (task->msg->buf);
                        free (task->msg);
                }
-               while (!TAILQ_EMPTY(&task->urls)) {
-                       cur = TAILQ_FIRST(&task->urls);
+               while (!TAILQ_EMPTY (&task->urls)) {
+                       cur = TAILQ_FIRST (&task->urls);
                        free (cur->string);
                        free (cur);
                        TAILQ_REMOVE (&task->urls, cur, next);
                }
+               while (!TAILQ_EMPTY (&task->results)) {
+                       res = TAILQ_FIRST (&task->results);
+                       free (res);
+                       TAILQ_REMOVE (&task->results, res, next);
+               }
                free (task);
        }
 }
@@ -303,6 +310,7 @@ accept_socket (int fd, short what, void *arg)
        new_task->content_length = 0;
        new_task->parts_count = 0;
        TAILQ_INIT (&new_task->urls);
+       TAILQ_INIT (&new_task->results);
 
        /* Read event */
        new_task->bev = bufferevent_new (nfd, read_socket, write_socket, err_socket, (void *)new_task);