dovecot-2.0-pigeonhole: LDA Sieve plugin: started using Dovecot ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Wed Dec 1 01:46:40 EET 2010


details:   http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/0171171e8e83
changeset: 1449:0171171e8e83
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Dec 01 00:46:31 2010 +0100
description:
LDA Sieve plugin: started using Dovecot reject API.

diffstat:

 TODO                                     |    4 +-
 src/lib-sieve/ext-reject.c               |  115 +----------------------------
 src/lib-sieve/sieve-actions.c            |  139 ++++++++++++++++++++++++++++++++++
 src/lib-sieve/sieve-actions.h            |    8 ++
 src/lib-sieve/sieve-types.h              |    4 +
 src/plugins/lda-sieve/lda-sieve-plugin.c |   14 +++-
 6 files changed, 167 insertions(+), 117 deletions(-)

diffs (truncated from 404 to 300 lines):

diff -r 006a0afb7e73 -r 0171171e8e83 TODO
--- a/TODO	Wed Dec 01 00:34:47 2010 +0100
+++ b/TODO	Wed Dec 01 00:46:31 2010 +0100
@@ -2,11 +2,11 @@
 
 * Build a sieve tool to filter an entire existing mailbox through a Sieve 
   script.
+* Finish the ereject extension
+	- Make reject/ereject use the LDA reject interface when available
 
 Next (in order of descending priority/precedence):
 
-* Finish the ereject extension
-	- Make reject/ereject use the LDA reject interface when available
 * Improve error handling. 
 	- Implement dropping errors in the user's mailbox as a mail message.
 * Add normalize() method to comparators to normalize the string before matching
diff -r 006a0afb7e73 -r 0171171e8e83 src/lib-sieve/ext-reject.c
--- a/src/lib-sieve/ext-reject.c	Wed Dec 01 00:34:47 2010 +0100
+++ b/src/lib-sieve/ext-reject.c	Wed Dec 01 00:46:31 2010 +0100
@@ -383,119 +383,6 @@
 	*keep = FALSE;
 }
 
