dovecot-2.2-pigeonhole: lib-sieve: Finished support for mboxmeta...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sun Nov 16 22:16:49 UTC 2014


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/4da1e84f32e4
changeset: 1966:4da1e84f32e4
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Nov 16 23:13:58 2014 +0100
description:
lib-sieve: Finished support for mboxmetadata and servermetadata extensions.

diffstat:

 src/lib-sieve/Makefile.am                            |    4 +-
 src/lib-sieve/plugins/Makefile.am                    |    3 +-
 src/lib-sieve/plugins/metadata/Makefile.am           |    3 +-
 src/lib-sieve/plugins/metadata/ext-metadata-common.h |    4 +
 src/lib-sieve/plugins/metadata/tst-metadata.c        |  147 ++++++++++++++++--
 src/lib-sieve/plugins/metadata/tst-metadataexists.c  |  137 ++++++++++++++---
 src/lib-sieve/sieve-extensions.c                     |    7 +-
 src/sieve-tools/sieve-test.c                         |    2 +-
 8 files changed, 256 insertions(+), 51 deletions(-)

diffs (truncated from 518 to 300 lines):

diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/Makefile.am
--- a/src/lib-sieve/Makefile.am	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/Makefile.am	Sun Nov 16 23:13:58 2014 +0100
@@ -44,8 +44,7 @@
 
 if BUILD_UNFINISHED
 unfinished_storages =
-unfinished_plugins = \
-	$(extdir)/metadata/libsieve_ext_metadata.la
+unfinished_plugins =
 endif
 
 strgdir = $(top_builddir)/src/lib-sieve/storage
@@ -77,6 +76,7 @@
 	$(extdir)/editheader/libsieve_ext_editheader.la \
 	$(extdir)/duplicate/libsieve_ext_duplicate.la \
 	$(extdir)/index/libsieve_ext_index.la \
+	$(extdir)/metadata/libsieve_ext_metadata.la \
 	$(extdir)/vnd.dovecot/debug/libsieve_ext_debug.la \
 	$(unfinished_plugins)
 
diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/plugins/Makefile.am
--- a/src/lib-sieve/plugins/Makefile.am	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/plugins/Makefile.am	Sun Nov 16 23:13:58 2014 +0100
@@ -1,5 +1,5 @@
 if BUILD_UNFINISHED
-UNFINISHED = metadata
+UNFINISHED = 
 endif
 
 SUBDIRS = \
@@ -23,6 +23,7 @@
 	editheader \
 	duplicate \
 	index \
+	metadata \
 	vnd.dovecot \
 	$(UNFINISHED)
 
diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/plugins/metadata/Makefile.am
--- a/src/lib-sieve/plugins/metadata/Makefile.am	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/plugins/metadata/Makefile.am	Sun Nov 16 23:13:58 2014 +0100
@@ -5,7 +5,8 @@
 AM_CPPFLAGS = \
 	-I$(srcdir)/../.. \
 	-I$(srcdir)/../variables \
-	$(LIBDOVECOT_INCLUDE)
+	$(LIBDOVECOT_INCLUDE) \
+	$(LIBDOVECOT_STORAGE_INCLUDE)
 
 tests = \
 	tst-metadata.c \
diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/plugins/metadata/ext-metadata-common.h
--- a/src/lib-sieve/plugins/metadata/ext-metadata-common.h	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/plugins/metadata/ext-metadata-common.h	Sun Nov 16 23:13:58 2014 +0100
@@ -4,6 +4,10 @@
 #ifndef __EXT_METADATA_COMMON_H
 #define __EXT_METADATA_COMMON_H
 
+#include "lib.h"
+#include "mail-storage.h"
+#include "imap-metadata.h"
+
 #include "sieve-common.h"
 
 /*
diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/plugins/metadata/tst-metadata.c
--- a/src/lib-sieve/plugins/metadata/tst-metadata.c	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/plugins/metadata/tst-metadata.c	Sun Nov 16 23:13:58 2014 +0100
@@ -1,7 +1,12 @@
 /* Copyright (c) 2002-2014 Pigeonhole authors, see the included COPYING file
  */
 
