dovecot-2.0-pigeonhole: Sieve-filter: implemented basic filterin...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sat Oct 16 22:20:08 EEST 2010


details:   http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/e6427895c197
changeset: 1441:e6427895c197
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sat Oct 16 21:19:51 2010 +0200
description:
Sieve-filter: implemented basic filtering with source mailbox actions.

diffstat:

 doc/man/sieve-filter.1.in      |   58 ++++++++++---------
 src/sieve-tools/sieve-filter.c |  115 ++++++++++++++++++++++++--------------
 2 files changed, 102 insertions(+), 71 deletions(-)

diffs (truncated from 303 to 300 lines):

diff -r a50464354f5a -r e6427895c197 doc/man/sieve-filter.1.in
--- a/doc/man/sieve-filter.1.in	Fri Oct 01 19:04:32 2010 +0200
+++ b/doc/man/sieve-filter.1.in	Sat Oct 16 21:19:51 2010 +0200
@@ -14,6 +14,7 @@
 .RI [ options ]
 .I script\-file
 .I source\-mailbox
+.RI [ source\-action ]
 .SH DESCRIPTION
 .PP
 The \fBsieve\-filter\fP command is part of the Pigeonhole Project
@@ -88,34 +89,6 @@
 option outgoing messages can be fed to the \fBstdin\fP of an external shell
 command. This option has no effect in simulation mode. Unless you really know
 what you are doing, \fBDO NOT USE THIS TO FEED MAIL TO SENDMAIL!\fP.
-.TP 
-.BI \-R\  source\-action
-Specifies what needs to be done with messages in the source mailbox once
-processed by the Sieve script. By default, the sieve\-filter command does not
-remove the messages from the source mailbox. In particular this means that the
-keep and fileinto actions will cause the messages to be copied. To alter this
-behavior, the \fIsource\-action\fP parameter of the \fB\-R\fP option accepts
-one of the following values:
-.RS 7
-.TP 
-\fBkeep\fP (default)
-Keep processed messages in source folder. If \fB\-W\fR is specified and the
-source mailbox is the destination of a keep or fileinto action, flags may be
-changed by the Sieve script, but messages are never duplicated there. 
-.TP 
-\fBflag\fP
-Flag processed messages as \\DELETED.
-.TP 
-\fBmove\fP [\fIfolder\fP]
-Move processed messages to the indicated \fIfolder\fP.
-.TP 
-\fBexpunge\fP
-Expunge processed messages, meaning that these are removed irreversibly when the
-tool finishes filtering.
-.PP
-Note that the chosen \fIsource\-action\fP only has an effect on the source
-mailbox when the \fB\-W\fP option is specified as well.
-.RE
 .TP
 .BI \-s\  script\-file
 Specify additional scripts to be executed before the main script. Multiple
@@ -157,6 +130,35 @@
 .TP
 .I source\-mailbox
 The name of the source mailbox.
+.TP 
+.I source\-action
+Specifies what needs to be done with messages in the source mailbox once
+processed by the Sieve script. By default, the sieve\-filter command does not
+remove the messages from the source mailbox. In particular this means that the
+keep and fileinto actions will cause the messages to be copied. To alter this
+behavior, the \fIsource\-action\fP parameter of the \fB\-R\fP option accepts
+one of the following values:
+.RS 7
+.TP 
+.BR keep\  (default)
+Keep processed messages in source folder. If \fB\-W\fR is specified and the
+source mailbox is the destination of a keep or fileinto action, flags may be
+changed by the Sieve script, but messages are never duplicated there. 
+.TP 
+.BI move\  folder
+Move processed messages to the indicated \fIfolder\fP.
+.TP 
+.B delete
+Flag processed messages as \\DELETED.
+.TP 
+.B expunge
+Expunge processed messages, meaning that these are removed irreversibly when the
+tool finishes filtering.
+.PP
+Note that the chosen \fIsource\-action\fP only has an effect on the source
+mailbox when the \fB\-W\fP option is specified as well.
+.RE
+
 .\"------------------------------------------------------------------------
 
 .SH EXAMPLES
