From: Timo Sirainen Date: Sat, 25 Oct 2008 20:56:35 +0000 (+0300) Subject: Virtual mailboxes: Fixes to handling errors. X-Git-Tag: 1.2.alpha4~148 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=942302b0247403645394d848b3c620ead262a2a5;p=thirdparty%2Fdovecot%2Fcore.git Virtual mailboxes: Fixes to handling errors. --HG-- branch : HEAD --- diff --git a/src/plugins/virtual/virtual-mail.c b/src/plugins/virtual/virtual-mail.c index cb069274d3..b403d68cfe 100644 --- a/src/plugins/virtual/virtual-mail.c +++ b/src/plugins/virtual/virtual-mail.c @@ -141,7 +141,11 @@ virtual_mail_get_parts(struct mail *mail, const struct message_part **parts_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_parts(vmail->backend_mail, parts_r); + if (mail_get_parts(vmail->backend_mail, parts_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int @@ -153,35 +157,55 @@ virtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r) if (timezone_r == NULL) timezone_r = &tz; - return mail_get_date(vmail->backend_mail, date_r, timezone_r); + if (mail_get_date(vmail->backend_mail, date_r, timezone_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int virtual_mail_get_received_date(struct mail *mail, time_t *date_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_received_date(vmail->backend_mail, date_r); + if (mail_get_received_date(vmail->backend_mail, date_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int virtual_mail_get_save_date(struct mail *mail, time_t *date_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_save_date(vmail->backend_mail, date_r); + if (mail_get_save_date(vmail->backend_mail, date_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int virtual_mail_get_virtual_mail_size(struct mail *mail, uoff_t *size_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_virtual_size(vmail->backend_mail, size_r); + if (mail_get_virtual_size(vmail->backend_mail, size_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int virtual_mail_get_physical_size(struct mail *mail, uoff_t *size_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_physical_size(vmail->backend_mail, size_r); + if (mail_get_physical_size(vmail->backend_mail, size_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int @@ -191,8 +215,12 @@ virtual_mail_get_first_header(struct mail *mail, const char *field, struct virtual_mail *vmail = (struct virtual_mail *)mail; struct mail_private *p = (struct mail_private *)vmail->backend_mail; - return p->v.get_first_header(vmail->backend_mail, field, - decode_to_utf8, value_r); + if (p->v.get_first_header(vmail->backend_mail, field, + decode_to_utf8, value_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int @@ -202,8 +230,12 @@ virtual_mail_get_headers(struct mail *mail, const char *field, struct virtual_mail *vmail = (struct virtual_mail *)mail; struct mail_private *p = (struct mail_private *)vmail->backend_mail; - return p->v.get_headers(vmail->backend_mail, field, - decode_to_utf8, value_r); + if (p->v.get_headers(vmail->backend_mail, field, + decode_to_utf8, value_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int @@ -219,6 +251,11 @@ virtual_mail_get_header_stream(struct mail *mail, headers->headers); ret = mail_get_header_stream(vmail->backend_mail, headers, stream_r); mailbox_header_lookup_unref(&backend_headers); + if (ret < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; return ret; } @@ -229,7 +266,12 @@ virtual_mail_get_stream(struct mail *mail, struct message_size *hdr_size, { struct virtual_mail *vmail = (struct virtual_mail *)mail; - return mail_get_stream(vmail->backend_mail, hdr_size, body_size, stream_r); + if (mail_get_stream(vmail->backend_mail, hdr_size, body_size, + stream_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static int @@ -242,7 +284,11 @@ virtual_mail_get_special(struct mail *mail, enum mail_fetch_field field, *value_r = vmail->backend_mail->box->name; return 0; } - return mail_get_special(vmail->backend_mail, field, value_r); + if (mail_get_special(vmail->backend_mail, field, value_r) < 0) { + virtual_box_copy_error(mail->box, vmail->backend_mail->box); + return -1; + } + return 0; } static void virtual_mail_expunge(struct mail *mail) diff --git a/src/plugins/virtual/virtual-storage.c b/src/plugins/virtual/virtual-storage.c index cf83f74d10..9aa68a5bbd 100644 --- a/src/plugins/virtual/virtual-storage.c +++ b/src/plugins/virtual/virtual-storage.c @@ -36,6 +36,34 @@ virtual_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx, enum mailbox_list_file_type type, enum mailbox_info_flags *flags); +void virtual_copy_error(struct mail_storage *dest, struct mail_storage *src) +{ + const char *str; + enum mail_error error; + + str = mail_storage_get_last_error(src, &error); + if ((src->ns->flags & NAMESPACE_FLAG_HIDDEN) != 0) { + str = t_strdup_printf("%s (namespace %s)", str, + src->ns->prefix); + } + mail_storage_set_error(dest, error, str); +} + +void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src) +{ + const char *str; + enum mail_error error; + + str = mail_storage_get_last_error(src->storage, &error); + if ((src->storage->ns->flags & NAMESPACE_FLAG_HIDDEN) != 0) + str = t_strdup_printf("%s (mailbox %s)", str, src->name); + else { + str = t_strdup_printf("%s (mailbox %s%s)", str, + src->storage->ns->prefix, src->name); + } + mail_storage_set_error(dest->storage, error, str); +} + static int virtual_get_list_settings(struct mailbox_list_settings *list_set, const char *data, struct mail_storage *storage, @@ -203,7 +231,7 @@ static int virtual_mailboxes_open(struct virtual_mailbox *mbox, else { /* failed */ for (; i > 0; i--) { - mailbox_close(&bboxes[i-1]->box); + (void)mailbox_close(&bboxes[i-1]->box); array_free(&bboxes[i-1]->uids); } return -1; @@ -300,6 +328,7 @@ virtual_mailbox_open(struct mail_storage *_storage, const char *name, static int virtual_storage_mailbox_close(struct mailbox *box) { struct virtual_mailbox *mbox = (struct virtual_mailbox *)box; + struct mail_storage *storage; struct virtual_backend_box **bboxes; unsigned int i, count; int ret = 0; @@ -310,8 +339,12 @@ static int virtual_storage_mailbox_close(struct mailbox *box) for (i = 0; i < count; i++) { if (bboxes[i]->search_result != NULL) mailbox_search_result_free(&bboxes[i]->search_result); - if (mailbox_close(&bboxes[i]->box) < 0) + + storage = bboxes[i]->box->storage; + if (mailbox_close(&bboxes[i]->box) < 0) { + virtual_copy_error(box->storage, storage); ret = -1; + } array_free(&bboxes[i]->sync_pending_removes); array_free(&bboxes[i]->uids); } diff --git a/src/plugins/virtual/virtual-storage.h b/src/plugins/virtual/virtual-storage.h index e57c027ba1..619ddc0e46 100644 --- a/src/plugins/virtual/virtual-storage.h +++ b/src/plugins/virtual/virtual-storage.h @@ -129,6 +129,9 @@ virtual_mail_alloc(struct mailbox_transaction_context *t, struct mailbox_sync_context * virtual_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); +void virtual_copy_error(struct mail_storage *dest, struct mail_storage *src); +void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src); + void virtual_transaction_class_init(void); void virtual_transaction_class_deinit(void); diff --git a/src/plugins/virtual/virtual-sync.c b/src/plugins/virtual/virtual-sync.c index 3f4064c1c6..17654c2a08 100644 --- a/src/plugins/virtual/virtual-sync.c +++ b/src/plugins/virtual/virtual-sync.c @@ -1112,8 +1112,12 @@ static int virtual_sync_backend_boxes(struct virtual_sync_context *ctx) i_array_init(&ctx->all_adds, 128); bboxes = array_get(&ctx->mbox->backend_boxes, &count); for (i = 0; i < count; i++) { - if (virtual_sync_backend_box(ctx, bboxes[i]) < 0) + if (virtual_sync_backend_box(ctx, bboxes[i]) < 0) { + /* backend failed, copy the error */ + virtual_box_copy_error(&ctx->mbox->ibox.box, + bboxes[i]->box); return -1; + } } if (!ctx->mbox->uids_mapped) { @@ -1151,7 +1155,7 @@ static int virtual_sync_finish(struct virtual_sync_context *ctx, bool success) mail_index_sync_rollback(&ctx->index_sync_ctx); } i_free(ctx); - return 0; + return ret; } static int virtual_sync(struct virtual_mailbox *mbox,