aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2008-06-25 15:17:06 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2008-06-25 15:17:06 +0400
commiteab76d300da4e6d5712efd1db68e40cb1fc86a2c (patch)
treea0e70a513d4bb4b297e9f7114de246ad0c45a44b
parent5c04a3b81677258da055dd686a21faf2896fa145 (diff)
downloadrspamd-eab76d300da4e6d5712efd1db68e40cb1fc86a2c.tar.gz
rspamd-eab76d300da4e6d5712efd1db68e40cb1fc86a2c.zip
* Add C api for calling perl filters
-rwxr-xr-xconfigure4
-rw-r--r--main.h10
-rw-r--r--perl.c163
-rw-r--r--perl.h15
-rw-r--r--worker.c12
5 files changed, 200 insertions, 4 deletions
diff --git a/configure b/configure
index 472b4c4bd..7748a2daf 100755
--- 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 9ed0bc2ec..3eaad29c5 100644
--- 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
index 000000000..78a2c7670
--- /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
index 000000000..6f74cae29
--- /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
diff --git a/worker.c b/worker.c
index 0409f5c43..c9ed1f9f4 100644
--- 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);