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"
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
struct pidfh;
struct config_file;
+struct filter_chain;
/* Struct that determine main server object (for logging purposes) */
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 {
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);
--- /dev/null
+#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;
+}
--- /dev/null
+#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
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);
}
}
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);