diff -r a50464354f5a -r e6427895c197 src/sieve-tools/sieve-filter.c
--- a/src/sieve-tools/sieve-filter.c	Fri Oct 01 19:04:32 2010 +0200
+++ b/src/sieve-tools/sieve-filter.c	Sat Oct 16 21:19:51 2010 +0200
@@ -35,33 +35,33 @@
 static void print_help(void)
 {
 	printf(
-"Usage: sieve-filter [-m <mailbox>] [-x <extensions>] [-s <script-file>] [-c]\n"
-"                    <script-file> <src-mail-store> [<dest-mail-store>]\n"
-"Usage: sieve-filter [-c <config-file>] [-C] [-D] [-e]\n"
-"                  [-m <default-mailbox>] [-P <plugin>]\n"
-"                  [-r <recipient-address>] [-s <script-file>]\n"
-"                  [-t <trace-file>] [-T <trace-option>] [-x <extensions>]\n"
-"                  <script-file> <mail-file>\n"
+"Usage: sieve-filter [-c <config-file>] [-C] [-D] [-e] [-m <default-mailbox>]\n"
+"                    [-P <plugin>] [-q <output-mailbox>] [-Q <mail-command>]\n"
+"                    [-s <script-file>] [-u <user>] [-W] [-x <extensions>]\n"
+"                    <script-file> <source-mailbox> <source-action>\n"
 	);
 }
 
