[dovecot-cvs] dovecot/src/lib-storage Makefile.am, 1.17, 1.18 mail-error.c, NONE, 1.1 mail-error.h, NONE, 1.1 mail-storage-private.h, 1.55, 1.56 mail-storage.c, 1.83, 1.84 mail-storage.h, 1.134, 1.135 mailbox-list-private.h, 1.7, 1.8 mailbox-list.c, 1.16, 1.17 mailbox-list.h, 1.10, 1.11

tss at dovecot.org tss at dovecot.org
Sun May 13 20:10:52 EEST 2007


Update of /var/lib/cvs/dovecot/src/lib-storage
In directory talvi:/tmp/cvs-serv20721/lib-storage

Modified Files:
	Makefile.am mail-storage-private.h mail-storage.c 
	mail-storage.h mailbox-list-private.h mailbox-list.c 
	mailbox-list.h 
Added Files:
	mail-error.c mail-error.h 
Log Message:
Error handling rewrite.



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- Makefile.am	3 Apr 2007 08:34:29 -0000	1.17
+++ Makefile.am	13 May 2007 17:10:49 -0000	1.18
@@ -11,6 +11,7 @@
 libstorage_a_SOURCES = \
 	mail.c \
 	mail-copy.c \
+	mail-error.c \
 	mail-namespace.c \
 	mail-search.c \
 	mail-storage.c \
@@ -19,6 +20,7 @@
 
 headers = \
 	mail-copy.h \
+	mail-error.h \
 	mail-namespace.h \
 	mail-search.h \
 	mail-storage.h \

--- NEW FILE: mail-error.c ---
/* Copyright (C) 2007 Timo Sirainen */

#include "lib.h"
#include "mail-error.h"

bool mail_error_from_errno(enum mail_error *error_r,
			   const char **error_string_r)
{
	if (ENOACCESS(errno)) {
		*error_r = MAIL_ERROR_PERM;
		*error_string_r = MAIL_ERRSTR_NO_PERMISSION;
	} else if (ENOSPACE(errno)) {
		*error_r = MAIL_ERROR_NOSPACE;
		*error_string_r = MAIL_ERRSTR_NO_SPACE;
	} else if (ENOTFOUND(errno)) {
		*error_r = MAIL_ERROR_NOTFOUND;
		*error_string_r = errno != ELOOP ? "Not found" :
			"Directory structure is broken";
	} else {
		return FALSE;
	}
	return TRUE;
}

--- NEW FILE: mail-error.h ---
#ifndef __MAIL_ERROR_H
#define __MAIL_ERROR_H

/* Some error strings that should be used everywhere to avoid
   permissions checks from revealing mailbox's existence */
#define MAIL_ERRSTR_MAILBOX_NOT_FOUND "Mailbox doesn't exist: %s"
#define MAIL_ERRSTR_NO_PERMISSION "Permission denied"

/* And just for making error strings consistent: */
#define MAIL_ERRSTR_NO_SPACE "Not enough disk space"
#define MAIL_ERRSTR_LOCK_TIMEOUT "Timeout while waiting for lock"

#define T_MAIL_ERR_MAILBOX_NOT_FOUND(name) \
	t_strdup_printf(MAIL_ERRSTR_MAILBOX_NOT_FOUND, name)

enum mail_error {
	MAIL_ERROR_NONE = 0,

	/* Temporary internal error */
	MAIL_ERROR_TEMP,
	/* It's not possible to do the wanted operation */
	MAIL_ERROR_NOTPOSSIBLE,
	/* Invalid parameters (eg. mailbox name not valid) */
	MAIL_ERROR_PARAMS,
	/* No permission to do the request */
	MAIL_ERROR_PERM,
	/* Out of disk space or quota */
	MAIL_ERROR_NOSPACE,
	/* Item (eg. mailbox) doesn't exist or it's not visible to us */
	MAIL_ERROR_NOTFOUND
};

/* Convert errno to mail_error and an error string. Returns TRUE if successful,
   FALSE if we couldn't handle the errno. */
bool mail_error_from_errno(enum mail_error *error_r,
			   const char **error_string_r);

#endif

