]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Virtual mailboxes: Fixes to handling errors.
authorTimo Sirainen <tss@iki.fi>
Sat, 25 Oct 2008 20:56:35 +0000 (23:56 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 25 Oct 2008 20:56:35 +0000 (23:56 +0300)
--HG--
branch : HEAD

src/plugins/virtual/virtual-mail.c
src/plugins/virtual/virtual-storage.c
src/plugins/virtual/virtual-storage.h
src/plugins/virtual/virtual-sync.c

index cb069274d3321acbcee5762b87c8908955c39507..b403d68cfef43e9e97b7fabc0a6602b3082a2a34 100644 (file)
@@ -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)
index cf83f74d107c88917e7db273f40e64ddd83860af..9aa68a5bbd3ac1d27aac3a5a5542ae818d65203b 100644 (file)
@@ -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);
        }
index e57c027ba1c5e037fa5e452ad69739791e21d1d7..619ddc0e4606273d2a4527619f5bd4d4eda09996 100644 (file)
@@ -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);
 
index 3f4064c1c656111ab9dc144068380aefcfde1720..17654c2a08fdb78eb9d8ff9398d1a70b841c90eb 100644 (file)
@@ -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,