From 60770a2ad1b70933c130bc0942e15c310e6360ae Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Thu, 22 Nov 2007 19:35:44 +0100
Subject: [PATCH] Created skeletons for the commands introduced by the
 imapflags extension.

---
 src/lib-sieve/plugins/imapflags/Makefile.am   |  9 ++++
 src/lib-sieve/plugins/imapflags/cmd-addflag.c | 41 +++++++++++++++++++
 .../plugins/imapflags/cmd-removeflag.c        | 41 +++++++++++++++++++
 src/lib-sieve/plugins/imapflags/cmd-setflag.c | 41 +++++++++++++++++++
 .../plugins/imapflags/ext-imapflags-common.c  | 16 ++++++++
 .../plugins/imapflags/ext-imapflags-common.h  |  7 ++++
 .../plugins/imapflags/ext-imapflags.c         | 12 +++++-
 .../plugins/imapflags/imapflags.sieve         | 16 ++++++++
 src/lib-sieve/sieve-commands.h                |  4 +-
 src/lib-sieve/sieve-extensions.c              |  3 +-
 src/lib-sieve/sieve-validator.c               |  5 ++-
 11 files changed, 188 insertions(+), 7 deletions(-)
 create mode 100644 src/lib-sieve/plugins/imapflags/cmd-addflag.c
 create mode 100644 src/lib-sieve/plugins/imapflags/cmd-removeflag.c
 create mode 100644 src/lib-sieve/plugins/imapflags/cmd-setflag.c
 create mode 100644 src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
 create mode 100644 src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
 create mode 100644 src/lib-sieve/plugins/imapflags/imapflags.sieve

diff --git a/src/lib-sieve/plugins/imapflags/Makefile.am b/src/lib-sieve/plugins/imapflags/Makefile.am
index 4bfb7c351..0220dac2b 100644
--- a/src/lib-sieve/plugins/imapflags/Makefile.am
+++ b/src/lib-sieve/plugins/imapflags/Makefile.am
@@ -7,6 +7,15 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir)/src/lib-mail \
 	-I$(dovecot_incdir)/src/lib-storage 
 
+cmds = \
+	cmd-setflag.c \
+	cmd-addflag.c \
+	cmd-removeflag.c
+
 libsieve_ext_imapflags_la_SOURCES = \
+	ext-imapflags-common.c \
+	$(cmds) \
 	ext-imapflags.c
 
+noinst_HEADERS = \
+	ext-imapflags-common.h
diff --git a/src/lib-sieve/plugins/imapflags/cmd-addflag.c b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
new file mode 100644
index 000000000..b61cdbacd
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
@@ -0,0 +1,41 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-commands-private.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+/* Forward declarations */
+
+static bool cmd_addflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx);
+
+/* Addflag command 
+ *
+ * Syntax:
+ *   addflag [<variablename: string>] <list-of-flags: string-list>
+ */
+  
+const struct sieve_command cmd_addflag = { 
+	"addflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_addflag_generate, 
+	NULL 
+};
+
+/* Code generation */
+
+static bool cmd_addflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx)
+{
+	return TRUE;
+}
+
+
diff --git a/src/lib-sieve/plugins/imapflags/cmd-removeflag.c b/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
new file mode 100644
index 000000000..bfeb260f7
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/cmd-removeflag.c
@@ -0,0 +1,41 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-commands-private.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+/* Forward declarations */
+
+static bool cmd_removeflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx);
+
+/* Removeflag command 
+ *
+ * Syntax:
+ *   removeflag [<variablename: string>] <list-of-flags: string-list>
+ */
+ 
+const struct sieve_command cmd_removeflag = { 
+	"removeflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_removeflag_generate, 
+	NULL 
+};
+
+/* Code generation */
+
+static bool cmd_removeflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx)
+{
+	return TRUE;
+}
+
+
diff --git a/src/lib-sieve/plugins/imapflags/cmd-setflag.c b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
new file mode 100644
index 000000000..d034ef17e
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
@@ -0,0 +1,41 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-commands-private.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+/* Forward declarations */
+
+static bool cmd_setflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx);
+
+/* Setflag command 
+ *
+ * Syntax: 
+ *   setflag [<variablename: string>] <list-of-flags: string-list>
+ */
+ 
+const struct sieve_command cmd_setflag = { 
+	"setflag", 
+	SCT_COMMAND,
+	-1, /* We check positional arguments ourselves */
+	0, FALSE, FALSE, 
+	NULL, NULL,
+	ext_imapflags_command_validate, 
+	cmd_setflag_generate, 
+	NULL 
+};
+
+/* Code generation */
+
+static bool cmd_setflag_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx)
+{
+	return TRUE;
+}
+
+
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
new file mode 100644
index 000000000..e47d5560c
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -0,0 +1,16 @@
+#include "lib.h"
+
+#include "sieve-commands.h"
+#include "sieve-commands-private.h"
+#include "sieve-validator.h" 
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-imapflags-common.h"
+
+bool ext_imapflags_command_validate
+	(struct sieve_validator *validator, struct sieve_command_context *cmd)
+{
+	return TRUE;
+}
+
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
new file mode 100644
index 000000000..63d36b3cc
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
@@ -0,0 +1,7 @@
+#ifndef __EXT_IMAPFLAGS_COMMON_H
+#define __EXT_IMAPFLAGS_COMMON_H
+
+bool ext_imapflags_command_validate
+	(struct sieve_validator *validator, struct sieve_command_context *cmd);
+
+#endif /* __EXT_IMAPFLAGS_COMMON_H */
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
index dab8875b7..74b9e4a32 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
@@ -24,6 +24,12 @@
 static bool ext_imapflags_load(int ext_id);
 static bool ext_imapflags_validator_load(struct sieve_validator *validator);
 
