dovecot-2.2-pigeonhole: lib-sieve: Improved (temporary) error ha...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sat Oct 18 23:02:30 UTC 2014


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/465dbd029556
changeset: 1926:465dbd029556
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Oct 19 01:02:02 2014 +0200
description:
lib-sieve: Improved (temporary) error handling from mail storage and io streams.

diffstat:

 src/lib-sieve/cmd-redirect.c                                   |   28 ++-
 src/lib-sieve/plugins/body/ext-body-common.c                   |   90 +++++--
 src/lib-sieve/plugins/body/ext-body-common.h                   |    4 +-
 src/lib-sieve/plugins/body/tst-body.c                          |    7 +-
 src/lib-sieve/plugins/duplicate/tst-duplicate.c                |   19 +-
 src/lib-sieve/plugins/enotify/cmd-notify.c                     |    6 +-
 src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c             |   52 ++--
 src/lib-sieve/plugins/enotify/sieve-ext-enotify.h              |    9 +-
 src/lib-sieve/plugins/notify/cmd-notify.c                      |   33 +-
 src/lib-sieve/plugins/notify/ext-notify-common.c               |   61 ++++-
 src/lib-sieve/plugins/notify/ext-notify-common.h               |    2 +-
 src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c |   33 ++-
 src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h |    4 +-
 src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c        |    4 +-
 src/lib-sieve/plugins/vacation/cmd-vacation.c                  |  111 ++++++---
 src/lib-sieve/sieve-actions.c                                  |   20 +-
 src/lib-sieve/sieve-interpreter.c                              |   19 +
 src/lib-sieve/sieve-interpreter.h                              |    3 +
 src/lib-sieve/sieve-message.c                                  |    7 +-
 src/lib-sieve/sieve-result.c                                   |   35 +++
 src/lib-sieve/sieve-result.h                                   |    7 +
 src/lib-sieve/tst-exists.c                                     |   12 +-
 src/plugins/sieve-extprograms/cmd-execute.c                    |   10 +-
 src/plugins/sieve-extprograms/cmd-filter.c                     |   10 +-
 src/plugins/sieve-extprograms/cmd-pipe.c                       |   10 +-
 25 files changed, 411 insertions(+), 185 deletions(-)

diffs (truncated from 1305 to 300 lines):

diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/cmd-redirect.c
--- a/src/lib-sieve/cmd-redirect.c	Fri Oct 17 21:07:36 2014 +0200
+++ b/src/lib-sieve/cmd-redirect.c	Sun Oct 19 01:02:02 2014 +0200
@@ -332,8 +332,10 @@
 		return SIEVE_EXEC_FAILURE;
 	}
 
-	if (mail_get_stream(mail, NULL, NULL, &input) < 0)
-		return SIEVE_EXEC_TEMP_FAILURE;
+	if (mail_get_stream(mail, NULL, NULL, &input) < 0) {
+		return sieve_result_mail_error(aenv, mail,
+			"redirect action: failed to read input message");
+	}
 
 	/* Determine which sender to use
 
@@ -386,6 +388,13 @@
 	} T_END;
 
 	o_stream_send_istream(output, input);
+	if (input->stream_errno != 0) {
+		sieve_result_critical(aenv,
+			"redirect action: failed to read input message",
+			"redirect action: failed to read message stream: %s",
+			i_stream_get_error(input));
+		return SIEVE_EXEC_TEMP_FAILURE;
+	}
   i_stream_unref(&input);
 
 	/* Close SMTP transport */
@@ -424,10 +433,19 @@
 	int ret;
 
 	/* Prevent mail loops if possible */