-/* FIXME: use LDA reject interface when available */
-
-static bool act_reject_send	
-(const struct sieve_action_exec_env *aenv, struct act_reject_context *ctx,
-	const char *sender, const char *recipient)
-{
-	const struct sieve_script_env *senv = aenv->scriptenv;
-	const struct sieve_message_data *msgdata = aenv->msgdata;
-	struct istream *input;
-	void *smtp_handle;
-	struct message_size hdr_size;
-	FILE *f;
-	const char *new_msgid, *boundary;
-	const unsigned char *data;
-	const char *header;
-	size_t size;
-	int ret;
-
-	/* Just to be sure */
-	if ( !sieve_smtp_available(senv) ) {
-		sieve_result_global_warning
-			(aenv, "reject action has no means to send mail");
-		return TRUE;
-	}
-
-	smtp_handle = sieve_smtp_open(senv, sender, NULL, &f);
-
-	new_msgid = sieve_message_get_new_id(senv);
-	boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname);
-
-	rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
-	rfc2822_header_field_write(f, "Message-ID", new_msgid);
-	rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
-	rfc2822_header_field_printf(f, "From", "Mail Delivery Subsystem <%s>",
-		senv->postmaster_address);
-	rfc2822_header_field_printf(f, "To", "<%s>", sender);
-	rfc2822_header_field_write(f, "Subject", "Automatically rejected mail");
-	rfc2822_header_field_write(f, "Auto-Submitted", "auto-replied (rejected)");
-	rfc2822_header_field_write(f, "Precedence", "bulk");
-	
-	rfc2822_header_field_write(f, "MIME-Version", "1.0");
-	rfc2822_header_field_printf(f, "Content-Type", 
-		"multipart/report; report-type=disposition-notification;\n"
-		"boundary=\"%s\"", boundary);
-	
-	fprintf(f, "\r\nThis is a MIME-encapsulated message\r\n\r\n");
-
-	/* Human readable status report */
-	fprintf(f, "--%s\r\n", boundary);
-	fprintf(f, "Content-Type: text/plain; charset=utf-8\r\n");
-	fprintf(f, "Content-Disposition: inline\r\n");
-	fprintf(f, "Content-Transfer-Encoding: 8bit\r\n\r\n");
-
-	/* FIXME: var_expand_table expansion not possible */
-	fprintf(f, "Your message to <%s> was automatically rejected:\r\n"	
-		"%s\r\n", recipient, ctx->reason);
-
-	/* MDN status report */
-	fprintf(f, "--%s\r\n"
-		"Content-Type: message/disposition-notification\r\n\r\n", boundary);
-	fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
-		senv->hostname);
-	if (mail_get_first_header(msgdata->mail, "Original-Recipient", &header) > 0)
-		fprintf(f, "Original-Recipient: rfc822; %s\r\n", header);
-	fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
-
-	if ( msgdata->id != NULL )
-		fprintf(f, "Original-Message-ID: %s\r\n", msgdata->id);
-	fprintf(f, "Disposition: "
-		"automatic-action/MDN-sent-automatically; deleted\r\n");
-	fprintf(f, "\r\n");
-
-	/* original message's headers */
-	fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary);
-
-	if (mail_get_stream(msgdata->mail, &hdr_size, NULL, &input) == 0) {
-		/* Note: If you add more headers, they need to be sorted.
-		 * We'll drop Content-Type because we're not including the message
-		 * body, and having a multipart Content-Type may confuse some
-		 * MIME parsers when they don't see the message boundaries. 
-		 */
-		static const char *const exclude_headers[] = {
-			"Content-Type"
-		};
-
-		input = i_stream_create_header_filter(input,
-			HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, 
-			exclude_headers, N_ELEMENTS(exclude_headers), 
-			null_header_filter_callback, NULL);
-
-		while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
-			if (fwrite(data, size, 1, f) == 0)
-				break;
-			i_stream_skip(input, size);
-		}
-		i_stream_unref(&input);
-			
-		i_assert(ret != 0);
-	}
-
-	fprintf(f, "\r\n\r\n--%s--\r\n", boundary);
-
-	if ( !sieve_smtp_close(senv, smtp_handle) ) {
-		sieve_result_global_error(aenv,
-			"failed to send rejection message to <%s> "
-			"(refer to server log for more information)",
-			str_sanitize(sender, 80));
-		return FALSE;
-	}
-	
-	return TRUE;
-}
-
 static bool act_reject_commit
 (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, 
 	void *tr_context ATTR_UNUSED, bool *keep)
@@ -526,7 +413,7 @@
 		return TRUE;
 	}
 		
