From 1ddbb32eaefb029abb1f38e247018b0234a282fa Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@dovecot.fi>
Date: Fri, 20 May 2016 15:32:51 +0300
Subject: [PATCH] Adjusted to changes in o_stream_send_istream() API

---
 .../storage/file/sieve-file-storage-save.c    | 38 +++++++++++++---
 src/managesieve/cmd-getscript.c               | 45 +++++++++----------
 2 files changed, 53 insertions(+), 30 deletions(-)

diff --git a/src/lib-sieve/storage/file/sieve-file-storage-save.c b/src/lib-sieve/storage/file/sieve-file-storage-save.c
index 3b81226d7..4353fbec7 100644
--- a/src/lib-sieve/storage/file/sieve-file-storage-save.c
+++ b/src/lib-sieve/storage/file/sieve-file-storage-save.c
@@ -6,6 +6,7 @@
 #include "ioloop.h"
 #include "array.h"
 #include "buffer.h"
+#include "istream.h"
 #include "ostream.h"
 #include "str.h"
 #include "eacces-error.h"
@@ -228,9 +229,22 @@ int sieve_file_storage_save_continue
 	struct sieve_file_save_context *fsctx =
 		(struct sieve_file_save_context *)sctx;
 
-	if (o_stream_send_istream(fsctx->output, sctx->input) < 0) {
-		sieve_storage_set_critical(sctx->storage, "save: "
-			"o_stream_send_istream(%s) failed: %m", fsctx->tmp_path);
+	switch (o_stream_send_istream(fsctx->output, sctx->input)) {
+	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
+		return 0;
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
+		i_unreached();
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
+		sieve_storage_set_critical(sctx->storage,
+			"save: read(%s) failed: %s",
+			i_stream_get_name(sctx->input),
+			i_stream_get_error(sctx->input));
+		return -1;
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
+		sieve_storage_set_critical(sctx->storage,
+			"save: write(%s) failed: %s", fsctx->tmp_path,
+			o_stream_get_error(fsctx->output));
 		return -1;
 	}
 	return 0;
@@ -418,9 +432,23 @@ sieve_file_storage_save_to(struct sieve_file_storage *fstorage,
 	}
 
 	output = o_stream_create_fd(fd, 0);
-	if ( o_stream_send_istream(output, input) < 0 ) {
+	switch ( o_stream_send_istream(output, input) ) {
+	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
+		break;
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
+		i_unreached();
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
+		sieve_storage_set_critical(storage,
+			"read(%s) failed: %s", i_stream_get_name(input),
+			i_stream_get_error(input));
+		o_stream_destroy(&output);
+		(void)unlink(str_c(temp_path));
+		return -1;
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
 		sieve_storage_set_critical(storage,
-			"o_stream_send_istream(%s) failed: %m", str_c(temp_path));
+			"write(%s) failed: %s", str_c(temp_path),
+			o_stream_get_error(output));
 		o_stream_destroy(&output);
 		(void)unlink(str_c(temp_path));
 		return -1;
diff --git a/src/managesieve/cmd-getscript.c b/src/managesieve/cmd-getscript.c
index 070999884..572663ae4 100644
--- a/src/managesieve/cmd-getscript.c
+++ b/src/managesieve/cmd-getscript.c
@@ -53,29 +53,10 @@ static bool cmd_getscript_continue(struct client_command_context *cmd)
 {
 	struct client *client = cmd->client;
 	struct cmd_getscript_context *ctx = cmd->context;
-	off_t ret;
 
-	ret = o_stream_send_istream(client->output, ctx->script_stream);
-
-	if ( ret < 0 ) {
-		if ( ctx->script_stream->stream_errno != 0 ) {
-			sieve_storage_set_critical(ctx->storage,
-				"o_stream_send_istream() failed for script `%s' from %s: %s",
-				sieve_script_name(ctx->script),
-				sieve_script_location(ctx->script),
-				i_stream_get_error(ctx->script_stream));
-		} else {
-			client_disconnect(ctx->client,
-				io_stream_get_disconnect_reason
-					(client->input, client->output));
-		}
-		ctx->failed = TRUE;
-		return cmd_getscript_finish(ctx);
-	}
-
-	if ( ctx->script_stream->v_offset != ctx->script_size && !ctx->failed ) {
-		/* unfinished */
-		if ( !i_stream_have_bytes_left(ctx->script_stream) ) {
+	switch (o_stream_send_istream(client->output, ctx->script_stream)) {
+	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
+		if ( ctx->script_stream->v_offset != ctx->script_size && !ctx->failed ) {
 			/* Input stream gave less data than expected */
 			sieve_storage_set_critical(ctx->storage,
 				"GETSCRIPT for script `%s' from %s got too little data: "
@@ -84,12 +65,26 @@ static bool cmd_getscript_continue(struct client_command_context *cmd)
 
 			client_disconnect(ctx->client, "GETSCRIPT failed");
 			ctx->failed = TRUE;
-			return cmd_getscript_finish(ctx);
 		}
-
+		break;
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
+		i_unreached();
+	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
 		return FALSE;
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
+		sieve_storage_set_critical(ctx->storage,
+			"o_stream_send_istream() failed for script `%s' from %s: %s",
+			sieve_script_name(ctx->script),
+			sieve_script_location(ctx->script),
+			i_stream_get_error(ctx->script_stream));
+		ctx->failed = TRUE;
+		break;
+	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
+		client_disconnect(ctx->client,
+			io_stream_get_disconnect_reason(client->input, client->output));
+		ctx->failed = TRUE;
+		break;
 	}
-
 	return cmd_getscript_finish(ctx);
 }
 
-- 
GitLab