Johannes Berg wrote:
> Hi,

Hello,

>> If you're building against libdspam you can't define -DHAVE_CONFIG_H or dspam
>> will look for its own dpsam config.h.
>
> Hah. Hmm we can do some makefile tricks to only define that for
> antispam-plugin.c rather than the backends.

This would be a workaround but not really nice. What about reading the output
of dovecot --version and adding it.

I've updated the plugin it should work now. The problem is that it always
fails for me. It makes no difference if I use the dpsam-exec or dspam-library
backend. It looks like call_dspam() is never called.

It reports "Failed to call dspam". I've added a debug message at the beginning
of call_dspam() and it gets never displayed.

>
> johannes

        -- andreas


-- 
http://www.cynapses.org/ - cybernetic synapses

diff --git a/Makefile b/Makefile
index 5f1e362..dca50d0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 -include .config
 
 # includes/flags we need for building a dovecot plugin
-CFLAGS += -DHAVE_CONFIG_H
+CFLAGS += $(DOVECOT_CFLAGS)
 CFLAGS += -I$(DOVECOT)/
 CFLAGS += -I$(DOVECOT)/src/
 CFLAGS += -I$(DOVECOT)/src/lib/
@@ -44,6 +44,12 @@ endif
 ifeq ("$(BACKEND)", "dspam-exec")
 objs += signature.o
 endif
+ifeq ("$(BACKEND)", "dspam-library")
+CFLAGS += -I$(DSPAM)/
+CFLAGS += -DLOGDIR=$(DSPAM_LOGDIR) -DCONFIG_DEFAULT=$(DSPAM_CONFIG)
+LDFLAGS += -ldspam
+objs += signature.o
+endif
 ifeq ("$(BACKEND)", "signature-log")
 objs += signature.o
 endif
diff --git a/README b/README
index 328ef0f..a0a73ea 100644
--- a/README
+++ b/README
@@ -69,6 +69,10 @@ BACKENDS
          (2) when many users retrain many messages at once server load may
              spike
 
+    dspam library backend (dspam specific)
+
+        This backend instantly retrains by calling dspam trough libdspam.
+
     email sender backend (spam filter agnostic)
 
         This backend sends mail to [EMAIL PROTECTED] or [EMAIL PROTECTED]
@@ -127,6 +131,13 @@ CONFIGURATION
         # antispam_dspam_args = --user;%u  # % expansion done by dovecot
         # antispam_dspam_args = --mode=teft
 
+        #===================
+        # dspam-library plugin
+
+        # dspam home
+        # The data directory of dspam
+        antispam_dspam_home = /var/lib/dspam
+
         #=====================
         # mail sending plugin
 
diff --git a/antispam-plugin.c b/antispam-plugin.c
index ea7e426..876e5c9 100644
--- a/antispam-plugin.c
+++ b/antispam-plugin.c
@@ -139,4 +139,6 @@ void antispam_plugin_deinit(void)
 }
 
 /* put dovecot version we built against into plugin for checking */
-const char *antispam_plugin_version = PACKAGE_VERSION;
+#ifdef HAVE_CONFIG_H
+const char *antispam_plugin_version"1.0.5";
+#endif
diff --git a/defconfig b/defconfig
index 31348dd..42e3f4b 100644
--- a/defconfig
+++ b/defconfig
@@ -17,18 +17,30 @@
 # point DOVECOT= to the installed headers too.
 DOVECOT=../dovecot-1.0.5
 #DOVECOT=../dovecot-1.1
+
+# Buliding in source
+DOVECOT_CFLAGS=-DHAVE_CONFIG_H
+
 #DOVECOT=/usr/include/dovecot
+# Buliding out of source
+#DOVECOT_CFLAGS=-DUOFF_T_LONG -DHAVE_SOCKLEN_T -DHAVE_STRUCT_IOVEC
 
 # Dovecot version to build against
 DOVECOT_VERSION=1.0
 #DOVECOT_VERSION=1.1	# CURRENTLY BROKEN
 
+# DSPAM header directory
+#DSPAM=/usr/include/dspam
+#DSPAM_LOGDIR=/var/log/dspam
+#DSPAM_CONFIG=/etc/dspam.conf
+
 # backend
 #  dspam-exec		- direct dspam training by calling dspam executable
 #  signature-log	- signature logging using dovecot's dict API
 #  mailtrain		- send mail to special addresses for training
 #  crm114-exec		- direct crm114 training by calling mailreaver.crm
 #BACKEND=dspam-exec
