]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Add mailbox_list_last_error_push/pop()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Jul 2017 14:36:28 +0000 (17:36 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 10 Jul 2017 13:22:17 +0000 (16:22 +0300)
These are similar to mail_storage_last_error_push/pop()

src/lib-storage/mailbox-list-private.h
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h

index 8e190ce7c40c157b9200d1d7d44d54920d9fba2a..6e536f5809f5fd256df1bfb1129387fb54abf433 100644 (file)
@@ -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;
 
index b377801df3c48e339d2c3df79b4f9eaeff5e8e00..7641c415c27eb23ada1fbd83ae7cfab8d961953f 100644 (file)
@@ -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)
index 6a2595edb8e12a50f5401492151141960d7f6906..3cb09c53f375b83c212d3ca561b75d4e4f812e2d 100644 (file)
@@ -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,