-enum source_action_type {
-	SOURCE_ACTION_KEEP,            /* Always keep messages in source folder */ 
-	SOURCE_ACTION_DELETE,          /* Flag discarded messages as \DELETED */
-	SOURCE_ACTION_TRASH_FOLDER,    /* Move discarded messages to Trash folder */      
-	SOURCE_ACTION_EXPUNGE          /* Expunge discarded messages */
+enum sieve_filter_source_action {
+	SIEVE_FILTER_SACT_KEEP,          /* Always keep messages in source folder */ 
+	SIEVE_FILTER_SACT_MOVE,          /* Move discarded messages to Trash folder */      
+	SIEVE_FILTER_SACT_DELETE,        /* Flag discarded messages as \DELETED */
+	SIEVE_FILTER_SACT_EXPUNGE        /* Expunge discarded messages */
 };
 
-struct source_action {
-	enum source_action_type type;
-	const char *trash_folder;
+struct sieve_filter_context {
+	enum sieve_filter_source_action source_action;
+	const char *move_mailbox;
+
+	struct sieve_script_env *senv;
+	struct sieve_binary *main_sbin;
+	struct sieve_error_handler *ehandler;
 };
 
 static int filter_message
-(struct mail *mail, struct sieve_binary *main_sbin, 
-	struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	struct source_action source_action)
+(struct sieve_filter_context *sfctx, struct mail *mail)
 {
+	struct sieve_error_handler *ehandler = sfctx->ehandler; 
 	struct sieve_exec_status estatus;
 	struct sieve_binary *sbin;
 	struct sieve_message_data msgdata;
@@ -72,7 +72,7 @@
 
 	/* Initialize execution status */
 	memset(&estatus, 0, sizeof(estatus));
-	senv->exec_status = &estatus;
+	sfctx->senv->exec_status = &estatus;
 
 	/* Collect necessary message data */
 	memset(&msgdata, 0, sizeof(msgdata));
@@ -80,37 +80,35 @@
 	msgdata.return_path = sender;
 	msgdata.orig_envelope_to = recipient;
 	msgdata.final_envelope_to = recipient;
-	msgdata.auth_user = senv->username;
+	msgdata.auth_user = sfctx->senv->username;
 	(void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
 
 	/* Single script */
-	sbin = main_sbin;
-	main_sbin = NULL;
+	sbin = sfctx->main_sbin;
 
 	/* Execute script */
-	ret = sieve_execute(sbin, &msgdata, senv, ehandler, NULL);
+	ret = sieve_execute(sbin, &msgdata, sfctx->senv, ehandler, NULL);
 
 	/* Handle message in source folder */
 	if ( ret > 0 && !estatus.keep_original ) {
-		switch ( source_action.type ) {
+		switch ( sfctx->source_action ) {
 		/* Leave it there */
-		case SOURCE_ACTION_KEEP:
+		case SIEVE_FILTER_SACT_KEEP:
 			sieve_info(ehandler, NULL, "message left in source mailbox");
 			break;
+		/* Move message to Trash folder */
+		case SIEVE_FILTER_SACT_MOVE:			
+			sieve_info(ehandler, NULL, 
+				"message in source mailbox moved to mailbox '%s'", sfctx->move_mailbox);
+			break;
 		/* Flag message as \DELETED */
-		case SOURCE_ACTION_DELETE:					
+		case SIEVE_FILTER_SACT_DELETE:					
 			sieve_info(ehandler, NULL, "message flagged as deleted in source mailbox");
 			mail_update_flags(mail, MODIFY_ADD, MAIL_DELETED);
 			break;
-		/* Move message to Trash folder */
-		case SOURCE_ACTION_TRASH_FOLDER:			
-			sieve_info(ehandler, NULL, 
-				"message in source folder moved to folder '%s'", 
-				source_action.trash_folder);
-			break;
 		/* Expunge the message immediately */
-		case SOURCE_ACTION_EXPUNGE:
-			sieve_info(ehandler, NULL, "message removed from source folder");
+		case SIEVE_FILTER_SACT_EXPUNGE:
+			sieve_info(ehandler, NULL, "message expunged from source mailbox");
 			mail_expunge(mail);
 			break;
 		/* Unknown */
@@ -118,6 +116,8 @@
 			i_unreached();
 			break;
 		}
+	} else {
+		sieve_info(ehandler, NULL, "message left in source mailbox");
 	}
 
 	return ret;
@@ -139,10 +139,9 @@
 }
 
 static int filter_mailbox
-(struct mailbox *src_box, struct sieve_binary *main_sbin, 
-	struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	struct source_action source_action)
+(struct sieve_filter_context *sfctx, struct mailbox *src_box)
 {
+	struct sieve_error_handler *ehandler = sfctx->ehandler;
 	struct mail_search_args *search_args;
 	struct mailbox_transaction_context *t;
 	struct mail_search_context *search_ctx;
@@ -189,7 +188,7 @@
 		sieve_info(ehandler, NULL,
 			"filtering: [%s; %"PRIuUOFF_T" bytes] %s", date, size, subject);
 	
-		ret = filter_message(mail, main_sbin, senv, ehandler, source_action);
+		ret = filter_message(sfctx, mail);
 	}
 	mail_free(&mail);
 	
@@ -235,8 +234,9 @@
 {
 	struct sieve_instance *svinst;
 	ARRAY_TYPE (const_string) scriptfiles;
-	const char *scriptfile,	*src_mailbox, *dst_mailbox;
-	struct source_action source_action = { SOURCE_ACTION_KEEP, "Trash" };
+	const char *scriptfile,	*src_mailbox, *dst_mailbox, *move_mailbox;
+	struct sieve_filter_context sfctx;
+	enum sieve_filter_source_action source_action = SIEVE_FILTER_SACT_KEEP;
 	struct mail_user *mail_user;
 	struct sieve_binary *main_sbin;
 	struct sieve_script_env scriptenv;
@@ -249,13 +249,15 @@
 	enum mail_error error;
 	int c;
 
-	sieve_tool = sieve_tool_init("sieve-filter", &argc, &argv, "m:s:x:P:CD", FALSE);
+	sieve_tool = sieve_tool_init("sieve-filter", &argc, &argv, 
+		"R:m:s:x:P:CD", FALSE);
 
 	t_array_init(&scriptfiles, 16);
 
 	/* Parse arguments */
 	scriptfile =  NULL;
 	src_mailbox = dst_mailbox = "INBOX";
+	move_mailbox = "Trash";
 	force_compile = FALSE;
 	while ((c = sieve_tool_getopt(sieve_tool)) > 0) {
 		switch (c) {
@@ -305,6 +307,26 @@
 		print_help();
 		i_fatal_status(EX_USAGE, "Missing <source-mailbox> argument");
 	}
+		
+	if ( optind < argc ) {
+		const char *srcact = argv[optind++];
+
+		if ( strcmp(srcact, "keep") == 0 ) {
+			source_action = SIEVE_FILTER_SACT_KEEP;
+		} else if ( strcmp(srcact, "move") == 0 ) {
+			source_action = SIEVE_FILTER_SACT_MOVE;
+			if ( optind < argc ) {
+				move_mailbox = t_strdup(argv[optind++]);
+			}
+		} else if ( strcmp(srcact, "flag") == 0 ) {
+			source_action = SIEVE_FILTER_SACT_DELETE;
+		} else if ( strcmp(srcact, "expunge") == 0 ) {
+			source_action = SIEVE_FILTER_SACT_EXPUNGE;
+		} else {
+			print_help();
+			i_fatal_status(EX_USAGE, "Invalid <source-action> argument");
+		}
+	} 
 
 	if ( optind != argc ) {
 		print_help();
@@ -359,9 +381,16 @@
 	scriptenv.smtp_open = NULL;
 	scriptenv.smtp_close = NULL;
 
+	/* Compose filter context */
+	memset(&sfctx, 0, sizeof(sfctx));
+	sfctx.senv = &scriptenv;
+	sfctx.source_action = source_action;
+	sfctx.move_mailbox = move_mailbox;
+	sfctx.main_sbin = main_sbin;
+	sfctx.ehandler = ehandler;
+
 	/* Apply Sieve filter to all messages found */
-	(void) filter_mailbox
-		(src_box, main_sbin, &scriptenv, ehandler, source_action);
+	(void) filter_mailbox(&sfctx, src_box);


More information about the dovecot-cvs mailing list