+#BACKEND=dspam-library
 #BACKEND=signature-log
 #BACKEND=mailtrain
 #BACKEND=crm114-exec
diff --git a/dspam-library.c b/dspam-library.c
new file mode 100644
index 0000000..b942532
--- /dev/null
+++ b/dspam-library.c
@@ -0,0 +1,146 @@
+/*
+ * dspam backend for dovecot antispam plugin
+ *
+ * Copyright (C) 2004-2007  Johannes Berg <[EMAIL PROTECTED]>
+ *                    2006  Frank Cusack
+ *                    2007  Andreas Schneider <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <stdlib.h>
+#include <libdspam.h>
+
+#include "lib.h"
+#include "mail-storage-private.h"
+
+#include "antispam-plugin.h"
+#include "signature.h"
+
+static const char *dspam_home = "/var/lib/dspam";
+
+static int call_dspam(const char *signature, enum classification wanted)
+{
+	dspam_init_driver (NULL);
+
+	DSPAM_CTX *ctx;
+	char *user_env = NULL;
+
+	user_env = getenv("USER");
+	ctx = dspam_init(user_env, NULL, "/var/lib/dspam", DSM_PROCESS, DSF_SIGNATURE);
+
+	if (ctx == NULL) {
+		debug("dspam_init failed!");
+		return -1;
+	}
+
+	/* Set up the context for error correction */
+	ctx->source = DSS_ERROR;
+
+	/* Reclassify the message  */
+	switch (wanted) {
+		case CLASS_SPAM:
+			ctx->classification = DSR_ISSPAM;
+			break;
+		case CLASS_NOTSPAM:
+			ctx->classification = DSR_ISINNOCENT;
+			break;
+	}
+
+	/* Use graham and robinson algorithms, graham's p-values */
+	ctx->algorithms = DSA_GRAHAM | DSA_BURTON | DSP_GRAHAM;
+
+	/* Attach the signature to the context */
+	if (_ds_set_signature(ctx, ctx->signature, signature)) {
+		debug("_ds_set_signature failed!");
+		return -1;
+	}
+
+	/* Call DSPAM */
+	debug("Calling dspam for signature %s with error %s.", signature, wanted == CLASS_SPAM  ? "Spam" : "Innocent");
+	if (dspam_process(ctx, NULL) != 0) {
+		debug("dspam_process failed");
+		return -1;
+	}
+
+	/* Destroy the context */
+	dspam_destroy(ctx);
+
+	dspam_shutdown_driver(NULL);
+	return 0;
+}
+
+struct antispam_transaction_context {
+	struct siglist *siglist;
+};
+
+struct antispam_transaction_context *backend_start(struct mailbox *box)
+{
+	struct antispam_transaction_context *ast;
+
+	ast = i_new(struct antispam_transaction_context, 1);
+	ast->siglist = NULL;
+	return ast;
+}
+
+void backend_rollback(struct antispam_transaction_context *ast)
+{
+	signature_list_free(&ast->siglist);
+	i_free(ast);
+}
+
+int backend_commit(struct mailbox_transaction_context *ctx,
+		   struct antispam_transaction_context *ast)
+{
+	struct siglist *item = ast->siglist;
+	int ret = 0;
+
+	while (item) {
+		if (call_dspam(item->sig, item->wanted)) {
+			ret = -1;
+			mail_storage_set_error(ctx->box->storage,
+					       "Failed to call dspam");
+			break;
+		}
+		item = item->next;
+	}
+
+	signature_list_free(&ast->siglist);
+	i_free(ast);
+	return ret;
+}
+
+int backend_handle_mail(struct mailbox_transaction_context *t,
+			struct antispam_transaction_context *ast,
+			struct mail *mail, enum classification want)
+{
+	return signature_extract_to_list(t, mail, &ast->siglist, want);
+}
+
+void backend_init(pool_t pool)
+{
+	char *tmp;
+
+	tmp = getenv("ANTISPAM_DSPAM_HOME");
+	if (tmp) {
+		dspam_home = tmp;
+		debug("antispam: dspam home set to %s\n", tmp);
+	}
+
+	signature_init();
+}
+
+void backend_exit(void)
+{
+}

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to