struct attachment_istream_part part;
bool retry_read;
+ bool failed;
};
static void stream_add_data(struct attachment_istream *astream,
return 0;
}
-static int astream_part_finish(struct attachment_istream *astream)
+static int
+astream_part_finish(struct attachment_istream *astream, const char **error_r)
{
struct attachment_istream_part *part = &astream->part;
struct istream_attachment_info info;
int ret = 0;
if (o_stream_nfinish(part->temp_output) < 0) {
- i_error("istream-attachment: write(%s) failed: %m",
- o_stream_get_name(part->temp_output));
+ *error_r = t_strdup_printf("write(%s) failed: %s",
+ o_stream_get_name(part->temp_output),
+ o_stream_get_error(part->temp_output));
return -1;
}
as attachment */
info.encoded_size = part->temp_output->offset;
}
- if (astream->set.open_attachment_ostream(&info, &output,
+ if (astream->set.open_attachment_ostream(&info, &output, error_r,
astream->context) < 0)
return -1;
}
if (input->stream_errno != 0) {
- i_error("istream-attachment: read(%s) failed: %m",
- i_stream_get_name(input));
+ *error_r = t_strdup_printf("read(%s) failed: %s",
+ i_stream_get_name(input), i_stream_get_error(input));
ret = -1;
}
i_stream_destroy(&input);
- if (astream->set.close_attachment_ostream(output, ret == 0,
+ if (astream->set.close_attachment_ostream(output, ret == 0, error_r,
astream->context) < 0)
ret = -1;
return ret;
}
static int
-astream_end_of_part(struct attachment_istream *astream)
+astream_end_of_part(struct attachment_istream *astream, const char **error_r)
{
struct attachment_istream_part *part = &astream->part;
size_t old_size;
break;
case MAIL_ATTACHMENT_STATE_YES:
old_size = astream->istream.pos - astream->istream.skip;
- if (astream_part_finish(astream) < 0)
+ if (astream_part_finish(astream, error_r) < 0)
ret = -1;
else {
/* finished base64 may have added a few more trailing
struct istream_private *stream = &astream->istream;
struct message_block block;
size_t old_size, new_size;
+ const char *error;
int ret;
*retry_r = FALSE;
if (stream->pos - stream->skip >= stream->max_buffer_size)
return -2;
+ if (astream->failed) {
+ stream->istream.stream_errno = EINVAL;
+ return -1;
+ }
+
old_size = stream->pos - stream->skip;
switch (message_parser_parse_next_block(astream->parser, &block)) {
case -1:
/* done / error */
- ret = astream_end_of_part(astream);
+ ret = astream_end_of_part(astream, &error);
if (ret > 0) {
/* final data */
new_size = stream->pos - stream->skip;
stream->istream.eof = TRUE;
stream->istream.stream_errno = stream->parent->stream_errno;
- if (ret < 0)
+ if (ret < 0) {
+ io_stream_set_error(&stream->iostream, "%s", error);
stream->istream.stream_errno = EINVAL;
+ astream->failed = TRUE;
+ }
astream->cur_part = NULL;
return -1;
case 0:
if (block.part != astream->cur_part && astream->cur_part != NULL) {
/* end of a MIME part */
- if (astream_end_of_part(astream) < 0) {
+ if (astream_end_of_part(astream, &error) < 0) {
+ io_stream_set_error(&stream->iostream, "%s", error);
stream->istream.stream_errno = EINVAL;
+ astream->failed = TRUE;
return -1;
}
}
static int
index_attachment_open_ostream(struct istream_attachment_info *info,
- struct ostream **output_r, void *context)
+ struct ostream **output_r,
+ const char **error_r ATTR_UNUSED, void *context)
{
struct mail_save_context *ctx = context;
struct mail_save_attachment *attach = ctx->data.attach;
}
static int
-index_attachment_close_ostream(struct ostream *output,
- bool success, void *context)
+index_attachment_close_ostream(struct ostream *output, bool success,
+ const char **error_r, void *context)
{
struct mail_save_context *ctx = context;
struct mail_save_attachment *attach = ctx->data.attach;
- struct mail_storage *storage = ctx->transaction->box->storage;
int ret = success ? 0 : -1;
i_assert(attach->cur_file != NULL);
if (ret < 0)
fs_write_stream_abort(attach->cur_file, &output);
else if (fs_write_stream_finish(attach->cur_file, &output) < 0) {
- mail_storage_set_critical(storage, "%s",
- fs_file_last_error(attach->cur_file));
+ *error_r = t_strdup(fs_file_last_error(attach->cur_file));
ret = -1;
}
fs_file_deinit(&attach->cur_file);
size_t size;
ssize_t ret;
+ if (attach->input->stream_errno != 0)
+ return -1;
+
do {
ret = i_stream_read(attach->input);
if (ret > 0) {
}
} while (ret != -1);
+ if (attach->input->stream_errno != 0) {
+ mail_storage_set_critical(storage, "read(%s) failed: %s",
+ i_stream_get_name(attach->input),
+ i_stream_get_error(attach->input));
+ return -1;
+ }
if (ctx->data.output != NULL) {
if (save_check_write_error(storage, ctx->data.output) < 0)
return -1;
(void)i_stream_read(attach->input);
i_assert(attach->input->eof);
- return attach->input->stream_errno == 0;
+ return attach->input->stream_errno == 0 ? 0 : -1;
}
void index_attachment_save_free(struct mail_save_context *ctx)