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 3b81226d7f9d7dbd29a452a4bd68dfb9f1e70c60..4353fbec7728e836b350d60449a7a65a420f7040 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 07099988494f81d4167cce8e7dace09c9df508a2..572663ae45ad6cd69300d2944544591359bd50e1 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); }