changeset 17708:3e461af4f0ff

lib-storage: Added mail_storage_last_error_push/pop()
author Timo Sirainen <tss@iki.fi>
date Tue, 12 Aug 2014 19:05:14 +0300
parents 8abf7eea2966
children 8948c0d91369
files src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h
diffstat 3 files changed, 39 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/mail-storage-private.h	Tue Aug 12 18:48:03 2014 +0300
+++ b/src/lib-storage/mail-storage-private.h	Tue Aug 12 19:05:14 2014 +0300
@@ -91,6 +91,11 @@
 	uoff_t size;
 };
 
+struct mail_storage_error {
+	char *error_string;
+	enum mail_error error;
+};
+
 struct mail_storage {
 	const char *name;
 	enum mail_storage_class_flags class_flags;
@@ -112,6 +117,7 @@
 
 	char *error_string;
 	enum mail_error error;
+	ARRAY(struct mail_storage_error) error_stack;
 
         const struct mail_storage *storage_class;
 	struct mail_user *user;
--- a/src/lib-storage/mail-storage.c	Tue Aug 12 18:48:03 2014 +0300
+++ b/src/lib-storage/mail-storage.c	Tue Aug 12 19:05:14 2014 +0300
@@ -432,6 +432,10 @@
 
 	storage->v.destroy(storage);
 	i_free(storage->error_string);
+	if (array_is_created(&storage->error_stack)) {
+		i_assert(array_count(&storage->error_stack) == 0);
+		array_free(&storage->error_stack);
+	}
 
 	*_storage = NULL;
 	pool_unref(&storage->pool);
@@ -595,6 +599,29 @@
 	return error;
 }
 
+void mail_storage_last_error_push(struct mail_storage *storage)
+{
+	struct mail_storage_error *err;
+
+	if (!array_is_created(&storage->error_stack))
+		i_array_init(&storage->error_stack, 2);
+	err = array_append_space(&storage->error_stack);
+	err->error_string = i_strdup(storage->error_string);
+	err->error = storage->error;
+}
+
+void mail_storage_last_error_pop(struct mail_storage *storage)
+{
+	unsigned int count = array_count(&storage->error_stack);
+	struct mail_storage_error *err =
+		array_idx(&storage->error_stack, count-1);
+
+	i_free(storage->error_string);
+	storage->error_string = err->error_string;
+	storage->error = err->error;
+	array_delete(&storage->error_stack, count-1, 1);
+}
+
 bool mail_storage_is_mailbox_file(struct mail_storage *storage)
 {
 	return (storage->class_flags &
--- a/src/lib-storage/mail-storage.h	Tue Aug 12 18:48:03 2014 +0300
+++ b/src/lib-storage/mail-storage.h	Tue Aug 12 19:05:14 2014 +0300
@@ -460,6 +460,12 @@
 /* Wrapper for mail_storage_get_last_error(); */
 enum mail_error mailbox_get_last_mail_error(struct mailbox *box);
 
+/* Save the last error until it's popped. This is useful for cases where the
+   storage has already failed, but the cleanup code path changes the error to
+   something else unwanted. */
+void mail_storage_last_error_push(struct mail_storage *storage);
+void mail_storage_last_error_pop(struct mail_storage *storage);
+
 /* Returns TRUE if mailboxes are files. */
 bool mail_storage_is_mailbox_file(struct mail_storage *storage) ATTR_PURE;