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