Index: mail-storage-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage-private.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- mail-storage-private.h	13 May 2007 15:46:08 -0000	1.55
+++ mail-storage-private.h	13 May 2007 17:10:49 -0000	1.56
@@ -52,7 +52,9 @@
 /* private: */
 	pool_t pool;
 
-	char *error;
+	char *error_string;
+	enum mail_error error;
+
 	struct mail_namespace *ns;
 	struct mailbox_list *list;
 
@@ -65,10 +67,6 @@
 
 	/* Module-specific contexts. See mail_storage_module_id. */
 	ARRAY_DEFINE(module_contexts, union mail_storage_module_context *);
-
-	/* Internal temporary error, as opposed to visible user errors like
-	   "permission denied" or "out of disk space" */
-	unsigned int temporary_error:1;
 };
 
 struct mailbox_vfuncs {
@@ -289,15 +287,13 @@
    but user sees only "internal error" message. */
 void mail_storage_clear_error(struct mail_storage *storage);
 void mail_storage_set_error(struct mail_storage *storage,
-			    const char *fmt, ...) __attr_format__(2, 3);
+			    enum mail_error error, const char *string);
 void mail_storage_set_critical(struct mail_storage *storage,
 			       const char *fmt, ...) __attr_format__(2, 3);
 void mail_storage_set_internal_error(struct mail_storage *storage);
-
-const char *mail_storage_class_get_last_error(struct mail_storage *storage);
+bool mail_storage_set_error_from_errno(struct mail_storage *storage);
 
 enum mailbox_list_flags
 mail_storage_get_list_flags(enum mail_storage_flags storage_flags);
-bool mail_storage_errno2str(const char **error_r);
 
 #endif

Index: mail-storage.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- mail-storage.c	13 May 2007 16:13:48 -0000	1.83
+++ mail-storage.c	13 May 2007 17:10:49 -0000	1.84
@@ -225,7 +225,7 @@
 		storage->v.destroy(storage);
 
 	mailbox_list_deinit(storage->list);
-	i_free(storage->error);
+	i_free(storage->error_string);
 	pool_unref(storage->pool);
 
 	index_storage_destroy_unrefed();
@@ -233,23 +233,17 @@
 
 void mail_storage_clear_error(struct mail_storage *storage)
 {
-	i_free(storage->error);
-	storage->error = NULL;
+	i_free_and_null(storage->error_string);
 
-	storage->temporary_error = FALSE;
+	storage->error = MAIL_ERROR_NONE;
 }
 
-void mail_storage_set_error(struct mail_storage *storage, const char *fmt, ...)
+void mail_storage_set_error(struct mail_storage *storage,
+			    enum mail_error error, const char *string)
 {
-	va_list va;
-
-	mail_storage_clear_error(storage);
-
-	if (fmt != NULL) {
-		va_start(va, fmt);
-		storage->error = i_strdup_vprintf(fmt, va);
-		va_end(va);
-	}
+	i_free(storage->error_string);
+	storage->error_string = i_strdup(string);
+	storage->error = error;
 }
 
 void mail_storage_set_internal_error(struct mail_storage *storage)
@@ -259,11 +253,11 @@
 
 	tm = localtime(&ioloop_time);
 
-	i_free(storage->error);
-	storage->error =
+	i_free(storage->error_string);
+	storage->error_string =
 		strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
 		i_strdup(str) : i_strdup(CRITICAL_MSG);
-	storage->temporary_error = TRUE;
+	storage->error = MAIL_ERROR_TEMP;
 }
 
 void mail_storage_set_critical(struct mail_storage *storage,
@@ -313,7 +307,8 @@
 	mail_storage_clear_error(storage);
 
 	if (!mailbox_list_is_valid_create_name(storage->list, name)) {
-		mail_storage_set_error(storage, "Invalid mailbox name");
+		mail_storage_set_error(storage, MAIL_ERROR_PARAMS,
+				       "Invalid mailbox name");
 		return -1;
 	}
 
@@ -321,14 +316,15 @@
 }
 
 const char *mail_storage_get_last_error(struct mail_storage *storage,
-					bool *temporary_error_r)
+					enum mail_error *error_r)
 {
-	*temporary_error_r = storage->temporary_error;
+	*error_r = storage->error;
 
 	/* We get here only in error situations, so we have to return some
 	   error. If storage->error is NULL, it means we forgot to set it at
 	   some point.. */
-	return storage->error != NULL ? storage->error : "Unknown error";
+	return storage->error_string != NULL ? storage->error_string :
+		"Unknown internal error";
 }
 
 const char *mail_storage_get_mailbox_path(struct mail_storage *storage,
@@ -377,16 +373,15 @@
 	return list_flags;
 }
 
