From: Timo Sirainen Date: Thu, 6 Jul 2017 14:36:28 +0000 (+0300) Subject: lib-storage: Add mailbox_list_last_error_push/pop() X-Git-Tag: 2.3.0.rc1~1286 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4654cf737f538f5de032b8c9908913f121917366;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Add mailbox_list_last_error_push/pop() These are similar to mail_storage_last_error_push/pop() --- diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index 8e190ce7c4..6e536f5809 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -134,6 +134,7 @@ struct mailbox_list { char *error_string; enum mail_error error; bool temporary_error; + ARRAY(struct mail_storage_error) error_stack; ARRAY(union mailbox_list_module_context *) module_contexts; diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index b377801df3..7641c415c2 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -791,6 +791,11 @@ void mailbox_list_destroy(struct mailbox_list **_list) mailbox_tree_deinit(&list->subscriptions); if (list->changelog != NULL) mailbox_log_free(&list->changelog); + + if (array_is_created(&list->error_stack)) { + i_assert(array_count(&list->error_stack) == 0); + array_free(&list->error_stack); + } list->v.deinit(list); } @@ -1907,6 +1912,35 @@ bool mailbox_list_set_error_from_errno(struct mailbox_list *list) return TRUE; } +void mailbox_list_last_error_push(struct mailbox_list *list) +{ + struct mail_storage_error *err; + + if (!array_is_created(&list->error_stack)) + i_array_init(&list->error_stack, 2); + err = array_append_space(&list->error_stack); + err->error_string = i_strdup(list->error_string); + err->error = list->error; + err->last_error_is_internal = list->last_error_is_internal; + if (err->last_error_is_internal) + err->last_internal_error = i_strdup(list->last_internal_error); +} + +void mailbox_list_last_error_pop(struct mailbox_list *list) +{ + unsigned int count = array_count(&list->error_stack); + const struct mail_storage_error *err = + array_idx(&list->error_stack, count-1); + + i_free(list->error_string); + i_free(list->last_internal_error); + list->error_string = err->error_string; + list->error = err->error; + list->last_error_is_internal = err->last_error_is_internal; + list->last_internal_error = err->last_internal_error; + array_delete(&list->error_stack, count-1, 1); +} + int mailbox_list_init_fs(struct mailbox_list *list, const char *driver, const char *args, const char *root_dir, struct fs **fs_r, const char **error_r) diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h index 6a2595edb8..3cb09c53f3 100644 --- a/src/lib-storage/mailbox-list.h +++ b/src/lib-storage/mailbox-list.h @@ -278,6 +278,12 @@ const char * ATTR_NOWARN_UNUSED_RESULT mailbox_list_get_last_internal_error(struct mailbox_list *list, enum mail_error *error_r); +/* Save the last error until it's popped. This is useful for cases where the + list operation has already failed, but the cleanup code path changes the + error to something else unwanted. */ +void mailbox_list_last_error_push(struct mailbox_list *list); +void mailbox_list_last_error_pop(struct mailbox_list *list); + /* Create a fs based on the settings in the given mailbox_list. */ int mailbox_list_init_fs(struct mailbox_list *list, const char *driver, const char *args, const char *root_dir,