-	if ( act_reject_send(aenv, rj_ctx, sender, recipient) ) {
+	if ( sieve_action_reject_mail(aenv, sender, recipient, rj_ctx->reason) ) {
 		sieve_result_global_log(aenv, 
 			"rejected message from <%s> (%s)", str_sanitize(sender, 80),
 			( rj_ctx->ereject ? "ereject" : "reject" ));
diff -r 006a0afb7e73 -r 0171171e8e83 src/lib-sieve/sieve-actions.c
--- a/src/lib-sieve/sieve-actions.c	Wed Dec 01 00:34:47 2010 +0100
+++ b/src/lib-sieve/sieve-actions.c	Wed Dec 01 00:46:31 2010 +0100
@@ -4,10 +4,18 @@
 #include "lib.h"
 #include "str.h"
 #include "strfuncs.h"
+#include "ioloop.h"
+#include "hostpid.h"
 #include "str-sanitize.h"
 #include "unichar.h"
+#include "istream.h"
+#include "istream-header-filter.h"
 #include "mail-deliver.h"
 #include "mail-storage.h"
+#include "message-date.h"
+#include "message-size.h"
+
+#include "rfc2822.h"
 
 #include "sieve-code.h"
 #include "sieve-extensions.h"
@@ -16,6 +24,8 @@
 #include "sieve-dump.h"
 #include "sieve-result.h"
 #include "sieve-actions.h"
+#include "sieve-message.h"
+#include "sieve-smtp.h"
 
 #include <ctype.h>
 
@@ -679,6 +689,8 @@
  * Action utility functions
  */
 
+/* Checking for duplicates */
+
 bool sieve_action_duplicate_check_available
 (const struct sieve_script_env *senv)
 {
@@ -705,5 +717,132 @@
 	senv->duplicate_mark
 		(senv->script_context, id, id_size, senv->username, time);
 }
+
+/* Rejecting the mail */
+
+static bool sieve_action_do_reject_mail
+(const struct sieve_action_exec_env *aenv, const char *sender, 
+	const char *recipient, const char *reason)
+{
+	const struct sieve_script_env *senv = aenv->scriptenv;
+	const struct sieve_message_data *msgdata = aenv->msgdata;
+	struct istream *input;
+	void *smtp_handle;
+	struct message_size hdr_size;
+	FILE *f;
+	const char *new_msgid, *boundary;
+	const unsigned char *data;
+	const char *header;
+	size_t size;
+	int ret;
+
+	/* Just to be sure */
+	if ( !sieve_smtp_available(senv) ) {
+		sieve_result_global_warning
+			(aenv, "reject action has no means to send mail");
+		return TRUE;
+	}
+
+	smtp_handle = sieve_smtp_open(senv, sender, NULL, &f);
+
+	new_msgid = sieve_message_get_new_id(senv);
+	boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname);
+
+	rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
+	rfc2822_header_field_write(f, "Message-ID", new_msgid);
+	rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
+	rfc2822_header_field_printf(f, "From", "Mail Delivery Subsystem <%s>",
+		senv->postmaster_address);
+	rfc2822_header_field_printf(f, "To", "<%s>", sender);
+	rfc2822_header_field_write(f, "Subject", "Automatically rejected mail");
+	rfc2822_header_field_write(f, "Auto-Submitted", "auto-replied (rejected)");
+	rfc2822_header_field_write(f, "Precedence", "bulk");
+	
+	rfc2822_header_field_write(f, "MIME-Version", "1.0");
+	rfc2822_header_field_printf(f, "Content-Type", 
+		"multipart/report; report-type=disposition-notification;\n"
+		"boundary=\"%s\"", boundary);
+	
+	fprintf(f, "\r\nThis is a MIME-encapsulated message\r\n\r\n");
+
+	/* Human readable status report */
+	fprintf(f, "--%s\r\n", boundary);
+	fprintf(f, "Content-Type: text/plain; charset=utf-8\r\n");
+	fprintf(f, "Content-Disposition: inline\r\n");
+	fprintf(f, "Content-Transfer-Encoding: 8bit\r\n\r\n");
+
+	fprintf(f, "Your message to <%s> was automatically rejected:\r\n"	
+		"%s\r\n", recipient, reason);
+
+	/* MDN status report */
+	fprintf(f, "--%s\r\n"
+		"Content-Type: message/disposition-notification\r\n\r\n", boundary);
+	fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
+		senv->hostname);
+	if (mail_get_first_header(msgdata->mail, "Original-Recipient", &header) > 0)
+		fprintf(f, "Original-Recipient: rfc822; %s\r\n", header);
+	fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
+
+	if ( msgdata->id != NULL )
+		fprintf(f, "Original-Message-ID: %s\r\n", msgdata->id);
+	fprintf(f, "Disposition: "
+		"automatic-action/MDN-sent-automatically; deleted\r\n");
+	fprintf(f, "\r\n");
+
+	/* original message's headers */
+	fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary);
+
+	if (mail_get_stream(msgdata->mail, &hdr_size, NULL, &input) == 0) {
+		/* Note: If you add more headers, they need to be sorted.
+		 * We'll drop Content-Type because we're not including the message
+		 * body, and having a multipart Content-Type may confuse some
+		 * MIME parsers when they don't see the message boundaries. 
+		 */
+		static const char *const exclude_headers[] = {
+			"Content-Type"
+		};
+
+		input = i_stream_create_header_filter(input,
+			HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, 
+			exclude_headers, N_ELEMENTS(exclude_headers), 
+			null_header_filter_callback, NULL);
+
+		while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
+			if (fwrite(data, size, 1, f) == 0)
+				break;
+			i_stream_skip(input, size);
+		}
+		i_stream_unref(&input);
+			
+		i_assert(ret != 0);
+	}
+
+	fprintf(f, "\r\n\r\n--%s--\r\n", boundary);
+
+	if ( !sieve_smtp_close(senv, smtp_handle) ) {
+		sieve_result_global_error(aenv,
+			"failed to send rejection message to <%s> "
+			"(refer to server log for more information)",
+			str_sanitize(sender, 80));


More information about the dovecot-cvs mailing list