-bool mail_storage_errno2str(const char **error_r)
+bool mail_storage_set_error_from_errno(struct mail_storage *storage)
 {
-	if (ENOACCESS(errno))
-		*error_r = MAILBOX_LIST_ERR_NO_PERMISSION;
-	else if (ENOSPACE(errno))
-		*error_r = "Not enough disk space";
-	else if (ENOTFOUND(errno))
-		*error_r = "Directory structure is broken";
-	else
+	const char *error_string;
+	enum mail_error error;
+
+	if (!mail_error_from_errno(&error, &error_string))
 		return FALSE;
+
+	mail_storage_set_error(storage, error, error_string);
 	return TRUE;
 }
 
@@ -399,7 +394,8 @@
 	mail_storage_clear_error(storage);
 
 	if (!mailbox_list_is_valid_existing_name(storage->list, name)) {
-		mail_storage_set_error(storage, "Invalid mailbox name");
+		mail_storage_set_error(storage, MAIL_ERROR_PARAMS,
+				       "Invalid mailbox name");
 		return NULL;
 	}
 

Index: mail-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage.h,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -d -r1.134 -r1.135
--- mail-storage.h	13 May 2007 16:13:48 -0000	1.134
+++ mail-storage.h	13 May 2007 17:10:49 -0000	1.135
@@ -4,6 +4,7 @@
 struct message_size;
 
 #include "mail-types.h"
+#include "mail-error.h"
 #include "mailbox-list.h"
 
 /* If some operation is taking long, call notify_ok every n seconds. */
@@ -228,7 +229,7 @@
 
 /* Returns the error message of last occurred error. */
 const char *mail_storage_get_last_error(struct mail_storage *storage,
-					bool *temporary_error_r);
+					enum mail_error *error_r);
 
 /* Returns path to the given mailbox, or NULL if mailbox doesn't exist in
    filesystem. is_file_r is set to TRUE if returned path points to a file,

Index: mailbox-list-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mailbox-list-private.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mailbox-list-private.h	17 Apr 2007 15:39:30 -0000	1.7
+++ mailbox-list-private.h	13 May 2007 17:10:49 -0000	1.8
@@ -1,11 +1,6 @@
 #ifndef __MAILBOX_LIST_PRIVATE_H
 #define __MAILBOX_LIST_PRIVATE_H
 
-/* Some error strings that should be used everywhere to avoid
-   permissions checks from revealing mailbox's existence */
-#define MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND "Mailbox doesn't exist: %s"
-#define MAILBOX_LIST_ERR_NO_PERMISSION "Permission denied"
-
 #include "mail-namespace.h"
 #include "mailbox-list.h"
 
@@ -78,7 +73,8 @@
 	uid_t cached_uid;
 	gid_t cached_gid;
 
-	char *error;
+	char *error_string;
+	enum mail_error error;
 	bool temporary_error;
 
 	ARRAY_DEFINE(module_contexts, union mailbox_list_module_context *);
@@ -103,9 +99,11 @@
 enum mailbox_list_file_type mailbox_list_get_file_type(const struct dirent *d);
 
 void mailbox_list_clear_error(struct mailbox_list *list);
-void mailbox_list_set_error(struct mailbox_list *list, const char *error);
+void mailbox_list_set_error(struct mailbox_list *list,
+			    enum mail_error error, const char *string);
 void mailbox_list_set_critical(struct mailbox_list *list, const char *fmt, ...)
 	__attr_format__(2, 3);
 void mailbox_list_set_internal_error(struct mailbox_list *list);
+bool mailbox_list_set_error_from_errno(struct mailbox_list *list);
 
 #endif

