From 5d26995a8c27db5f64b11d7ba8a973a4af96d3a9 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Tue, 27 Nov 2007 23:42:04 +0100
Subject: [PATCH] Added :flags tag to the imapflags extension and fixed bug in
 the result execution.

---
 src/lib-sieve/plugins/copy/ext-copy.c         |  2 +-
 src/lib-sieve/plugins/imapflags/Makefile.am   |  4 ++
 .../plugins/imapflags/ext-imapflags.c         | 13 +++++-
 .../plugins/imapflags/imapflags.sieve         |  2 +
 src/lib-sieve/plugins/imapflags/tag-flags.c   | 45 +++++++++++++++++++
 src/lib-sieve/sieve-actions.c                 |  8 ++--
 src/lib-sieve/sieve-result.c                  |  6 +--
 7 files changed, 71 insertions(+), 9 deletions(-)
 create mode 100644 src/lib-sieve/plugins/imapflags/tag-flags.c

diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c
index 82ac36548..cdfca1575 100644
--- a/src/lib-sieve/plugins/copy/ext-copy.c
+++ b/src/lib-sieve/plugins/copy/ext-copy.c
@@ -57,7 +57,7 @@ static bool tag_copy_validate
 	return TRUE;
 }
 
-/* Command registration */
+/* Tag */
 
 static const struct sieve_argument copy_tag = { 
 	"copy", NULL, 
diff --git a/src/lib-sieve/plugins/imapflags/Makefile.am b/src/lib-sieve/plugins/imapflags/Makefile.am
index 87d1d9e66..8d551234e 100644
--- a/src/lib-sieve/plugins/imapflags/Makefile.am
+++ b/src/lib-sieve/plugins/imapflags/Makefile.am
@@ -15,10 +15,14 @@ cmds = \
 tsts = \
 	tst-hasflag.c
 
+tags = \
+	tag-flags.c
+
 libsieve_ext_imapflags_la_SOURCES = \
 	ext-imapflags-common.c \
 	$(cmds) \
 	$(tsts) \
+	$(tags) \
 	ext-imapflags.c
 
 noinst_HEADERS = \
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
index 04361bd36..82be527f9 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
@@ -39,6 +39,10 @@ extern const struct sieve_command cmd_removeflag;
 
 extern const struct sieve_command tst_hasflag;
 
+/* Tagged arguments */
+
+extern const struct sieve_argument tag_flags;
+
 /* Opcodes */
 
 extern const struct sieve_opcode setflag_opcode;
@@ -75,11 +79,18 @@ static bool ext_imapflags_load(int ext_id)
 static bool ext_imapflags_validator_load
 	(struct sieve_validator *validator)
 {
-	/* Register new command */
+	/* Register commands */
 	sieve_validator_register_command(validator, &cmd_setflag);
 	sieve_validator_register_command(validator, &cmd_addflag);
 	sieve_validator_register_command(validator, &cmd_removeflag);
 	sieve_validator_register_command(validator, &tst_hasflag);
+	
+	/* Register :flags tag with keep and fileinto commands and we don't care
+	 * whether these commands are registered or even whether they will be
+	 * registered at all. The validator handles either situation gracefully 
+	 */
+	sieve_validator_register_external_tag(validator, &tag_flags, "keep", 0);
+	sieve_validator_register_external_tag(validator, &tag_flags, "fileinto", 0);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/imapflags/imapflags.sieve b/src/lib-sieve/plugins/imapflags/imapflags.sieve
index c58c72c34..a05a2f68b 100644
--- a/src/lib-sieve/plugins/imapflags/imapflags.sieve
+++ b/src/lib-sieve/plugins/imapflags/imapflags.sieve
@@ -24,3 +24,5 @@ if header :contains "from" "imap@cac.washington.example.edu" {
 if hasflag :count "ge" :comparator "i;ascii-numeric" "2" {
 	fileinto "INBOX.imap-twoflags";
 }
+
+fileinto :flags "\\Seen" "INBOX";
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
new file mode 100644
index 000000000..2d4ba5d0d
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -0,0 +1,45 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+static bool tag_flags_validate
+	(struct sieve_validator *validator,	struct sieve_ast_argument **arg, 
+	struct sieve_command_context *cmd);
+
+/* Tag */
+
+const struct sieve_argument tag_flags = { 
+	"flags", NULL, 
+	tag_flags_validate, 
+	NULL, NULL 
+};
+
+/* Tag validation */
+
+static bool tag_flags_validate
+(struct sieve_validator *validator,	struct sieve_ast_argument **arg, 
+	struct sieve_command_context *cmd)
+{
+	struct sieve_ast_argument *tag = *arg;
+
+	/* Detach the tag itself */
+	*arg = sieve_ast_arguments_detach(*arg,1);
+	
+	/* Check syntax:
+	 *   :flags <list-of-flags: string-list>
+	 */
+	if ( !sieve_validate_tag_parameter
+		(validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
+		return FALSE;
+	}
+	
+	/* Detach parameter */
+	*arg = sieve_ast_arguments_detach(*arg,1);
+
+	return TRUE;
+}
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 73f24b112..fb569f250 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -192,7 +192,8 @@ static bool act_store_commit
 	
 	act_store_log_status(trans, aenv->msgdata, FALSE, status);
 	
-	mailbox_close(&trans->box);
+	if ( trans->box != NULL )
+		mailbox_close(&trans->box);
 	
 	return status;
 }
@@ -208,8 +209,9 @@ static void act_store_rollback
 	  mailbox_transaction_rollback(&trans->mail_trans);
   
   act_store_log_status(trans, aenv->msgdata, TRUE, success);
-  
-  mailbox_close(&trans->box);
+
+	if ( trans->box != NULL )  
+	  mailbox_close(&trans->box);
 }
 
 
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 66c3e45ad..369cdc356 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -178,9 +178,8 @@ bool sieve_result_execute
 	
 	printf("\nTransaction execute:\n");
 	
-	if ( success )
-		rac = result->first_action;
-	
+	last_attempted = rac;
+	rac = result->first_action;
 	while ( success && rac != NULL ) {
 		const struct sieve_action *act = rac->action;
 	
@@ -201,7 +200,6 @@ bool sieve_result_execute
 		printf("\nTransaction rollback:\n");
 
 	commit_ok = success;
-	last_attempted = rac;
 	rac = result->first_action;
 	while ( rac != NULL && rac != last_attempted ) {
 		const struct sieve_action *act = rac->action;
-- 
GitLab