From: Vsevolod Stakhov Date: Wed, 25 Jun 2008 11:17:06 +0000 (+0400) Subject: * Add C api for calling perl filters X-Git-Tag: 0.2.7~396 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=eab76d300da4e6d5712efd1db68e40cb1fc86a2c;p=rspamd.git * Add C api for calling perl filters --- 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 +#include +#include +#include +#include +#include + +#include + +#include /* from the Perl distribution */ +#include /* 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 +#include + +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);