Index: mailbox-list.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mailbox-list.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- mailbox-list.c	11 Apr 2007 19:28:23 -0000	1.16
+++ mailbox-list.c	13 May 2007 17:10:49 -0000	1.17
@@ -154,7 +154,7 @@
 
 void mailbox_list_deinit(struct mailbox_list *list)
 {
-	i_free_and_null(list->error);
+	i_free_and_null(list->error_string);
 
 	list->v.deinit(list);
 }
@@ -309,11 +309,13 @@
 int mailbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
 {
 	if (!mailbox_list_is_valid_existing_name(list, name)) {
-		mailbox_list_set_error(list, "Invalid mailbox name");
+		mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
+				       "Invalid mailbox name");
 		return -1;
 	}
 	if (strcmp(name, "INBOX") == 0) {
-		mailbox_list_set_error(list, "INBOX can't be deleted.");
+		mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
+				       "INBOX can't be deleted.");
 		return -1;
 	}
 	return list->v.delete_mailbox(list, name);
@@ -324,7 +326,8 @@
 {
 	if (!mailbox_list_is_valid_existing_name(list, oldname) ||
 	    !mailbox_list_is_valid_create_name(list, newname)) {
-		mailbox_list_set_error(list, "Invalid mailbox name");
+		mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
+				       "Invalid mailbox name");
 		return -1;
 	}
 
@@ -415,26 +418,28 @@
 }
 
 const char *mailbox_list_get_last_error(struct mailbox_list *list,
-					bool *temporary_error_r)
+					enum mail_error *error_r)
 {
-	*temporary_error_r = list->temporary_error;
+	*error_r = list->error;
 
-	return list->error;
+	return list->error_string != NULL ? list->error_string :
+		"Unknown internal list error";
 }
 
 void mailbox_list_clear_error(struct mailbox_list *list)
 {
-	i_free_and_null(list->error);
+	i_free_and_null(list->error_string);
 
-	list->temporary_error = FALSE;
+	list->error = MAIL_ERROR_NONE;
 }
 
-void mailbox_list_set_error(struct mailbox_list *list, const char *error)
+void mailbox_list_set_error(struct mailbox_list *list,
+			    enum mail_error error, const char *string)
 {
-	i_free(list->error);
-	list->error = i_strdup(error);
+	i_free(list->error_string);
+	list->error_string = i_strdup(string);
 
-	list->temporary_error = FALSE;
+	list->error = error;
 }
 
 void mailbox_list_set_internal_error(struct mailbox_list *list)
@@ -444,11 +449,11 @@
 
 	tm = localtime(&ioloop_time);
 
-	i_free(list->error);
-	list->error =
+	i_free(list->error_string);
+	list->error_string =
 		strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
 		i_strdup(str) : i_strdup(CRITICAL_MSG);
-	list->temporary_error = TRUE;
+	list->error = MAIL_ERROR_TEMP;
 }
 
 void mailbox_list_set_critical(struct mailbox_list *list, const char *fmt, ...)
@@ -464,3 +469,15 @@
 	   easier to look from log files the actual error message. */
 	mailbox_list_set_internal_error(list);
 }
+
+bool mailbox_list_set_error_from_errno(struct mailbox_list *list)
+{
+	const char *error_string;
+	enum mail_error error;
+
+	if (!mail_error_from_errno(&error, &error_string))
+		return FALSE;
+
+	mailbox_list_set_error(list, error, error_string);
+	return TRUE;
+}

Index: mailbox-list.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mailbox-list.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mailbox-list.h	17 Apr 2007 15:39:30 -0000	1.10
+++ mailbox-list.h	13 May 2007 17:10:49 -0000	1.11
@@ -1,6 +1,8 @@
 #ifndef __MAILBOX_LIST_H
 #define __MAILBOX_LIST_H
 
+#include "mail-error.h"
+
 struct mail_namespace;
 struct mailbox_list;
 struct mailbox_list_iterate_context;
@@ -176,6 +178,6 @@
 
 /* Returns the error message of last occurred error. */
 const char *mailbox_list_get_last_error(struct mailbox_list *list,
-					bool *temporary_error_r);
+					enum mail_error *error_r);
 
 #endif



More information about the dovecot-cvs mailing list