+/* Commands */
+
+extern const struct sieve_command cmd_setflag;
+extern const struct sieve_command cmd_addflag;
+extern const struct sieve_command cmd_removeflag;
+
 /* Extension definitions */
 
 int ext_my_id;
@@ -48,10 +54,12 @@ static bool ext_imapflags_load(int ext_id)
 /* Load extension into validator */
 
 static bool ext_imapflags_validator_load
-	(struct sieve_validator *validator ATTR_UNUSED)
+	(struct sieve_validator *validator)
 {
 	/* Register new command */
-	//sieve_validator_register_command(validator, &imapflags_command);
+	sieve_validator_register_command(validator, &cmd_setflag);
+	sieve_validator_register_command(validator, &cmd_addflag);
+	sieve_validator_register_command(validator, &cmd_removeflag);
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/imapflags/imapflags.sieve b/src/lib-sieve/plugins/imapflags/imapflags.sieve
new file mode 100644
index 000000000..18d3d1a6d
--- /dev/null
+++ b/src/lib-sieve/plugins/imapflags/imapflags.sieve
@@ -0,0 +1,16 @@
+require "imapflags";
+require "fileinto";
+
+if header :contains "from" "boss@frobnitzm.example.edu" {
+	setflag "flagvar" "\\Flagged";
+#	fileinto :flags "${flagvar}" "INBOX.From Boss";
+}
+
+if header :contains "Disposition-Notification-To" "mel@example.com" {
+	addflag "flagvar" "$MDNRequired";
+}
+
+if header :contains "from" "imap@cac.washington.example.edu" {
+	removeflag "flagvar" "$MDNRequired";
+#	fileinto :flags "${flagvar}" "INBOX.imap-list";
+}
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index a88a8ef23..79255f968 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -43,8 +43,8 @@ struct sieve_command {
 	enum sieve_command_type type;
 	
 	/* High-level command syntax */
-	unsigned int positional_arguments;
-	unsigned int subtests;
+	int positional_arguments;
+	int subtests;
 	bool block_allowed;
 	bool block_required;
 	
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index bb6a4cb1c..1e89d319e 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -48,6 +48,7 @@ extern const struct sieve_extension subaddress_extension;
 extern const struct sieve_extension comparator_i_ascii_numeric_extension;
 extern const struct sieve_extension relational_extension;
 extern const struct sieve_extension regex_extension;
+extern const struct sieve_extension imapflags_extension;
 
 const struct sieve_extension *sieve_core_extensions[] = {
 	&comparator_extension, &match_type_extension, &address_part_extension, 
@@ -57,7 +58,7 @@ const struct sieve_extension *sieve_core_extensions[] = {
 	/* 'Plugins' */
 	&vacation_extension, &subaddress_extension, 
 	&comparator_i_ascii_numeric_extension, 
-	&relational_extension, &regex_extension
+	&relational_extension, &regex_extension, &imapflags_extension
 };
 
 const unsigned int sieve_core_extensions_count =
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index e0f46fd18..956529d8f 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -655,8 +655,9 @@ static bool sieve_validate_command
 		
 				/* Check syntax */
 				if ( 
-					!sieve_validate_command_arguments
-						(validator, ctx, command->positional_arguments) ||
+					( command->positional_arguments >= 0 && 
+						!sieve_validate_command_arguments
+							(validator, ctx, command->positional_arguments) ) ||
  					!sieve_validate_command_subtests
  						(validator, ctx, command->subtests) || 
  					(ast_type == SAT_COMMAND && !sieve_validate_command_block
-- 
GitLab