+#include "lib.h"
+#include "str-sanitize.h"
+#include "istream.h"
+
 #include "sieve-common.h"
+#include "sieve-limits.h"
 #include "sieve-commands.h"
 #include "sieve-stringlist.h"
 #include "sieve-code.h"
@@ -15,6 +20,10 @@
 
 #include "ext-metadata-common.h"
 
+#include <ctype.h>
+
+#define TST_METADATA_MAX_MATCH_SIZE SIEVE_MAX_STRING_LEN
+
 /*
  * Test definitions
  */
@@ -102,7 +111,8 @@
  */
 
 static bool tst_metadata_registered
-(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED,
+(struct sieve_validator *valdtr,
+	const struct sieve_extension *ext ATTR_UNUSED,
 	struct sieve_command_registration *cmd_reg)
 {
 	/* The order of these is not significant */
@@ -125,7 +135,9 @@
 	const struct sieve_comparator cmp_default =
 		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
 	unsigned int arg_index = 1;
+	const char *error;
 
+	/* mailbox */
 	if ( sieve_command_is(tst, metadata_test) ) {
 		if ( !sieve_validate_positional_argument
 			(valdtr, tst, arg, "mailbox", arg_index++, SAAT_STRING) ) {
@@ -138,6 +150,7 @@
 		arg = sieve_ast_argument_next(arg);
 	}
 
+	/* annotation-name */
 	if ( !sieve_validate_positional_argument
 		(valdtr, tst, arg, "annotation-name", arg_index++, SAAT_STRING) ) {
 		return FALSE;
@@ -146,10 +159,25 @@
 	if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
 		return FALSE;
 
+	if ( sieve_argument_is_string_literal(arg) ) {
+		string_t *aname = sieve_ast_argument_str(arg);
+
+		if ( !imap_metadata_verify_entry_name(str_c(aname), &error) ) {
+			char *lcerror = t_strdup_noconst(error);
+			lcerror[0] = i_tolower(lcerror[0]);
+			sieve_argument_validate_warning
+				(valdtr, arg, "%s test: "
+					"specified annotation name `%s' is invalid: %s",
+					sieve_command_identifier(tst),
+					str_sanitize(str_c(aname), 256), lcerror);
+		}
+	}
+
 	arg = sieve_ast_argument_next(arg);
 
+	/* key-list */
 	if ( !sieve_validate_positional_argument
-		(valdtr, tst, arg, "key list", arg_index++, SAAT_STRING_LIST) ) {
+		(valdtr, tst, arg, "key-list", arg_index++, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
 
@@ -217,6 +245,63 @@
  * Code execution
  */
 
+static inline const char *_lc_error(const char *error)
+{
+	char *lcerror = t_strdup_noconst(error);
+	lcerror[0] = i_tolower(lcerror[0]);
+
+	return lcerror;
+}
+
+static int tst_metadata_get_annotation
+(const struct sieve_runtime_env *renv, const char *mailbox,
+	const char *aname, const char **annotation_r)
+{
+	struct mail_user *user = renv->scriptenv->user;
+	struct mailbox *box;
+	struct imap_metadata_transaction *imtrans;
+	struct mail_attribute_value avalue;
+	int status, ret;
+
+	*annotation_r = NULL;
+
+	if ( user == NULL )
+		return SIEVE_EXEC_OK;
+
+	if ( mailbox != NULL ) {
+		struct mail_namespace *ns;
+		ns = mail_namespace_find(user->namespaces, mailbox);
+		box = mailbox_alloc(ns->list, mailbox, 0);
+		imtrans = imap_metadata_transaction_begin(box);
+	} else {
+		imtrans = imap_metadata_transaction_begin_server(user);
+	}
+
+	status = SIEVE_EXEC_OK;
+	ret = imap_metadata_get(imtrans, aname, &avalue);
+	if (ret < 0) {
+		enum mail_error error_code;
+		const char *error;
+
+		error = imap_metadata_transaction_get_last_error
+			(imtrans, &error_code);
+
+		sieve_runtime_error(renv, NULL, "%s test: "
+			"failed to retrieve annotation `%s': %s%s",
+			(mailbox != NULL ? "metadata" : "servermetadata"),
+			str_sanitize(aname, 256), _lc_error(error),
+			(error_code == MAIL_ERROR_TEMP ? " (temporary failure)" : ""));
+
+		status = ( error_code == MAIL_ERROR_TEMP ?
+			SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE );
+
+	} else if (avalue.value != NULL) {
+		*annotation_r = avalue.value;
+	}
+	(void)imap_metadata_transaction_commit(&imtrans, NULL, NULL);
+	return status;
+}
+
 static int tst_metadata_operation_execute
 (const struct sieve_runtime_env *renv, sieve_size_t *address)
 {
@@ -225,9 +310,9 @@
 		SIEVE_MATCH_TYPE_DEFAULT(is_match_type);
 	struct sieve_comparator cmp =
 		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
-	string_t *mailbox, *annotation_name;
+	string_t *mailbox, *aname;
 	struct sieve_stringlist *value_list, *key_list;
-	const char *annotation = NULL;
+	const char *annotation = NULL, *error;
 	int match, ret;
 
 	/*
@@ -247,7 +332,7 @@
 
 	/* Read annotation-name */
 	if ( (ret=sieve_opr_string_read
-		(renv, address, "annotation-name", &annotation_name)) <= 0 )
+		(renv, address, "annotation-name", &aname)) <= 0 )
 		return ret;
 
 	/* Read key-list */
@@ -263,24 +348,48 @@
 		sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "metadata test");
 	else
 		sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "servermetadata test");
+	sieve_runtime_trace_descend(renv);
+
+	if ( !imap_metadata_verify_entry_name(str_c(aname), &error) ) {
+		sieve_runtime_warning(renv, NULL, "%s test: "
+			"specified annotation name `%s' is invalid: %s",
+			(metadata ? "metadata" : "servermetadata"),
+			str_sanitize(str_c(aname), 256), _lc_error(error));
+		sieve_interpreter_set_test_result(renv->interp, FALSE);
+		return SIEVE_EXEC_OK;
+	}
+
+	if ( metadata ) {
+		sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS,
+			"retrieving annotation `%s' from mailbox `%s'",
+			str_sanitize(str_c(aname), 256),
+			str_sanitize(str_c(mailbox), 80));
+	} else {
+		sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS,
+			"retrieving server annotation `%s'",
+			str_sanitize(str_c(aname), 256));
+	}
 
 	/* Get annotation */
-	annotation = "FIXME";
+	if ( (ret=tst_metadata_get_annotation
+		(renv, (metadata ? str_c(mailbox) : NULL), str_c(aname), &annotation))
+			== SIEVE_EXEC_OK ) {
+		/* Perform match */
+		if ( annotation != NULL ) {
+			/* Create value stringlist */
+			value_list = sieve_single_stringlist_create_cstr(renv, annotation, FALSE);
 
-	/* Perform match */
-	if ( annotation != NULL ) {
-		/* Create value stringlist */
-		value_list = sieve_single_stringlist_create_cstr(renv, annotation, FALSE);
-
-		/* Perform match */
-		if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret))
-			< 0 )
-			return ret;
-	} else {
-		match = 0;
+			/* Perform match */
+			if ( (match=sieve_match
+				(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 )
+				return ret;
+		} else {
+			match = 0;
+		}
 	}
 
 	/* Set test result for subsequent conditional jump */
-	sieve_interpreter_set_test_result(renv->interp, match > 0);
-	return SIEVE_EXEC_OK;
+	if (ret == SIEVE_EXEC_OK)
+		sieve_interpreter_set_test_result(renv->interp, match > 0);
+	return ret;
 }
diff -r 1d06b61cbaf3 -r 4da1e84f32e4 src/lib-sieve/plugins/metadata/tst-metadataexists.c
--- a/src/lib-sieve/plugins/metadata/tst-metadataexists.c	Wed Nov 12 22:10:25 2014 +0100
+++ b/src/lib-sieve/plugins/metadata/tst-metadataexists.c	Sun Nov 16 23:13:58 2014 +0100
@@ -17,6 +17,9 @@


More information about the dovecot-cvs mailing list