Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5613:f717fb4b31c0 HEAD
Error handling rewrite.
line wrap: on
line diff
--- a/src/deliver/deliver.c Sun May 13 19:53:41 2007 +0300 +++ b/src/deliver/deliver.c Sun May 13 20:10:48 2007 +0300 @@ -81,7 +81,7 @@ { struct mail_namespace *ns; struct mailbox *box; - bool temp; + enum mail_error error; ns = mail_namespace_find(namespaces, &name); if (ns == NULL) { @@ -95,11 +95,11 @@ if (box != NULL || no_mailbox_autocreate) return box; - (void)mail_storage_get_last_error(ns->storage, &temp); - if (temp) + (void)mail_storage_get_last_error(ns->storage, &error); + if (error != MAIL_ERROR_NOTFOUND) return NULL; - /* probably the mailbox just doesn't exist. try creating it. */ + /* try creating it. */ if (mail_storage_mailbox_create(ns->storage, name, FALSE) < 0) return NULL; @@ -714,25 +714,29 @@ } if (ret < 0) { - const char *error, *msgid; - bool temporary_error; + const char *error_string, *msgid; + enum mail_error error; int ret; - error = mail_storage_get_last_error(storage, &temporary_error); - if (temporary_error) + error_string = mail_storage_get_last_error(ns->storage, &error); + if (error != MAIL_ERROR_NOSPACE) { + /* Saving to INBOX should always work unless + we're over quota. If it didn't, it's probably a + configuration problem. */ return EX_TEMPFAIL; + } msgid = mail_get_first_header(mail, "Message-ID"); i_info("msgid=%s: Rejected: %s", msgid == NULL ? "" : str_sanitize(msgid, 80), - str_sanitize(error, 512)); + str_sanitize(error_string, 512)); /* we'll have to reply with permanent failure */ if (stderr_rejection) { - fprintf(stderr, "%s\n", error); + fprintf(stderr, "%s\n", error_string); return EX_NOPERM; } - ret = mail_send_rejection(mail, destination, error); + ret = mail_send_rejection(mail, destination, error_string); if (ret != 0) return ret < 0 ? EX_TEMPFAIL : ret; /* ok, rejection sent */
--- a/src/imap/cmd-fetch.c Sun May 13 19:53:41 2007 +0300 +++ b/src/imap/cmd-fetch.c Sun May 13 20:10:48 2007 +0300 @@ -78,8 +78,8 @@ if (ctx->failed) { struct mail_storage *storage; - const char *error; - bool temporary_error; + const char *error_string; + enum mail_error error; if (ctx->client->output->closed) { client_disconnect(cmd->client, "Disconnected"); @@ -87,11 +87,11 @@ } storage = mailbox_get_storage(cmd->client->mailbox); - error = mail_storage_get_last_error(storage, &temporary_error); + error_string = mail_storage_get_last_error(storage, &error); /* We never want to reply NO to FETCH requests, BYE is preferrable (see imap-ml for reasons). */ - client_disconnect_with_error(cmd->client, error); + client_disconnect_with_error(cmd->client, error_string); return TRUE; }
--- a/src/imap/commands-util.c Sun May 13 19:53:41 2007 +0300 +++ b/src/imap/commands-util.c Sun May 13 20:10:48 2007 +0300 @@ -146,18 +146,18 @@ void client_send_list_error(struct client_command_context *cmd, struct mailbox_list *list) { - const char *error; - bool temporary_error; + const char *error_string; + enum mail_error error; - error = mailbox_list_get_last_error(list, &temporary_error); - client_send_tagline(cmd, t_strconcat("NO ", error, NULL)); + error_string = mailbox_list_get_last_error(list, &error); + client_send_tagline(cmd, t_strconcat("NO ", error_string, NULL)); } void client_send_storage_error(struct client_command_context *cmd, struct mail_storage *storage) { - const char *error; - bool temporary_error; + const char *error_string; + enum mail_error error; if (cmd->client->mailbox != NULL && mailbox_is_inconsistent(cmd->client->mailbox)) { @@ -167,15 +167,15 @@ return; } - error = mail_storage_get_last_error(storage, &temporary_error); - client_send_tagline(cmd, t_strconcat("NO ", error, NULL)); + error_string = mail_storage_get_last_error(storage, &error); + client_send_tagline(cmd, t_strconcat("NO ", error_string, NULL)); } void client_send_untagged_storage_error(struct client *client, struct mail_storage *storage) { - const char *error; - bool temporary_error; + const char *error_string; + enum mail_error error; if (client->mailbox != NULL && mailbox_is_inconsistent(client->mailbox)) { @@ -185,8 +185,8 @@ return; } - error = mail_storage_get_last_error(storage, &temporary_error); - client_send_line(client, t_strconcat("* NO ", error, NULL)); + error_string = mail_storage_get_last_error(storage, &error); + client_send_line(client, t_strconcat("* NO ", error_string, NULL)); } static bool is_valid_keyword(struct client_command_context *cmd,
--- a/src/imap/imap-search.c Sun May 13 19:53:41 2007 +0300 +++ b/src/imap/imap-search.c Sun May 13 20:10:48 2007 +0300 @@ -19,7 +19,7 @@ struct mail_search_seqset **seqset_r, const char **error_r) { struct mail_search_seqset *seqset, **p; - bool temporary, last; + bool last; *seqset_r = imap_messageset_parse(pool, uidset); if (*seqset_r == NULL) { @@ -38,8 +38,9 @@ if (mailbox_get_uids(box, seqset->seq1, seqset->seq2, &seqset->seq1, &seqset->seq2) < 0) { struct mail_storage *storage = mailbox_get_storage(box); - *error_r = mail_storage_get_last_error(storage, - &temporary); + enum mail_error error; + + *error_r = mail_storage_get_last_error(storage, &error); return -1; }
--- a/src/lib-storage/Makefile.am Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/Makefile.am Sun May 13 20:10:48 2007 +0300 @@ -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 \
--- a/src/lib-storage/index/cydir/cydir-save.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-save.c Sun May 13 20:10:48 2007 +0300 @@ -125,16 +125,14 @@ int cydir_save_continue(struct mail_save_context *_ctx) { struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx; + struct mail_storage *storage = &ctx->mbox->storage->storage; if (ctx->failed) return -1; if (o_stream_send_istream(ctx->output, ctx->input) < 0) { - if (ENOSPACE(ctx->output->stream_errno)) { - mail_storage_set_error(&ctx->mbox->storage->storage, - "Not enough disk space"); - } else { - mail_storage_set_critical(&ctx->mbox->storage->storage, + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, "o_stream_send_istream(%s) failed: %m", cydir_get_save_path(ctx, ctx->mail_count)); }
--- a/src/lib-storage/index/cydir/cydir-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-storage.c Sun May 13 20:10:48 2007 +0300 @@ -141,16 +141,11 @@ static int create_cydir(struct mail_storage *storage, const char *path) { - const char *error; - if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) { - if (mail_storage_errno2str(&error)) { - mail_storage_set_error(storage, "%s", error); - return -1; + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, + "mkdir(%s) failed: %m", path); } - - mail_storage_set_critical(storage, "mkdir(%s) failed: %m", - path); return -1; } return 0; @@ -235,8 +230,8 @@ if (stat(path, &st) == 0) { return cydir_open(storage, name, flags); } else if (errno == ENOENT) { - mail_storage_set_error(_storage, - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name); + mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return NULL; } else { mail_storage_set_critical(_storage, "stat(%s) failed: %m", @@ -255,7 +250,8 @@ path = mailbox_list_get_path(_storage->list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(path, &st) == 0) { - mail_storage_set_error(_storage, "Mailbox already exists"); + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, + "Mailbox already exists"); return -1; } @@ -274,10 +270,7 @@ dir = opendir(path); if (dir == NULL) { - if (errno == ENOENT) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); - } else { + if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "opendir(%s) failed: %m", path); } @@ -327,8 +320,9 @@ } if (!unlinked_something) { - mailbox_list_set_error(list, t_strdup_printf( - "Directory %s isn't empty, can't delete it.", name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + t_strdup_printf("Directory %s isn't empty, " + "can't delete it.", name)); return -1; } return 0; @@ -354,8 +348,8 @@ /* check if the mailbox actually exists */ src = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(src, &st) != 0 && errno == ENOENT) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; }
--- a/src/lib-storage/index/dbox/dbox-save.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-save.c Sun May 13 20:10:48 2007 +0300 @@ -252,16 +252,14 @@ int dbox_save_continue(struct mail_save_context *_ctx) { struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx; + struct mail_storage *storage = &ctx->mbox->storage->storage; if (ctx->failed) return -1; if (o_stream_send_istream(ctx->file->output, ctx->input) < 0) { - if (ENOSPACE(ctx->file->output->stream_errno)) { - mail_storage_set_error(&ctx->mbox->storage->storage, - "Not enough disk space"); - } else { - mail_storage_set_critical(&ctx->mbox->storage->storage, + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, "o_stream_send_istream(%s) failed: %m", ctx->file->path); }
--- a/src/lib-storage/index/dbox/dbox-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-storage.c Sun May 13 20:10:48 2007 +0300 @@ -257,16 +257,11 @@ static int create_dbox(struct mail_storage *storage, const char *path) { - const char *error; - if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) { - if (mail_storage_errno2str(&error)) { - mail_storage_set_error(storage, "%s", error); - return -1; + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, + "mkdir(%s) failed: %m", path); } - - mail_storage_set_critical(storage, "mkdir(%s) failed: %m", - path); return -1; } return 0; @@ -391,8 +386,8 @@ if (stat(path, &st) == 0) { return dbox_open(storage, name, flags); } else if (errno == ENOENT) { - mail_storage_set_error(_storage, - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name); + mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return NULL; } else { mail_storage_set_critical(_storage, "stat(%s) failed: %m", @@ -411,7 +406,8 @@ path = mailbox_list_get_path(_storage->list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(path, &st) == 0) { - mail_storage_set_error(_storage, "Mailbox already exists"); + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, + "Mailbox already exists"); return -1; } @@ -423,7 +419,7 @@ { struct dbox_storage *storage = DBOX_LIST_CONTEXT(list); struct stat st; - const char *path, *mail_path, *error; + const char *path, *mail_path; /* make sure the indexes are closed before trying to delete the directory that contains them */ @@ -440,8 +436,8 @@ if (stat(mail_path, &st) < 0 && ENOTFOUND(errno)) { if (stat(path, &st) < 0) { /* doesn't exist at all */ - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; } @@ -450,9 +446,9 @@ return 0; if (errno == ENOTEMPTY) { - mailbox_list_set_error(list, t_strdup_printf( - "Directory %s isn't empty, can't delete it.", - name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + t_strdup_printf("Directory %s isn't empty, " + "can't delete it.", name)); } else { mailbox_list_set_critical(list, "rmdir() failed for %s: %m", path); @@ -463,9 +459,7 @@ if (unlink_directory(mail_path, TRUE) < 0) { - if (mail_storage_errno2str(&error)) - mailbox_list_set_error(list, error); - else { + if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "unlink_directory() failed for %s: %m", mail_path);
--- a/src/lib-storage/index/dbox/dbox-uidlist.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-uidlist.c Sun May 13 20:10:48 2007 +0300 @@ -439,8 +439,7 @@ if (uidlist->lock_fd == -1) { if (errno == EAGAIN) { mail_storage_set_error(&mbox->storage->storage, - "Timeout while waiting for lock"); - mbox->storage->storage.temporary_error = TRUE; + MAIL_ERROR_TEMP, MAIL_ERRSTR_LOCK_TIMEOUT); return 0; } mail_storage_set_critical(&mbox->storage->storage,
--- a/src/lib-storage/index/index-search.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/index-search.c Sun May 13 20:10:48 2007 +0300 @@ -907,7 +907,7 @@ if (ctx->error != NULL) { mail_storage_set_error(ctx->ibox->box.storage, - "%s", ctx->error); + MAIL_ERROR_PARAMS, ctx->error); } mail_search_args_reset(ctx->mail_ctx.args, FALSE);
--- a/src/lib-storage/index/maildir/maildir-copy.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-copy.c Sun May 13 20:10:48 2007 +0300 @@ -72,7 +72,7 @@ if (ENOSPACE(errno)) { mail_storage_set_error(&mbox->storage->storage, - "Not enough disk space"); + MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); return -1; }
--- a/src/lib-storage/index/maildir/maildir-save.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Sun May 13 20:10:48 2007 +0300 @@ -94,7 +94,7 @@ ret = -1; if (ENOSPACE(errno)) { mail_storage_set_error(storage, - "Not enough disk space"); + MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); } else { mail_storage_set_critical(storage, "rename(%s, %s) failed: %m", @@ -378,6 +378,7 @@ int maildir_save_continue(struct mail_save_context *_ctx) { struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx; + struct mail_storage *storage = &ctx->mbox->storage->storage; if (ctx->failed) return -1; @@ -386,11 +387,8 @@ index_mail_cache_parse_continue(ctx->cur_dest_mail); if (o_stream_send_istream(ctx->output, ctx->input) < 0) { - if (ENOSPACE(errno)) { - mail_storage_set_error(&ctx->mbox->storage->storage, - "Not enough disk space"); - } else { - mail_storage_set_critical(&ctx->mbox->storage->storage, + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, "o_stream_send_istream(%s/%s) failed: %m", ctx->tmpdir, ctx->file_last->basename); } @@ -466,7 +464,7 @@ errno = output_errno; if (ENOSPACE(errno)) { mail_storage_set_error(&ctx->mbox->storage->storage, - "Not enough disk space"); + MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); } else if (errno != 0) { mail_storage_set_critical(&ctx->mbox->storage->storage, "write(%s) failed: %m", ctx->mbox->path);
--- a/src/lib-storage/index/maildir/maildir-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun May 13 20:10:48 2007 +0300 @@ -568,8 +568,8 @@ return maildir_open(storage, name, flags); } else if (errno == ENOENT) { - mail_storage_set_error(_storage, - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name); + mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return NULL; } else { mail_storage_set_critical(_storage, "stat(%s) failed: %m", @@ -593,7 +593,7 @@ old_mask = umask(0777 ^ mode); if (create_maildir(storage, dir, FALSE) < 0) { if (errno == EEXIST) { - mail_storage_set_error(storage, + mail_storage_set_error(storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox already exists"); } umask(old_mask); @@ -643,7 +643,7 @@ if (create_maildir(_storage, path, FALSE) < 0) { if (errno == EEXIST) { - mail_storage_set_error(_storage, + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox already exists"); } return -1; @@ -694,8 +694,8 @@ dir = opendir(path); if (dir == NULL) { if (errno == ENOENT) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); } else { mailbox_list_set_critical(list, "opendir(%s) failed: %m", path); @@ -757,8 +757,9 @@ } if (!unlinked_something) { - mailbox_list_set_error(list, t_strdup_printf( - "Directory %s isn't empty, can't delete it.", name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + t_strdup_printf("Directory %s isn't empty, " + "can't delete it.", name)); return -1; } return 0; @@ -785,8 +786,8 @@ /* check if the mailbox actually exists */ src = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(src, &st) != 0 && errno == ENOENT) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; } @@ -805,8 +806,8 @@ if (errno == ENOENT) { /* it was just deleted under us by another process */ - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; } if (!EDESTDIREXISTS(errno)) { @@ -849,7 +850,7 @@ path2 = mailbox_list_get_path(list, NULL, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (strcmp(path1, path2) == 0) { - mailbox_list_set_error(list, + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Renaming INBOX isn't supported."); return -1; }
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sun May 13 20:10:48 2007 +0300 @@ -103,8 +103,7 @@ if (fd == -1) { if (errno == EAGAIN) { mail_storage_set_error(&mbox->storage->storage, - "Timeout while waiting for lock"); - mbox->storage->storage.temporary_error = TRUE; + MAIL_ERROR_TEMP, MAIL_ERRSTR_LOCK_TIMEOUT); return 0; } mail_storage_set_critical(&mbox->storage->storage,
--- a/src/lib-storage/index/maildir/maildir-util.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-util.c Sun May 13 20:10:48 2007 +0300 @@ -135,7 +135,7 @@ if (fd == -1) { if (ENOSPACE(errno)) { mail_storage_set_error(&mbox->storage->storage, - "Not enough disk space"); + MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); } else { mail_storage_set_critical(&mbox->storage->storage, "open(%s) failed: %m", str_c(path));
--- a/src/lib-storage/index/mbox/mbox-file.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-file.c Sun May 13 20:10:48 2007 +0300 @@ -171,6 +171,7 @@ if (istream_raw_mbox_seek(mbox->mbox_stream, offset) < 0) { if (offset == 0) { mail_storage_set_error(&mbox->storage->storage, + MAIL_ERROR_NOTPOSSIBLE, "Mailbox isn't a valid mbox file"); return -1; }
--- a/src/lib-storage/index/mbox/mbox-lock.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-lock.c Sun May 13 20:10:48 2007 +0300 @@ -263,8 +263,7 @@ } if (ret == 0) { mail_storage_set_error(&mbox->storage->storage, - "Timeout while waiting for lock"); - mbox->storage->storage.temporary_error = TRUE; + MAIL_ERROR_TEMP, MAIL_ERRSTR_LOCK_TIMEOUT); return 0; } mbox->mbox_dotlocked = TRUE; @@ -495,8 +494,7 @@ (void)mbox_unlock_files(&ctx); if (ret == 0) { mail_storage_set_error(&mbox->storage->storage, - "Timeout while waiting for lock"); - mbox->storage->storage.temporary_error = TRUE; + MAIL_ERROR_TEMP, MAIL_ERRSTR_LOCK_TIMEOUT); } return ret; }
--- a/src/lib-storage/index/mbox/mbox-save.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Sun May 13 20:10:48 2007 +0300 @@ -59,13 +59,7 @@ static int write_error(struct mbox_save_context *ctx) { - if (ENOSPACE(errno)) { - mail_storage_set_error(&ctx->mbox->storage->storage, - "Not enough disk space"); - } else { - mbox_set_syscall_error(ctx->mbox, "write()"); - } - + mbox_set_syscall_error(ctx->mbox, "write()"); ctx->failed = TRUE; return -1; } @@ -266,10 +260,11 @@ struct mbox_transaction_context *t, bool want_mail) { struct mbox_mailbox *mbox = ctx->mbox; + struct mail_storage *storage = &mbox->storage->storage; int ret; if (ctx->mbox->mbox_readonly) { - mail_storage_set_error(&ctx->mbox->storage->storage, + mail_storage_set_error(storage, MAIL_ERROR_PERM, "Read-only mbox"); return -1; } @@ -284,8 +279,8 @@ /* FIXME: we shouldn't fail here. it's just a locking issue that should be possible to fix.. */ - mail_storage_set_error( - &ctx->mbox->storage->storage, + mail_storage_set_error(storage, + MAIL_ERROR_NOTPOSSIBLE, "Can't copy mails inside same mailbox"); return -1; }
--- a/src/lib-storage/index/mbox/mbox-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Sun May 13 20:10:48 2007 +0300 @@ -84,7 +84,7 @@ if (ENOSPACE(errno)) { mail_storage_set_error(&mbox->storage->storage, - "Not enough disk space"); + MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); } else { mail_storage_set_critical(&mbox->storage->storage, "%s failed with mbox file %s: %m", @@ -648,7 +648,7 @@ struct istream *input, enum mailbox_open_flags flags) { struct mbox_storage *storage = (struct mbox_storage *)_storage; - const char *path, *error; + const char *path; struct stat st; if (input != NULL) @@ -665,8 +665,9 @@ MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(path, &st) == 0) { if (S_ISDIR(st.st_mode)) { - mail_storage_set_error(_storage, - "Mailbox isn't selectable: %s", name); + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, + t_strdup_printf("Mailbox isn't selectable: %s", + name)); return NULL; } @@ -674,11 +675,9 @@ } if (ENOTFOUND(errno)) { - mail_storage_set_error(_storage, - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name); - } else if (mail_storage_errno2str(&error)) - mail_storage_set_error(_storage, "%s", error); - else { + mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + } else if (!mail_storage_set_error_from_errno(_storage)) { mail_storage_set_critical(_storage, "stat(%s) failed: %m", path); } @@ -689,7 +688,7 @@ static int mbox_mailbox_create(struct mail_storage *_storage, const char *name, bool directory) { - const char *path, *p, *error; + const char *path, *p; struct stat st; int fd; @@ -698,17 +697,16 @@ path = mailbox_list_get_path(_storage->list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (stat(path, &st) == 0) { - mail_storage_set_error(_storage, "Mailbox already exists"); + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, + "Mailbox already exists"); return -1; } if (errno != ENOENT) { if (errno == ENOTDIR) { - mail_storage_set_error(_storage, + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox doesn't allow inferior mailboxes"); - } else if (mail_storage_errno2str(&error)) - mail_storage_set_error(_storage, "%s", error); - else { + } else if (!mail_storage_set_error_from_errno(_storage)) { mail_storage_set_critical(_storage, "stat() failed for mbox file %s: %m", path); } @@ -720,9 +718,7 @@ if (p != NULL) { p = t_strdup_until(path, p); if (mkdir_parents(p, CREATE_MODE) < 0) { - if (mail_storage_errno2str(&error)) - mail_storage_set_error(_storage, "%s", error); - else { + if (!mail_storage_set_error_from_errno(_storage)) { mail_storage_set_critical(_storage, "mkdir_parents(%s) failed: %m", p); } @@ -744,10 +740,9 @@ if (errno == EEXIST) { /* mailbox was just created between stat() and open() call.. */ - mail_storage_set_error(_storage, "Mailbox already exists"); - } else if (mail_storage_errno2str(&error)) - mail_storage_set_error(_storage, "%s", error); - else { + mail_storage_set_error(_storage, MAIL_ERROR_NOTPOSSIBLE, + "Mailbox already exists"); + } else if (!mail_storage_set_error_from_errno(_storage)) { mail_storage_set_critical(_storage, "Can't create mailbox %s: %m", name); } @@ -883,17 +878,15 @@ { struct mbox_storage *storage = MBOX_LIST_CONTEXT(list); struct stat st; - const char *path, *index_dir, *error; + const char *path, *index_dir; path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX); if (lstat(path, &st) < 0) { if (ENOTFOUND(errno)) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); - } else if (mail_storage_errno2str(&error)) - mailbox_list_set_error(list, error); - else { + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + } else if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "lstat() failed for %s: %m", path); } @@ -911,9 +904,7 @@ if (*index_dir != '\0' && rmdir(index_dir) < 0 && !ENOTFOUND(errno) && errno != ENOTEMPTY) { - if (mail_storage_errno2str(&error)) - mailbox_list_set_error(list, error); - else { + if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "rmdir() failed for %s: %m", index_dir); } @@ -924,15 +915,13 @@ return 0; if (ENOTFOUND(errno)) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); } else if (errno == ENOTEMPTY) { - mailbox_list_set_error(list, t_strdup_printf( - "Directory %s isn't empty, can't delete it.", - name)); - } else if (mail_storage_errno2str(&error)) - mailbox_list_set_error(list, error); - else { + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + t_strdup_printf("Directory %s isn't empty, " + "can't delete it.", name)); + } else if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "rmdir() failed for %s: %m", path); } @@ -946,11 +935,9 @@ if (unlink(path) < 0) { if (ENOTFOUND(errno)) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); - } else if (mail_storage_errno2str(&error)) - mailbox_list_set_error(list, error); - else { + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + } else if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "unlink() failed for %s: %m", path); }
--- a/src/lib-storage/index/mbox/mbox-sync.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Sun May 13 20:10:48 2007 +0300 @@ -946,6 +946,7 @@ if (seq == 0) { if (istream_raw_mbox_seek(mbox->mbox_stream, 0) < 0) { mail_storage_set_error(&mbox->storage->storage, + MAIL_ERROR_NOTPOSSIBLE, "Mailbox isn't a valid mbox file"); return -1; }
--- a/src/lib-storage/list/mailbox-list-fs-iter.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Sun May 13 20:10:48 2007 +0300 @@ -68,7 +68,8 @@ /* subfolder, ignore */ return 0; } - mailbox_list_set_error(list, "Access denied"); + mailbox_list_set_error(list, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); return -1; } @@ -92,7 +93,8 @@ /* check that we're not trying to do any "../../" lists */ if (!mailbox_list_is_valid_mask(_list, mask)) { - mailbox_list_set_error(_list, "Invalid mask"); + mailbox_list_set_error(_list, MAIL_ERROR_PARAMS, + "Invalid mask"); ctx->ctx.failed = TRUE; return &ctx->ctx; }
--- a/src/lib-storage/list/mailbox-list-fs.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/list/mailbox-list-fs.c Sun May 13 20:10:48 2007 +0300 @@ -272,19 +272,6 @@ return mailbox_list_delete_index_control(list, name); } -static bool fs_handle_errors(struct mailbox_list *list) -{ - if (ENOACCESS(errno)) - mailbox_list_set_error(list, MAILBOX_LIST_ERR_NO_PERMISSION); - else if (ENOSPACE(errno)) - mailbox_list_set_error(list, "Not enough disk space"); - else if (ENOTFOUND(errno)) - mailbox_list_set_error(list, "Directory structure is broken"); - else - return FALSE; - return TRUE; -} - static int fs_list_rename_mailbox(struct mailbox_list *list, const char *oldname, const char *newname) { @@ -301,7 +288,7 @@ if (p != NULL) { p = t_strdup_until(newpath, p); if (mkdir_parents(p, CREATE_MODE) < 0) { - if (fs_handle_errors(list)) + if (mailbox_list_set_error_from_errno(list)) return -1; mailbox_list_set_critical(list, @@ -315,10 +302,11 @@ possibility that someone actually tries to rename two mailboxes to same new one */ if (lstat(newpath, &st) == 0) { - mailbox_list_set_error(list, "Target mailbox already exists"); + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + "Target mailbox already exists"); return -1; } else if (errno == ENOTDIR) { - mailbox_list_set_error(list, + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Target mailbox doesn't allow inferior mailboxes"); return -1; } else if (errno != ENOENT && errno != EACCES) { @@ -331,9 +319,9 @@ the next time it's needed. */ if (rename(oldpath, newpath) < 0) { if (ENOTFOUND(errno)) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname)); - } else if (!fs_handle_errors(list)) { + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); + } else if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "rename(%s, %s) failed: %m", oldpath, newpath); }
--- a/src/lib-storage/list/mailbox-list-maildir.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/list/mailbox-list-maildir.c Sun May 13 20:10:48 2007 +0300 @@ -383,8 +383,8 @@ if (ret < 0) return -1; if (!found && ret == 0) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); return -1; } @@ -392,7 +392,8 @@ } if (EDESTDIREXISTS(errno)) { - mailbox_list_set_error(list, "Target mailbox already exists"); + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + "Target mailbox already exists"); } else { mailbox_list_set_critical(list, "rename(%s, %s) failed: %m", oldpath, newpath);
--- a/src/lib-storage/list/subscription-file.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/list/subscription-file.c Sun May 13 20:10:48 2007 +0300 @@ -30,9 +30,10 @@ { i_assert(function != NULL); - if (errno == EACCES) - mailbox_list_set_error(list, "Permission denied"); - else { + if (errno == EACCES) { + mailbox_list_set_error(list, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); + } else { mailbox_list_set_critical(list, "%s failed with subscription file %s: %m", function, path); @@ -97,7 +98,7 @@ fd_out = file_dotlock_open(&dotlock_set, path, 0, &dotlock); if (fd_out == -1) { if (errno == EAGAIN) { - mailbox_list_set_error(list, + mailbox_list_set_error(list, MAIL_ERROR_TEMP, "Timeout waiting for subscription file lock"); } else { subsfile_set_syscall_error(list,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mail-error.c Sun May 13 20:10:48 2007 +0300 @@ -0,0 +1,23 @@ +/* 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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mail-error.h Sun May 13 20:10:48 2007 +0300 @@ -0,0 +1,38 @@ +#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
--- a/src/lib-storage/mail-storage-private.h Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mail-storage-private.h Sun May 13 20:10:48 2007 +0300 @@ -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
--- a/src/lib-storage/mail-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mail-storage.c Sun May 13 20:10:48 2007 +0300 @@ -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; }
--- a/src/lib-storage/mail-storage.h Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mail-storage.h Sun May 13 20:10:48 2007 +0300 @@ -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,
--- a/src/lib-storage/mailbox-list-private.h Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mailbox-list-private.h Sun May 13 20:10:48 2007 +0300 @@ -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
--- a/src/lib-storage/mailbox-list.c Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mailbox-list.c Sun May 13 20:10:48 2007 +0300 @@ -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; +}
--- a/src/lib-storage/mailbox-list.h Sun May 13 19:53:41 2007 +0300 +++ b/src/lib-storage/mailbox-list.h Sun May 13 20:10:48 2007 +0300 @@ -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
--- a/src/plugins/acl/acl-mailbox-list.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/acl/acl-mailbox-list.c Sun May 13 20:10:48 2007 +0300 @@ -286,11 +286,11 @@ if (ret < 0) return -1; if (can_see) { - mailbox_list_set_error(list, - MAILBOX_LIST_ERR_NO_PERMISSION); + mailbox_list_set_error(list, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); } else { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); } return -1; } @@ -313,11 +313,11 @@ if (ret < 0) return -1; if (can_see) { - mailbox_list_set_error(list, - MAILBOX_LIST_ERR_NO_PERMISSION); + mailbox_list_set_error(list, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); } else { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); } return 0; } @@ -334,8 +334,8 @@ /* Note that if the mailbox didn't have LOOKUP permission, this not reveals to user the mailbox's existence. Can't help it. */ - mailbox_list_set_error(list, - MAILBOX_LIST_ERR_NO_PERMISSION); + mailbox_list_set_error(list, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); } return -1; }
--- a/src/plugins/acl/acl-mailbox.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/acl/acl-mailbox.c Sun May 13 20:10:48 2007 +0300 @@ -48,7 +48,8 @@ return -1; } - mail_storage_set_error(box->storage, MAILBOX_LIST_ERR_NO_PERMISSION); + mail_storage_set_error(box->storage, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); return 0; }
--- a/src/plugins/acl/acl-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/acl/acl-storage.c Sun May 13 20:10:48 2007 +0300 @@ -110,11 +110,11 @@ if (ret < 0) return NULL; if (can_see) { - mail_storage_set_error(storage, - MAILBOX_LIST_ERR_NO_PERMISSION); + mail_storage_set_error(storage, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); } else { - mail_storage_set_error(storage, - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name); + mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); } return NULL; } @@ -145,8 +145,8 @@ /* Note that if the mailbox didn't have LOOKUP permission, this not reveals to user the mailbox's existence. Can't help it. */ - mail_storage_set_error(storage, - MAILBOX_LIST_ERR_NO_PERMISSION); + mail_storage_set_error(storage, MAIL_ERROR_PERM, + MAIL_ERRSTR_NO_PERMISSION); } return -1; }
--- a/src/plugins/convert/convert-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/convert/convert-storage.c Sun May 13 20:10:48 2007 +0300 @@ -101,9 +101,9 @@ static const char *storage_error(struct mail_storage *storage) { - bool temp; + enum mail_error error; - return mail_storage_get_last_error(storage, &temp); + return mail_storage_get_last_error(storage, &error); } static const char *
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c Sun May 13 20:10:48 2007 +0300 @@ -69,7 +69,7 @@ mailbox_open_or_create(struct mail_storage *storage, const char *name) { struct mailbox *box; - bool temp; + enum mail_error error; box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | @@ -77,11 +77,11 @@ if (box != NULL) return box; - (void)mail_storage_get_last_error(storage, &temp); - if (temp) + (void)mail_storage_get_last_error(storage, &error); + if (error != MAIL_ERROR_NOTFOUND) return NULL; - /* probably the mailbox just doesn't exist. try creating it. */ + /* try creating it. */ if (mail_storage_mailbox_create(storage, name, FALSE) < 0) return NULL; @@ -428,14 +428,16 @@ /* first do the normal sanity checks */ 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; } if (mailbox_list_get_mailbox_name_status(list, name, &status) < 0) return -1; if (status == MAILBOX_NAME_INVALID) { - mailbox_list_set_error(list, "Invalid mailbox name"); + mailbox_list_set_error(list, MAIL_ERROR_PARAMS, + "Invalid mailbox name"); return -1; } @@ -450,8 +452,8 @@ if ((ret = mailbox_move(list, name, dest_list, &destname)) < 0) return -1; if (ret == 0) { - mailbox_list_set_error(list, t_strdup_printf( - MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name)); + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); return -1; }
--- a/src/plugins/quota/quota-storage.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/quota/quota-storage.c Sun May 13 20:10:48 2007 +0300 @@ -151,11 +151,12 @@ if (ret > 0) return 0; else if (ret == 0) { - mail_storage_set_error(t->box->storage, "Quota exceeded"); + mail_storage_set_error(t->box->storage, MAIL_ERROR_NOSPACE, + "Quota exceeded"); return -1; } else { - mail_storage_set_error(t->box->storage, - "Internal quota calculation error"); + mail_storage_set_critical(t->box->storage, + "Internal quota calculation error"); return -1; } } @@ -215,10 +216,10 @@ ret = quota_test_alloc(qt, st->st_size, &too_large); if (ret == 0) { mail_storage_set_error(t->box->storage, - "Quota exceeded"); + MAIL_ERROR_NOSPACE, "Quota exceeded"); return -1; } else if (ret < 0) { - mail_storage_set_error(t->box->storage, + mail_storage_set_critical(t->box->storage, "Internal quota calculation error"); return -1; }
--- a/src/plugins/quota/quota.c Sun May 13 19:53:41 2007 +0300 +++ b/src/plugins/quota/quota.c Sun May 13 20:10:48 2007 +0300 @@ -418,7 +418,7 @@ /* the quota information comes from userdb (or even config file), so there's really no way to support this until some major changes are done */ - *error_r = MAILBOX_LIST_ERR_NO_PERMISSION; + *error_r = MAIL_ERRSTR_NO_PERMISSION; return -1; }
--- a/src/pop3/client.c Sun May 13 19:53:41 2007 +0300 +++ b/src/pop3/client.c Sun May 13 20:10:48 2007 +0300 @@ -130,7 +130,7 @@ struct client *client; enum mailbox_open_flags flags; const char *errmsg; - bool temporary_error; + enum mail_error error; /* always use nonblocking I/O */ net_set_nonblock(fd_in, TRUE); @@ -169,7 +169,7 @@ if (client->mailbox == NULL) { errmsg = t_strdup_printf("Couldn't open INBOX: %s", mail_storage_get_last_error(storage, - &temporary_error)); + &error)); i_error("%s", errmsg); client_send_line(client, "-ERR [IN-USE] %s", errmsg); client_destroy(client, "Couldn't open INBOX"); @@ -178,7 +178,7 @@ if (!init_mailbox(client)) { i_error("Couldn't init INBOX: %s", - mail_storage_get_last_error(storage, &temporary_error)); + mail_storage_get_last_error(storage, &error)); client_destroy(client, "Mailbox init failed"); return NULL; } @@ -331,8 +331,7 @@ void client_send_storage_error(struct client *client) { - const char *error; - bool temporary_error; + enum mail_error error; if (mailbox_is_inconsistent(client->mailbox)) { client_send_line(client, "-ERR Mailbox is in inconsistent " @@ -341,10 +340,9 @@ return; } - error = mail_storage_get_last_error(client->inbox_ns->storage, - &temporary_error); - client_send_line(client, "-ERR %s", error != NULL ? error : - "BUG: Unknown error"); + client_send_line(client, "-ERR %s", + mail_storage_get_last_error(client->inbox_ns->storage, + &error)); } static void client_input(struct client *client)