From: Martti Rannanjärvi Date: Thu, 16 Mar 2017 09:12:29 +0000 (+0200) Subject: lib-storage: Add mail_storage_get_last_internal_error() X-Git-Tag: 2.2.29.rc1~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dcf7e4f93a2fbd31d17b4ac71bf8c611fc5d22ae;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Add mail_storage_get_last_internal_error() This returns the error given to mail_storage_set_critical(). --- diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 48a39f4168..7e7239edb9 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -128,6 +128,9 @@ struct mail_storage { * uniqueness checking (via strcmp) and never used as a path. */ const char *unique_root_dir; + /* Last error set in mail_storage_set_critical(). */ + char *last_internal_error; + char *error_string; enum mail_error error; ARRAY(struct mail_storage_error) error_stack; @@ -152,6 +155,7 @@ struct mail_storage { /* Failed to create shared attribute dict, don't try again */ unsigned int shared_attr_dict_failed:1; + unsigned int last_error_is_internal:1; }; struct mail_attachment_part { diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 1a215f0e24..a9206b2142 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -452,6 +452,7 @@ void mail_storage_unref(struct mail_storage **_storage) DLLIST_REMOVE(&storage->user->storages, storage); storage->v.destroy(storage); + i_free(storage->last_internal_error); i_free(storage->error_string); if (array_is_created(&storage->error_stack)) { i_assert(array_count(&storage->error_stack) == 0); @@ -487,6 +488,8 @@ void mail_storage_clear_error(struct mail_storage *storage) { i_free_and_null(storage->error_string); + i_free(storage->last_internal_error); + storage->last_error_is_internal = FALSE; storage->error = MAIL_ERROR_NONE; } @@ -497,6 +500,7 @@ void mail_storage_set_error(struct mail_storage *storage, i_free(storage->error_string); storage->error_string = i_strdup(string); } + storage->last_error_is_internal = FALSE; storage->error = error; } @@ -516,9 +520,12 @@ void mail_storage_set_critical(struct mail_storage *storage, { va_list va; + i_free(storage->last_internal_error); va_start(va, fmt); - i_error("%s", t_strdup_vprintf(fmt, va)); + storage->last_internal_error = i_strdup_vprintf(fmt, va); va_end(va); + storage->last_error_is_internal = TRUE; + i_error("%s", storage->last_internal_error); /* critical errors may contain sensitive data, so let user see only "Internal error" with a timestamp to make it @@ -526,6 +533,25 @@ void mail_storage_set_critical(struct mail_storage *storage, mail_storage_set_internal_error(storage); } +const char *mail_storage_get_last_internal_error(struct mail_storage *storage, + enum mail_error *error_r) +{ + if (error_r != NULL) + *error_r = storage->error; + if (storage->last_error_is_internal) { + i_assert(storage->last_internal_error != NULL); + return storage->last_internal_error; + } + return mail_storage_get_last_error(storage, error_r); +} + +const char *mailbox_get_last_internal_error(struct mailbox *box, + enum mail_error *error_r) +{ + return mail_storage_get_last_internal_error(mailbox_get_storage(box), + error_r); +} + void mail_storage_copy_error(struct mail_storage *dest, struct mail_storage *src) { diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 06207e8dcf..3dc77dd449 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -481,6 +481,14 @@ mailbox_get_last_error(struct mailbox *box, enum mail_error *error_r) /* Wrapper for mail_storage_get_last_error(); */ enum mail_error mailbox_get_last_mail_error(struct mailbox *box); +const char * ATTR_NOWARN_UNUSED_RESULT +mail_storage_get_last_internal_error(struct mail_storage *storage, + enum mail_error *error_r) ATTR_NULL(2); +/* Wrapper for mail_storage_get_last_internal_error(); */ +const char * ATTR_NOWARN_UNUSED_RESULT +mailbox_get_last_internal_error(struct mailbox *box, + enum mail_error *error_r) ATTR_NULL(2); + /* 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. */