-	(void)mail_get_first_header(msgdata->mail, "resent-message-id", &resent_id);
+	if ( mail_get_first_header
+		(msgdata->mail, "resent-message-id", &resent_id) < 0 ) {
+		return sieve_result_mail_error(aenv, mail,
+			"failed to read header field `resent-message-id'");
+	}
 	if ( msgdata->id != NULL || resent_id != NULL ) {
-		if ( resent_id == NULL )
-			(void)mail_get_first_header(msgdata->mail, "resent-from", &resent_from);
+		if ( resent_id == NULL ) {
+			if ( mail_get_first_header
+				(msgdata->mail, "resent-from", &resent_from) < 0 ) {
+				return sieve_result_mail_error(aenv, mail,
+					"failed to read header field `resent-from'");
+			}
+		}
 		dupeid = t_strdup_printf("%s-%s-%s-%s",
 			(msgdata->id == NULL ? "" : msgdata->id),
 			orig_recipient, ctx->to_address,
diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/ext-body-common.c
--- a/src/lib-sieve/plugins/body/ext-body-common.c	Fri Oct 17 21:07:36 2014 +0200
+++ b/src/lib-sieve/plugins/body/ext-body-common.c	Sun Oct 19 01:02:02 2014 +0200
@@ -211,11 +211,12 @@
 /* ext_body_parts_add_missing():
  *   Add requested message body parts to the cache that are missing.
  */
-static bool ext_body_parts_add_missing
-(struct sieve_message_context *msgctx, struct ext_body_message_context *ctx,
-	const char * const *content_types, bool decode_to_plain)
+static int ext_body_parts_add_missing
+(const struct sieve_runtime_env *renv,
+	struct ext_body_message_context *ctx,
+	const char *const *content_types, bool decode_to_plain)
 {
-	struct mail *mail = sieve_message_get_mail(msgctx);
+	struct mail *mail = sieve_message_get_mail(renv->msgctx);
 	struct ext_body_part_cached *body_part = NULL, *header_part = NULL;
 	struct message_parser_ctx *parser;
 	struct message_decoder_context *decoder;
@@ -230,15 +231,18 @@
 	/* First check whether any are missing */
 	if (ext_body_get_return_parts(ctx, content_types, decode_to_plain)) {
 		/* Cache hit; all are present */
-		return TRUE;
+		return SIEVE_EXEC_OK;
 	}
 
 	/* Get the message stream */
-	if ( mail_get_stream(mail, NULL, NULL, &input) < 0 )
-		return FALSE;
-
-	if (mail_get_parts(mail, &parts) < 0)
-		return FALSE;
+	if ( mail_get_stream(mail, NULL, NULL, &input) < 0 ) {
+		return sieve_runtime_mail_error(renv, mail,
+			"body test: failed to read input message");
+	}
+	if (mail_get_parts(mail, &parts) < 0) {
+		return sieve_runtime_mail_error(renv, mail,
+			"body test: failed to parse input message");
+	}
 
 	if ( (want_multipart=_want_multipart_content_type(content_types)) ) {
 		t_array_init(&part_index, 8);
@@ -408,7 +412,14 @@
 		message_decoder_deinit(&decoder);
 
 	/* Return status */
-	return ( input->stream_errno == 0 );
+	if ( input->stream_errno != 0 ) {
+		sieve_runtime_critical(renv, NULL,
+			"body test: failed to read input message",
+			"body test: failed to read message stream: %s",
+			i_stream_get_error(input));
+		return SIEVE_EXEC_TEMP_FAILURE;
+	}
+	return SIEVE_EXEC_OK;
 }
 
 static struct ext_body_message_context *ext_body_get_context
@@ -440,33 +451,33 @@
 	return ctx;
 }
 
-static bool ext_body_get_content
+static int ext_body_get_content
 (const struct sieve_runtime_env *renv, const char * const *content_types,
 	int decode_to_plain, struct ext_body_part **parts_r)
 {
 	const struct sieve_extension *this_ext = renv->oprtn->ext;
 	struct ext_body_message_context *ctx =
 		ext_body_get_context(this_ext, renv->msgctx);
-	bool result = TRUE;
+	int status;
 
 	T_BEGIN {
 		/* Fill the return_body_parts array */
-		if ( !ext_body_parts_add_missing
-			(renv->msgctx, ctx, content_types, decode_to_plain != 0) )
-			result = FALSE;
+		status = ext_body_parts_add_missing
+			(renv, ctx, content_types, decode_to_plain != 0);
 	} T_END;
 
 	/* Check status */
-	if ( !result ) return FALSE;
+	if ( status <= 0 )
+		return status;
 
 	/* Return the array of body items */
 	(void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */
 	*parts_r = array_idx_modifiable(&ctx->return_body_parts, 0);
 
-	return result;
+	return status;
 }
 
-static bool ext_body_get_raw
+static int ext_body_get_raw
 (const struct sieve_runtime_env *renv, struct ext_body_part **parts_r)
 {
 	const struct sieve_extension *this_ext = renv->oprtn->ext;
@@ -486,8 +497,10 @@
 		ctx->raw_body = buf = buffer_create_dynamic(ctx->pool, 1024*64);
 
 		/* Get stream for message */
- 		if ( mail_get_stream(mail, &hdr_size, &body_size, &input) < 0 )
-			return FALSE;
+ 		if ( mail_get_stream(mail, &hdr_size, &body_size, &input) < 0 ) {
+			return sieve_runtime_mail_error(renv, mail,
+				"body test: failed to read input message");
+		}
 
 		/* Skip stream to beginning of body */
 		i_stream_skip(input, hdr_size.physical_size);
@@ -499,8 +512,13 @@
 			i_stream_skip(input, size);
 		}
 
-		if ( ret == -1 && input->stream_errno != 0 )
-			return FALSE;
+		if ( ret == -1 && input->stream_errno != 0 ) {
+			sieve_runtime_critical(renv, NULL,
+				"body test: failed to read input message as raw",
+				"body test: failed to read raw message stream: %s",
+				i_stream_get_error(input));
+			return SIEVE_EXEC_TEMP_FAILURE;
+		}
 	} else {
 		buf = ctx->raw_body;
 	}
@@ -522,7 +540,7 @@
 	(void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */
 	*parts_r = array_idx_modifiable(&ctx->return_body_parts, 0);
 
-	return TRUE;
+	return SIEVE_EXEC_OK;
 }
 
 /*
@@ -541,30 +559,35 @@
 	struct ext_body_part *body_parts_iter;
 };
 
-struct sieve_stringlist *ext_body_get_part_list
+int ext_body_get_part_list
 (const struct sieve_runtime_env *renv, enum tst_body_transform transform,
-	const char * const *content_types)
+	const char * const *content_types, struct sieve_stringlist **strlist_r)
 {
 	static const char * const _no_content_types[] = { "", NULL };
 	struct ext_body_stringlist *strlist;
 	struct ext_body_part *body_parts;
+	int ret;
+
+	*strlist_r = NULL;
 
 	if ( content_types == NULL ) content_types = _no_content_types;
 
 	switch ( transform ) {
 	case TST_BODY_TRANSFORM_RAW:
-		if ( !ext_body_get_raw(renv, &body_parts) )
-			return NULL;
+		if ( (ret=ext_body_get_raw(renv, &body_parts)) <= 0 )
+			return ret;
 		break;
 	case TST_BODY_TRANSFORM_CONTENT:
 		/* FIXME: check these parameters */
-		if ( !ext_body_get_content(renv, content_types, TRUE, &body_parts) )
-			return NULL;
+		if ( (ret=ext_body_get_content
+			(renv, content_types, TRUE, &body_parts)) <= 0 )
+			return ret;
 		break;
 	case TST_BODY_TRANSFORM_TEXT:
 		/* FIXME: check these parameters */
-		if ( !ext_body_get_content(renv, content_types, TRUE, &body_parts) )
-			return NULL;
+		if ( (ret=ext_body_get_content
+			(renv, content_types, TRUE, &body_parts)) <= 0 )
+			return ret;
 		break;
 	default:
 		i_unreached();
@@ -577,7 +600,8 @@
 	strlist->body_parts = body_parts;
 	strlist->body_parts_iter = body_parts;
 
-	return &strlist->strlist;
+	*strlist_r = &strlist->strlist;
+	return SIEVE_EXEC_OK;
 }
 
 static int ext_body_stringlist_next_item
diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/ext-body-common.h
--- a/src/lib-sieve/plugins/body/ext-body-common.h	Fri Oct 17 21:07:36 2014 +0200
+++ b/src/lib-sieve/plugins/body/ext-body-common.h	Sun Oct 19 01:02:02 2014 +0200
@@ -36,8 +36,8 @@
  * Message body part extraction
  */
 
-struct sieve_stringlist *ext_body_get_part_list
+int ext_body_get_part_list
 	(const struct sieve_runtime_env *renv, enum tst_body_transform transform,
-		const char * const *content_types);
+		const char * const *content_types, struct sieve_stringlist **strlist_r);
 
 #endif /* __EXT_BODY_COMMON_H */
diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/body/tst-body.c
--- a/src/lib-sieve/plugins/body/tst-body.c	Fri Oct 17 21:07:36 2014 +0200
+++ b/src/lib-sieve/plugins/body/tst-body.c	Sun Oct 19 01:02:02 2014 +0200
@@ -370,10 +370,9 @@
 	sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "body test");
 
 	/* Extract requested parts */
-	value_list = ext_body_get_part_list
-		(renv, (enum tst_body_transform) transform, content_types);
-	if ( value_list == FALSE )
-		return SIEVE_EXEC_FAILURE;
+	if ( (ret=ext_body_get_part_list(renv,
+		(enum tst_body_transform) transform, content_types,&value_list)) <= 0 )
+		return ret;
 
 	/* Disable match values processing as required by RFC */
 	mvalues_active = sieve_match_values_set_enabled(renv, FALSE);
diff -r 971eba8c3361 -r 465dbd029556 src/lib-sieve/plugins/duplicate/tst-duplicate.c
--- a/src/lib-sieve/plugins/duplicate/tst-duplicate.c	Fri Oct 17 21:07:36 2014 +0200
+++ b/src/lib-sieve/plugins/duplicate/tst-duplicate.c	Sun Oct 19 01:02:02 2014 +0200
@@ -316,6 +316,7 @@
 	const struct sieve_extension *ext = renv->oprtn->ext;
 	const struct ext_duplicate_config *config =
 		(const struct ext_duplicate_config *) ext->context;
+	struct mail *mail = renv->msgdata->mail;
 	int opt_code = 0;
 	string_t *handle = NULL, *header = NULL, *uniqueid = NULL;
 	const char *val = NULL;
@@ -380,13 +381,21 @@
 		val_len = str_len(uniqueid);
 	} else {
 		if ( header == NULL ) {
-			ret = mail_get_first_header_utf8
-				(renv->msgdata->mail, "Message-ID", &val);
+			ret = mail_get_first_header_utf8(mail, "Message-ID", &val);
+			if ( ret < 0 ) {
+				return sieve_runtime_mail_error	(renv, mail,
+					"duplicate test: "


More information about the dovecot-cvs mailing list