]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dbox: Don't crash if index files can't be opened.
authorTimo Sirainen <tss@iki.fi>
Tue, 14 Apr 2009 00:07:59 +0000 (20:07 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 14 Apr 2009 00:07:59 +0000 (20:07 -0400)
--HG--
branch : HEAD

src/lib-storage/index/dbox/dbox-storage.c
src/lib-storage/index/dbox/dbox-sync.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/index-sync.c

index fae404864118d2b5c0f6409d38b7ab5c94511196..adcd9973225f116a6ea352c55e3cb2923e70a378 100644 (file)
@@ -223,9 +223,11 @@ dbox_open(struct dbox_storage *storage, const char *name,
 {
        struct mail_storage *_storage = &storage->storage;
        struct dbox_mailbox *mbox;
+       struct mailbox *box;
        struct mail_index *index;
        const char *path;
        pool_t pool;
+       int ret;
 
        path = mailbox_list_get_path(_storage->list, name,
                                     MAILBOX_LIST_PATH_TYPE_MAILBOX);
@@ -257,9 +259,13 @@ dbox_open(struct dbox_storage *storage, const char *name,
        mbox->guid_ext_id =
                mail_index_ext_register(index, "guid", 0, DBOX_GUID_BIN_LEN, 1);
 
-       index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
+       ret = index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
        mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox);
-       return &mbox->ibox.box;
+
+       box = &mbox->ibox.box;
+       if (ret < 0)
+               mailbox_close(&box);
+       return box;
 }
 
 uint32_t dbox_get_uidvalidity_next(struct mail_storage *storage)
@@ -309,8 +315,11 @@ static int create_dbox(struct mail_storage *_storage, const char *path,
                        /* create indexes immediately with the dbox header */
                        box = dbox_open(storage, name,
                                        MAILBOX_OPEN_KEEP_RECENT);
+                       if (box == NULL)
+                               return -1;
                        dbox_write_index_header(box);
                        mailbox_close(&box);
+                       return 0;
                }
        } else if (errno != EEXIST) {
                if (!mail_storage_set_error_from_errno(_storage)) {
@@ -360,9 +369,9 @@ dbox_mailbox_open(struct mail_storage *_storage, const char *name,
 
        path = mailbox_list_get_path(_storage->list, name,
                                     MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (dbox_cleanup_if_exists(_storage, path))
+       if (dbox_cleanup_if_exists(_storage, path)) {
                return dbox_open(storage, name, flags);
-       else if (errno == ENOENT) {
+       else if (errno == ENOENT) {
                if (strcmp(name, "INBOX") == 0 &&
                    (_storage->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
                        /* INBOX always exists, create it */
index 3b09f6bbe3b2af636098f85b19eb9181bb7bc414..5b59e0501370bb67ebaaa94f579202973cb2e078 100644 (file)
@@ -49,7 +49,7 @@ static int dbox_sync_add_seq(struct dbox_sync_context *ctx,
 
        memset(&lookup_entry, 0, sizeof(lookup_entry));
        if (dbox_mail_lookup(ctx->mbox, ctx->sync_view, seq, &map_uid) < 0)
-               return 0;
+               return ctx->mbox->storage->sync_rebuild ? 0 : -1;
        if (map_uid == 0)
                mail_index_lookup_uid(ctx->sync_view, seq, &lookup_entry.uid);
        else {
@@ -361,11 +361,13 @@ dbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        enum dbox_sync_flags dbox_sync_flags = 0;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (index_storage_mailbox_open(&mbox->ibox) < 0)
+                       ret = -1;
+       }
 
-       if (index_mailbox_want_full_sync(&mbox->ibox, flags) ||
-           mbox->storage->sync_rebuild) {
+       if (ret == 0 && (index_mailbox_want_full_sync(&mbox->ibox, flags) ||
+                        mbox->storage->sync_rebuild)) {
                if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0)
                        dbox_sync_flags |= DBOX_SYNC_FLAG_FORCE_REBUILD;
                ret = dbox_sync(mbox, dbox_sync_flags);
index 1b62cada54c0ce1be711847eeeb832e868061816..9eaa887b75ce32328ba8638b75f26dba35c8d6ca 100644 (file)
@@ -349,7 +349,7 @@ void index_storage_lock_notify_reset(struct index_mailbox *ibox)
        ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE;
 }
 
-void index_storage_mailbox_open(struct index_mailbox *ibox)
+int index_storage_mailbox_open(struct index_mailbox *ibox)
 {
        struct mail_storage *storage = ibox->storage;
        enum mail_index_open_flags index_flags;
@@ -367,6 +367,11 @@ void index_storage_mailbox_open(struct index_mailbox *ibox)
 
        ret = mail_index_open(ibox->index, index_flags, storage->lock_method);
        if (ret <= 0 || ibox->move_to_memory) {
+               if (ibox->index_never_in_memory) {
+                       mail_storage_set_index_error(ibox);
+                       return -1;
+               }
+
                if (mail_index_move_to_memory(ibox->index) < 0) {
                        /* try opening once more. it should be created
                           directly into memory now. */
@@ -390,11 +395,12 @@ void index_storage_mailbox_open(struct index_mailbox *ibox)
        index_thread_mailbox_index_opened(ibox);
        if (hook_mailbox_index_opened != NULL)
                hook_mailbox_index_opened(&ibox->box);
+       return 0;
 }
 
-void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
-                               enum mailbox_open_flags flags,
-                               bool move_to_memory)
+int index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
+                              enum mailbox_open_flags flags,
+                              bool move_to_memory)
 {
        struct mail_storage *storage = ibox->storage;
        struct mailbox *box = &ibox->box;
@@ -431,7 +437,8 @@ void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
                mail_index_ext_register(ibox->index, "header-md5", 0, 16, 1);
 
        if ((flags & MAILBOX_OPEN_FAST) == 0)
-               index_storage_mailbox_open(ibox);
+               return index_storage_mailbox_open(ibox);
+       return 0;
 }
 
 int index_storage_mailbox_enable(struct mailbox *box,
@@ -441,11 +448,13 @@ int index_storage_mailbox_enable(struct mailbox *box,
 
        if ((feature & MAILBOX_FEATURE_CONDSTORE) != 0) {
                box->enabled_features |= MAILBOX_FEATURE_CONDSTORE;
-               if (!box->opened)
-                       index_storage_mailbox_open(ibox);
+               if (!box->opened) {
+                       if (index_storage_mailbox_open(ibox) < 0)
+                               return -1;
+               }
                mail_index_modseq_enable(ibox->index);
        }
-       return TRUE;
+       return 0;
 }
 
 int index_storage_mailbox_close(struct mailbox *box)
index 1b13583b5e6e7caa21cb8740b04e529ea2d6c666..362f7a29d6a3a78899b9529c6dceeab322a416e8 100644 (file)
@@ -99,10 +99,10 @@ void index_storage_unref(struct mail_index *index);
 void index_storage_destroy_unrefed(void);
 void index_storage_destroy(struct mail_storage *storage ATTR_UNUSED);
 
-void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
-                               enum mailbox_open_flags flags,
-                               bool move_to_memory);
-void index_storage_mailbox_open(struct index_mailbox *ibox);
+int index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
+                              enum mailbox_open_flags flags,
+                              bool move_to_memory);
+int index_storage_mailbox_open(struct index_mailbox *ibox);
 int index_storage_mailbox_enable(struct mailbox *box,
                                 enum mailbox_feature feature);
 int index_storage_mailbox_close(struct mailbox *box);
index 1555afd5ead571a9d34bf3ee3e78935ea66698be..8d965db694456aa05518d1f77a40167024052af2 100644 (file)
@@ -323,7 +323,7 @@ int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
        }
        index_mailbox_expunge_unseen_recent(ctx);
 
-       if (ibox->keep_recent) {
+       if (ibox->keep_recent && ibox->box.opened) {
                /* mailbox syncing didn't necessarily update our recent state */
                hdr = mail_index_get_header(ibox->view);
                if (hdr->first_recent_uid > ibox->recent_flags_prev_uid) {