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);
}
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)
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,