]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Mailbox opening and closing APIs changed.
authorTimo Sirainen <tss@iki.fi>
Mon, 15 Jun 2009 18:28:55 +0000 (14:28 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 15 Jun 2009 18:28:55 +0000 (14:28 -0400)
--HG--
branch : HEAD

80 files changed:
src/imap/cmd-append.c
src/imap/cmd-close.c
src/imap/cmd-copy.c
src/imap/cmd-delete.c
src/imap/cmd-select.c
src/imap/cmd-unselect.c
src/imap/imap-status.c
src/lda/main.c
src/lib-lda/mail-deliver.c
src/lib-storage/index/cydir/cydir-storage.c
src/lib-storage/index/cydir/cydir-storage.h
src/lib-storage/index/cydir/cydir-sync.c
src/lib-storage/index/dbox/dbox-file.c
src/lib-storage/index/dbox/dbox-mail.c
src/lib-storage/index/dbox/dbox-save.c
src/lib-storage/index/dbox/dbox-storage-rebuild.c
src/lib-storage/index/dbox/dbox-storage.c
src/lib-storage/index/dbox/dbox-storage.h
src/lib-storage/index/dbox/dbox-sync-rebuild.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-thread.c
src/lib-storage/index/maildir/maildir-copy.c
src/lib-storage/index/maildir/maildir-keywords.c
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/index/maildir/maildir-save.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/maildir/maildir-storage.h
src/lib-storage/index/maildir/maildir-sync-index.c
src/lib-storage/index/maildir/maildir-sync.c
src/lib-storage/index/maildir/maildir-uidlist.c
src/lib-storage/index/maildir/maildir-util.c
src/lib-storage/index/mbox/mbox-file.c
src/lib-storage/index/mbox/mbox-lock.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/mbox/mbox-storage.h
src/lib-storage/index/mbox/mbox-sync-rewrite.c
src/lib-storage/index/mbox/mbox-sync.c
src/lib-storage/index/raw/raw-mail.c
src/lib-storage/index/raw/raw-storage.c
src/lib-storage/index/raw/raw-storage.h
src/lib-storage/index/raw/raw-sync.c
src/lib-storage/list/index-mailbox-list-sync.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h
src/lib-storage/mailbox-list-private.h
src/lib-storage/mailbox-list.c
src/lib-storage/test-mail-storage.c
src/lib-storage/test-mail-storage.h
src/lib-storage/test-mailbox.c
src/lmtp/commands.c
src/plugins/acl/acl-mailbox.c
src/plugins/acl/acl-plugin.h
src/plugins/acl/acl-storage.c
src/plugins/convert/convert-storage.c
src/plugins/expire/expire-plugin.c
src/plugins/expire/expire-tool.c
src/plugins/fts/fts-plugin.c
src/plugins/fts/fts-plugin.h
src/plugins/fts/fts-storage.c
src/plugins/imap-acl/imap-acl-plugin.c
src/plugins/imap-quota/imap-quota-plugin.c
src/plugins/lazy-expunge/lazy-expunge-plugin.c
src/plugins/listescape/listescape-plugin.c
src/plugins/mail-log/mail-log-plugin.c
src/plugins/mbox-snarf/mbox-snarf-plugin.c
src/plugins/quota/quota-count.c
src/plugins/quota/quota-storage.c
src/plugins/trash/trash-plugin.c
src/plugins/virtual/virtual-config.c
src/plugins/virtual/virtual-storage.c
src/plugins/virtual/virtual-storage.h
src/plugins/virtual/virtual-sync.c
src/plugins/zlib/zlib-plugin.c
src/pop3/pop3-client.c
src/util/doveadm.c

index 5a28795b46195bab486faac42a16f711ee1608f6..a1e9bf2376df6f2038a8fc3dcd2204310b165d73 100644 (file)
@@ -465,10 +465,11 @@ get_mailbox(struct client_command_context *cmd, const char *name)
            mailbox_equals(cmd->client->mailbox, ns, name))
                return cmd->client->mailbox;
 
-       box = mailbox_open(ns->list, name, NULL, MAILBOX_OPEN_SAVEONLY |
-                          MAILBOX_OPEN_KEEP_RECENT);
-       if (box == NULL) {
-               client_send_list_error(cmd, ns->list);
+       box = mailbox_alloc(ns->list, name, NULL, MAILBOX_FLAG_SAVEONLY |
+                           MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(box) < 0) {
+               client_send_storage_error(cmd, mailbox_get_storage(box));
+               mailbox_close(&box);
                return NULL;
        }
        if (cmd->client->enabled_features != 0)
index 4e5dc31067efb387eb8c1045326ba04fc5c48f0a..ab61079f6310de069eedc0626f6eff121663ea4d 100644 (file)
@@ -23,8 +23,7 @@ bool cmd_close(struct client_command_context *cmd)
        if (mailbox_sync(mailbox, 0, 0, NULL) < 0)
                client_send_untagged_storage_error(client, storage);
 
-       if (mailbox_close(&mailbox) < 0)
-               client_send_untagged_storage_error(client, storage);
+       mailbox_close(&mailbox);
        client_update_mailbox_flags(client, NULL);
 
        client_send_tagline(cmd, "OK Close completed.");
index 47e0b571eb21789be6b68a7ab6b82e075f583258..9e6e91ee5c9ffe3801bfa5df62b95eeaa62c560b 100644 (file)
@@ -127,11 +127,13 @@ bool cmd_copy(struct client_command_context *cmd)
        if (mailbox_equals(client->mailbox, dest_ns, mailbox))
                destbox = client->mailbox;
        else {
-               destbox = mailbox_open(dest_ns->list, mailbox, NULL,
-                                      MAILBOX_OPEN_SAVEONLY |
-                                      MAILBOX_OPEN_KEEP_RECENT);
-               if (destbox == NULL) {
-                       client_send_list_error(cmd, dest_ns->list);
+               destbox = mailbox_alloc(dest_ns->list, mailbox, NULL,
+                                       MAILBOX_FLAG_SAVEONLY |
+                                       MAILBOX_FLAG_KEEP_RECENT);
+               if (mailbox_open(destbox) < 0) {
+                       client_send_storage_error(cmd,
+                               mailbox_get_storage(destbox));
+                       mailbox_close(&destbox);
                        return TRUE;
                }
                if (client->enabled_features != 0)
index 872ab608eff8cc86f8d886e1545efa4ae9d6e0b6..e78a98e980f87ab436b41bdcad371a67c18ba1a8 100644 (file)
@@ -33,8 +33,7 @@ bool cmd_delete(struct client_command_context *cmd)
                storage = mailbox_get_storage(mailbox);
                client->mailbox = NULL;
 
-               if (mailbox_close(&mailbox) < 0)
-                       client_send_untagged_storage_error(client, storage);
+               mailbox_close(&mailbox);
        }
 
        if ((client->workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 &&
index 15c07833760059a805a3193ba69acc6f710c21fc..4860e77b4164fbc10a424dea68e8e8f2fb9d472c 100644 (file)
@@ -263,13 +263,15 @@ select_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
 {
        struct client *client = ctx->cmd->client;
        struct mailbox_status status;
-       enum mailbox_open_flags open_flags = 0;
+       enum mailbox_flags flags = 0;
 
        if (readonly)
-               open_flags |= MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT;
-       ctx->box = mailbox_open(ctx->ns->list, mailbox, NULL, open_flags);
-       if (ctx->box == NULL) {
-               client_send_list_error(ctx->cmd, ctx->ns->list);
+               flags |= MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT;
+       ctx->box = mailbox_alloc(ctx->ns->list, mailbox, NULL, flags);
+       if (mailbox_open(ctx->box) < 0) {
+               client_send_storage_error(ctx->cmd,
+                                         mailbox_get_storage(ctx->box));
+               mailbox_close(&ctx->box);
                return -1;
        }
 
@@ -370,15 +372,11 @@ bool cmd_select_full(struct client_command_context *cmd, bool readonly)
        client->mailbox_change_lock = cmd;
 
        if (client->mailbox != NULL) {
-               struct mail_storage *old_storage =
-                       mailbox_get_storage(client->mailbox);
-
                client_search_updates_free(client);
                box = client->mailbox;
                client->mailbox = NULL;
 
-               if (mailbox_close(&box) < 0)
-                       client_send_untagged_storage_error(client, old_storage);
+               mailbox_close(&box);
                /* CLOSED response is required by QRESYNC */
                client_send_line(client, "* OK [CLOSED]");
        }
index fb320494fee2896f6701dc6468951e4cfb5ea218..951e291c8ac6d90d5c49b614f42fdb30466d338b 100644 (file)
@@ -18,8 +18,7 @@ bool cmd_unselect(struct client_command_context *cmd)
        client->mailbox = NULL;
 
        storage = mailbox_get_storage(mailbox);
-       if (mailbox_close(&mailbox) < 0)
-               client_send_untagged_storage_error(client, storage);
+       mailbox_close(&mailbox);
        client_update_mailbox_flags(client, NULL);
 
        client_send_tagline(cmd, "OK Unselect completed.");
index 76c6d9f03e0129fe1d07fe0350453b74e967640d..cdd7e65dbe6e71e0cb09e247b457730d8c3212e6 100644 (file)
@@ -62,13 +62,8 @@ int imap_status_get(struct client *client, struct mail_namespace *ns,
        }
 
        /* open the mailbox */
-       box = mailbox_open(ns->list, mailbox, NULL, MAILBOX_OPEN_FAST |
-                          MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
-       if (box == NULL) {
-               *error_r = mailbox_list_get_last_error(ns->list, &error);
-               *error_r = imap_get_error_string(*error_r, error);
-               return -1;
-       }
+       box = mailbox_alloc(ns->list, mailbox, NULL, MAILBOX_FLAG_READONLY |
+                           MAILBOX_FLAG_KEEP_RECENT);
 
        if ((items & STATUS_HIGHESTMODSEQ) != 0)
                client_enable(client, MAILBOX_FEATURE_CONDSTORE);
index 43c076d1d3b59664bdfe680eecd836b174650d45..ad2fae130aedd69e21fa86f32862c79a747de344 100644 (file)
@@ -416,17 +416,17 @@ int main(int argc, char *argv[])
                i_fatal("Couldn't create internal raw storage: %s", errstr);
        if (path == NULL) {
                input = create_raw_stream(&ctx, 0, &mtime);
-               box = mailbox_open(raw_ns->list, "Dovecot Delivery Mail",
-                                  input, MAILBOX_OPEN_NO_INDEX_FILES);
+               box = mailbox_alloc(raw_ns->list, "Dovecot Delivery Mail",
+                                   input, MAILBOX_FLAG_NO_INDEX_FILES);
                i_stream_unref(&input);
        } else {
                mtime = (time_t)-1;
-               box = mailbox_open(raw_ns->list, path, NULL,
-                                  MAILBOX_OPEN_NO_INDEX_FILES);
+               box = mailbox_alloc(raw_ns->list, path, NULL,
+                                   MAILBOX_FLAG_NO_INDEX_FILES);
        }
-       if (box == NULL) {
+       if (mailbox_open(box) < 0) {
                i_fatal("Can't open delivery mail as raw: %s",
-                       mailbox_list_get_last_error(raw_ns->list, &error));
+                       mail_storage_get_last_error(box->storage, &error));
        }
        if (mailbox_sync(box, 0, 0, NULL) < 0) {
                i_fatal("Can't sync delivery mail: %s",
index 66c6d26228a7fae3f012d4c6ba7b17d3c72bc195..d5233aef292416c9ed56889894c8becd3efde5ad 100644 (file)
@@ -79,16 +79,16 @@ mailbox_open_or_create_synced(struct mail_deliver_context *ctx,
        struct mail_storage *storage;
        struct mailbox *box;
        enum mail_error error;
-       enum mailbox_open_flags open_flags =
-               MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_SAVEONLY |
-               MAILBOX_OPEN_POST_SESSION;
+       enum mailbox_flags flags =
+               MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY |
+               MAILBOX_FLAG_POST_SESSION;
 
        *error_r = NULL;
 
        if (strcasecmp(name, "INBOX") == 0) {
                /* deliveries to INBOX must always succeed,
                   regardless of ACLs */
-               open_flags |= MAILBOX_OPEN_IGNORE_ACLS;
+               flags |= MAILBOX_FLAG_IGNORE_ACLS;
        }
 
        *ns_r = ns = mail_namespace_find(ctx->dest_user->namespaces, &name);
@@ -101,16 +101,17 @@ mailbox_open_or_create_synced(struct mail_deliver_context *ctx,
                return NULL;
        }
 
-       box = mailbox_open(ns->list, name, NULL, open_flags);
-       if (box != NULL)
+       box = mailbox_alloc(ns->list, name, NULL, flags);
+       if (mailbox_open(box) == 0)
                return box;
 
-       *error_r = mailbox_list_get_last_error(ns->list, &error);
+       storage = mailbox_get_storage(box);
+       *error_r = mail_storage_get_last_error(storage, &error);
+       mailbox_close(&box);
        if (!ctx->set->lda_mailbox_autocreate || error != MAIL_ERROR_NOTFOUND)
                return NULL;
 
        /* try creating it. */
-       storage = mail_namespace_get_default_storage(ns);
        if (mail_storage_mailbox_create(storage, ns, name, FALSE) < 0) {
                *error_r = mail_storage_get_last_error(storage, &error);
                return NULL;
@@ -121,16 +122,12 @@ mailbox_open_or_create_synced(struct mail_deliver_context *ctx,
        }
 
        /* and try opening again */
-       box = mailbox_open(ns->list, name, NULL, open_flags);
-       if (box == NULL) {
-               *error_r = mailbox_list_get_last_error(ns->list, &error);
-               return NULL;
-       }
-
-       if (mailbox_sync(box, 0, 0, NULL) < 0) {
+       box = mailbox_alloc(ns->list, name, NULL, flags);
+       storage = mailbox_get_storage(box);
+       if (mailbox_open(box) < 0 ||
+           mailbox_sync(box, 0, 0, NULL) < 0) {
+               *error_r = mail_storage_get_last_error(storage, &error);
                mailbox_close(&box);
-               *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
-                                                      &error);
                return NULL;
        }
        return box;
index a5e0266add6abf4f3597a9c59dbec272009ed04b..02b22cf0cc8a86569fe0c0e70e0782ce7d97dbd3 100644 (file)
@@ -48,13 +48,13 @@ cydir_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
                set->subscription_fname = CYDIR_SUBSCRIPTION_FILE_NAME;
 }
 
-static int create_cydir(struct mail_storage *storage, struct mail_namespace *ns,
+static int create_cydir(struct mail_storage *storage, struct mailbox_list *list,
                        const char *path)
 {
        mode_t mode;
        gid_t gid;
 
-       mailbox_list_get_dir_permissions(ns->list, NULL, &mode, &gid);
+       mailbox_list_get_dir_permissions(list, NULL, &mode, &gid);
        if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 &&
            errno != EEXIST) {
                if (!mail_storage_set_error_from_errno(storage)) {
@@ -67,76 +67,64 @@ static int create_cydir(struct mail_storage *storage, struct mail_namespace *ns,
 }
 
 static struct mailbox *
-cydir_open(struct mail_storage *storage, struct mailbox_list *list,
-          const char *name, enum mailbox_open_flags flags)
+cydir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                   const char *name, struct istream *input,
+                   enum mailbox_flags flags)
 {
        struct cydir_mailbox *mbox;
-       struct mail_index *index;
-       const char *path;
        pool_t pool;
 
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       index = index_storage_alloc(list, name, flags, CYDIR_INDEX_PREFIX);
-       mail_index_set_fsync_types(index, MAIL_INDEX_SYNC_TYPE_APPEND |
-                                  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+       /* cydir can't work without index files */
+       flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
 
        pool = pool_alloconly_create("cydir mailbox", 1024+512);
        mbox = p_new(pool, struct cydir_mailbox, 1);
        mbox->ibox.box = cydir_mailbox;
        mbox->ibox.box.pool = pool;
        mbox->ibox.box.storage = storage;
+       mbox->ibox.box.list = list;
        mbox->ibox.mail_vfuncs = &cydir_mail_vfuncs;
-       mbox->ibox.index = index;
 
-       mbox->storage = (struct cydir_storage *)storage;
-       mbox->path = p_strdup(pool, path);
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
+                                   CYDIR_INDEX_PREFIX);
+       mail_index_set_fsync_types(mbox->ibox.index,
+                                  MAIL_INDEX_SYNC_TYPE_APPEND |
+                                  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
-       index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
+       mbox->storage = (struct cydir_storage *)storage;
        return &mbox->ibox.box;
 }
 
-static struct mailbox *
-cydir_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                  const char *name, struct istream *input,
-                  enum mailbox_open_flags flags)
+static int cydir_mailbox_open(struct mailbox *box)
 {
-       const char *path;
        struct stat st;
 
-       if (input != NULL) {
-               mailbox_list_set_critical(list,
+       if (box->input != NULL) {
+               mail_storage_set_critical(box->storage,
                        "cydir doesn't support streamed mailboxes");
-               return NULL;
+               return -1;
        }
 
-       /* cydir can't work without index files */
-       flags &= ~MAILBOX_OPEN_NO_INDEX_FILES;
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (stat(path, &st) == 0)
-               return cydir_open(storage, list, name, flags);
-       else if (errno == ENOENT) {
-               if (strcmp(name, "INBOX") == 0) {
-                       /* INBOX always exists, create it */
-                       if (create_cydir(storage, list->ns, path) < 0) {
-                               mailbox_list_set_error_from_storage(list,
-                                                                   storage);
-                               return NULL;
-                       }
-                       return cydir_open(storage, list, "INBOX", flags);
-               }
-               mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
-                       T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
+       if (stat(box->path, &st) == 0) {
+               /* exists, open it */
+       } else if (errno == ENOENT && strcmp(box->name, "INBOX") == 0) {
+               /* INBOX always exists, create it */
+               if (create_cydir(box->storage, box->list, box->path) < 0)
+                       return -1;
+       } else if (errno == ENOENT) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                       T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               return -1;
        } else if (errno == EACCES) {
-               mail_storage_set_critical(storage, "%s",
-                       mail_error_eacces_msg("stat", path));
+               mail_storage_set_critical(box->storage, "%s",
+                       mail_error_eacces_msg("stat", box->path));
+               return -1;
        } else {
-               mail_storage_set_critical(storage, "stat(%s) failed: %m",
-                                         path);
+               mail_storage_set_critical(box->storage, "stat(%s) failed: %m",
+                                         box->path);
+               return -1;
        }
-       return NULL;
+       return index_storage_mailbox_open(box);
 }
 
 static int
@@ -154,7 +142,7 @@ cydir_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
                return -1;
        }
 
-       return create_cydir(storage, list->ns, path);
+       return create_cydir(storage, list, path);
 }
 
 static int
@@ -261,7 +249,7 @@ static void cydir_notify_changes(struct mailbox *box)
        if (box->notify_callback == NULL)
                index_mailbox_check_remove_all(&mbox->ibox);
        else
-               index_mailbox_check_add(&mbox->ibox, mbox->path);
+               index_mailbox_check_add(&mbox->ibox, mbox->ibox.box.path);
 }
 
 static int cydir_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx
@@ -356,7 +344,7 @@ struct mail_storage cydir_storage = {
                cydir_storage_add_list,
                cydir_storage_get_list_settings,
                NULL,
-               cydir_mailbox_open,
+               cydir_mailbox_alloc,
                cydir_mailbox_create,
                NULL
        }
@@ -371,6 +359,7 @@ struct mailbox cydir_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
+               cydir_mailbox_open,
                index_storage_mailbox_close,
                index_storage_get_status,
                NULL,
index 296f5cca0da439fafbb2568d7f6e084afbc1e182..c601892fd1050435f3d9e5c3686f76c5fb8e300d 100644 (file)
@@ -16,8 +16,6 @@ struct cydir_storage {
 struct cydir_mailbox {
        struct index_mailbox ibox;
        struct cydir_storage *storage;
-
-       const char *path;
 };
 
 struct cydir_transaction_context {
index c2d00c2a1c16897179fe19815ffabbd1ac6cddca..b0a1a31f286cdeca839b4c154b6c9fc987c9b766 100644 (file)
@@ -175,10 +175,12 @@ cydir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        struct cydir_mailbox *mbox = (struct cydir_mailbox *)box;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       ret = -1;
+       }
 
-       if (index_mailbox_want_full_sync(&mbox->ibox, flags))
+       if (index_mailbox_want_full_sync(&mbox->ibox, flags) && ret == 0)
                ret = cydir_sync(mbox);
 
        return index_mailbox_sync_init(box, flags, ret < 0);
index b394466073d597780789a51be89fe1bc943731ed..6913a261683767c6436e2a37ed6e109b668a9e2d 100644 (file)
@@ -151,7 +151,7 @@ const char *dbox_file_get_primary_path(struct dbox_file *file)
 {
        const char *dir;
 
-       dir = file->single_mbox != NULL ? file->single_mbox->path :
+       dir = file->single_mbox != NULL ? file->single_mbox->ibox.box.path :
                file->storage->storage_dir;
        return t_strdup_printf("%s/%s", dir, file->fname);
 }
@@ -184,7 +184,8 @@ dbox_file_init_single(struct dbox_mailbox *mbox, uint32_t uid)
        } else {
                file->fname = dbox_generate_tmp_filename();
        }
-       file->current_path = i_strdup_printf("%s/%s", mbox->path, file->fname);
+       file->current_path = i_strdup_printf("%s/%s", mbox->ibox.box.path,
+                                            file->fname);
        return file;
 }
 
@@ -237,7 +238,8 @@ int dbox_file_assign_id(struct dbox_file *file, uint32_t id)
        if (file->single_mbox != NULL) {
                new_fname = dbox_file_uid_get_fname(file->single_mbox,
                                                    id, &maildir);
-               new_path = i_strdup_printf("%s/%s", file->single_mbox->path,
+               new_path = i_strdup_printf("%s/%s",
+                                          file->single_mbox->ibox.box.path,
                                           new_fname);
        } else {
                new_fname = i_strdup_printf(DBOX_MAIL_FILE_MULTI_FORMAT, id);
index ead161277a703fb9592f711f81e82fc05255e46e..6eff26e9b7aad5d133ead73699e854bb7de6458b 100644 (file)
@@ -68,7 +68,8 @@ int dbox_mail_lookup(struct dbox_mailbox *mbox, struct mail_index_view *view,
                                          &data, &data_size);
                if (data_size != sizeof(*hdr)) {
                        mail_storage_set_critical(&mbox->storage->storage,
-                               "dbox %s: Invalid dbox header size", mbox->path);
+                               "dbox %s: Invalid dbox header size",
+                               mbox->ibox.box.path);
                        mbox->storage->sync_rebuild = TRUE;
                        return -1;
                }
@@ -82,7 +83,7 @@ int dbox_mail_lookup(struct dbox_mailbox *mbox, struct mail_index_view *view,
        if (cur_map_uid_validity != mbox->map_uid_validity) {
                mail_storage_set_critical(&mbox->storage->storage,
                        "dbox %s: map uidvalidity mismatch (%u vs %u)",
-                       mbox->path, mbox->map_uid_validity,
+                       mbox->ibox.box.path, mbox->map_uid_validity,
                        cur_map_uid_validity);
                mbox->storage->sync_rebuild = TRUE;
                return -1;
index f780377190879e88ef050d939dadcb1139c20bdc..06d50522925237481288a49bd3c62e9df46ebfeb 100644 (file)
@@ -445,9 +445,9 @@ void dbox_transaction_save_commit_post(struct dbox_save_context *ctx)
        dbox_map_append_free(&ctx->append_ctx);
 
        if (!ctx->mbox->storage->storage.set->fsync_disable) {
-               if (fdatasync_path(ctx->mbox->path) < 0) {
+               if (fdatasync_path(ctx->mbox->ibox.box.path) < 0) {
                        i_error("fdatasync_path(%s) failed: %m",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                }
        }
        dbox_transaction_save_rollback(ctx);
index a63dcd8fb449aaaf2bb4bc965fc050c5043c5a01..3da61c6842e53dc33c490d568307b51a0b65d352 100644 (file)
@@ -398,12 +398,13 @@ rebuild_mailbox(struct dbox_storage_rebuild_context *ctx,
        enum mail_error error;
        int ret;
 
-       box = dbox_mailbox_open(&ctx->storage->storage, ns->list, name, NULL,
-                               MAILBOX_OPEN_READONLY |
-                               MAILBOX_OPEN_KEEP_RECENT |
-                               MAILBOX_OPEN_IGNORE_ACLS);
-       if (box == NULL) {
-               mailbox_list_get_last_error(ns->list, &error);
+       box = dbox_mailbox_alloc(&ctx->storage->storage, ns->list, name, NULL,
+                                MAILBOX_FLAG_READONLY |
+                                MAILBOX_FLAG_KEEP_RECENT |
+                                MAILBOX_FLAG_IGNORE_ACLS);
+       if (dbox_mailbox_open(box) < 0) {
+               (void)mail_storage_get_last_error(box->storage, &error);
+               mailbox_close(&box);
                if (error == MAIL_ERROR_TEMP)
                        return -1;
                /* non-temporary error, ignore */
@@ -416,7 +417,7 @@ rebuild_mailbox(struct dbox_storage_rebuild_context *ctx,
        if (ret <= 0) {
                i_assert(ret != 0);
                mail_storage_set_index_error(&mbox->ibox);
-               (void)mailbox_close(&box);
+               mailbox_close(&box);
                return -1;
        }
 
@@ -431,7 +432,7 @@ rebuild_mailbox(struct dbox_storage_rebuild_context *ctx,
                ret = -1;
        }
 
-       (void)mailbox_close(&box);
+       mailbox_close(&box);
        return ret < 0 ? -1 : 0;
 }
 
@@ -484,7 +485,7 @@ static int rebuild_msg_mailbox_commit(struct rebuild_msg_mailbox *msg)
 {
        if (mail_index_sync_commit(&msg->sync_ctx) < 0)
                return -1;
-       (void)mailbox_close(&msg->box);
+       mailbox_close(&msg->box);
        memset(msg, 0, sizeof(*msg));
        return 0;
 }
@@ -533,15 +534,16 @@ static int rebuild_restore_msg(struct dbox_storage_rebuild_context *ctx,
                strcmp(mailbox, ctx->prev_msg.box->name) == 0 ?
                ctx->prev_msg.box : NULL;
        while (box == NULL) {
-               box = dbox_mailbox_open(storage, ctx->default_list,
-                                       mailbox, NULL,
-                                       MAILBOX_OPEN_READONLY |
-                                       MAILBOX_OPEN_KEEP_RECENT |
-                                       MAILBOX_OPEN_IGNORE_ACLS);
-               if (box != NULL)
+               box = dbox_mailbox_alloc(storage, ctx->default_list,
+                                        mailbox, NULL,
+                                        MAILBOX_FLAG_READONLY |
+                                        MAILBOX_FLAG_KEEP_RECENT |
+                                        MAILBOX_FLAG_IGNORE_ACLS);
+               if (dbox_mailbox_open(box) == 0)
                        break;
 
-               mail_storage_get_last_error(storage, &error);
+               (void)mail_storage_get_last_error(box->storage, &error);
+               mailbox_close(&box);
                if (error == MAIL_ERROR_TEMP)
                        return -1;
 
@@ -574,7 +576,7 @@ static int rebuild_restore_msg(struct dbox_storage_rebuild_context *ctx,
                if (ret <= 0) {
                        i_assert(ret != 0);
                        mail_storage_set_index_error(&mbox->ibox);
-                       (void)mailbox_close(&box);
+                       mailbox_close(&box);
                        return -1;
                }
                ctx->prev_msg.box = box;
index 0004d82ba4c2f6b407fc108f4d3c1e835a8f61dc..8cddab087df2476b7500487734fb3f27c741579f 100644 (file)
@@ -136,59 +136,49 @@ dbox_get_alt_path(struct mailbox_list *list, const char *path)
        return NULL;
 }
 
-static struct mailbox *
-dbox_open(struct dbox_storage *storage, struct mailbox_list *list,
-         const char *name, enum mailbox_open_flags flags)
+struct mailbox *
+dbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input,
+                  enum mailbox_flags flags)
 {
-       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;
 
        /* dbox can't work without index files */
-       flags &= ~MAILBOX_OPEN_NO_INDEX_FILES;
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-
-       index = index_storage_alloc(list, name, flags, DBOX_INDEX_PREFIX);
-       mail_index_set_fsync_types(index, MAIL_INDEX_SYNC_TYPE_APPEND |
-                                  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+       flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
 
        pool = pool_alloconly_create("dbox mailbox", 1024+512);
        mbox = p_new(pool, struct dbox_mailbox, 1);
        mbox->ibox.box = dbox_mailbox;
        mbox->ibox.box.pool = pool;
-       mbox->ibox.box.storage = _storage;
+       mbox->ibox.box.storage = storage;
        mbox->ibox.box.list = list;
        mbox->ibox.mail_vfuncs = &dbox_mail_vfuncs;
-       mbox->ibox.index = index;
        mbox->ibox.keep_index_backups = TRUE;
        mbox->ibox.index_never_in_memory = TRUE;
-       mbox->path = p_strdup(pool, path);
-       mbox->alt_path = p_strdup(pool, dbox_get_alt_path(list, path));
-       mbox->storage = storage;
 
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
+                                   DBOX_INDEX_PREFIX);
+       mail_index_set_fsync_types(mbox->ibox.index,
+                                  MAIL_INDEX_SYNC_TYPE_APPEND |
+                                  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+
+       mbox->storage = (struct dbox_storage *)storage;
+       mbox->alt_path =
+               p_strdup(pool, dbox_get_alt_path(list, mbox->ibox.box.path));
        mbox->dbox_ext_id =
-               mail_index_ext_register(index, "dbox", 0,
+               mail_index_ext_register(mbox->ibox.index, "dbox", 0,
                                        sizeof(struct dbox_mail_index_record),
                                        sizeof(uint32_t));
        mbox->dbox_hdr_ext_id =
-               mail_index_ext_register(index, "dbox-hdr",
+               mail_index_ext_register(mbox->ibox.index, "dbox-hdr",
                                        sizeof(struct dbox_index_header), 0, 0);
        mbox->guid_ext_id =
-               mail_index_ext_register(index, "guid", 0, DBOX_GUID_BIN_LEN, 1);
+               mail_index_ext_register(mbox->ibox.index, "guid",
+                                       0, DBOX_GUID_BIN_LEN, 1);
 
-       ret = index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
        mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox);
-
-       box = &mbox->ibox.box;
-       if (ret < 0)
-               mailbox_close(&box);
-       return box;
+       return &mbox->ibox.box;
 }
 
 uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list)
@@ -201,7 +191,7 @@ uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list)
        return mailbox_uidvalidity_next(path);
 }
 
-static void dbox_write_index_header(struct mailbox *box)
+static int dbox_write_index_header(struct mailbox *box)
 {
        struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
        struct mail_index_transaction *trans;
@@ -209,7 +199,7 @@ static void dbox_write_index_header(struct mailbox *box)
        uint32_t uid_validity;
 
        if (dbox_map_open(mbox->storage->map, TRUE) < 0)
-               return;
+               return -1;
 
        trans = mail_index_transaction_begin(mbox->ibox.view, 0);
 
@@ -225,33 +215,25 @@ static void dbox_write_index_header(struct mailbox *box)
                offsetof(struct mail_index_header, uid_validity),
                &uid_validity, sizeof(uid_validity), TRUE);
 
-       (void)mail_index_transaction_commit(&trans);
+       return mail_index_transaction_commit(&trans);
 }
 
-static int create_dbox(struct mail_storage *_storage, struct mailbox_list *list,
-                      const char *path, const char *name, bool directory)
+static int create_dbox(struct mailbox *box)
 {
-       struct dbox_storage *storage = (struct dbox_storage *)_storage;
-       struct mailbox *box;
        mode_t mode;
        gid_t gid;
 
-       mailbox_list_get_dir_permissions(list, NULL, &mode, &gid);
-       if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) == 0) {
-               if (!directory) {
-                       /* create indexes immediately with the dbox header */
-                       box = dbox_open(storage, list, name,
-                                       MAILBOX_OPEN_KEEP_RECENT);
-                       if (box == NULL)
-                               return -1;
-                       dbox_write_index_header(box);
-                       mailbox_close(&box);
-                       return 0;
-               }
+       mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid);
+       if (mkdir_parents_chown(box->path, mode, (uid_t)-1, gid) == 0) {
+               /* create indexes immediately with the dbox header */
+               if (index_storage_mailbox_open(box) < 0)
+                       return -1;
+               if (dbox_write_index_header(box) < 0)
+                       return -1;
        } else if (errno != EEXIST) {
-               if (!mail_storage_set_error_from_errno(_storage)) {
-                       mail_storage_set_critical(_storage,
-                               "mkdir(%s) failed: %m", path);
+               if (!mail_storage_set_error_from_errno(box->storage)) {
+                       mail_storage_set_critical(box->storage,
+                               "mkdir(%s) failed: %m", box->path);
                }
                return -1;
        }
@@ -281,53 +263,46 @@ dbox_cleanup_if_exists(struct mailbox_list *list, const char *path)
        return TRUE;
 }
 
-struct mailbox *
-dbox_mailbox_open(struct mail_storage *_storage, struct mailbox_list *list,
-                 const char *name, struct istream *input,
-                 enum mailbox_open_flags flags)
+int dbox_mailbox_open(struct mailbox *box)
 {
-       struct dbox_storage *storage = (struct dbox_storage *)_storage;
-       const char *path;
-
-       if (input != NULL) {
-               mailbox_list_set_critical(list,
+       if (box->input != NULL) {
+               mail_storage_set_critical(box->storage,
                        "dbox doesn't support streamed mailboxes");
-               return NULL;
+               return -1;
        }
 
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (dbox_cleanup_if_exists(list, path)) {
-               return dbox_open(storage, list, name, flags);
+       if (dbox_cleanup_if_exists(box->list, box->path)) {
+               return index_storage_mailbox_open(box);
        } else if (errno == ENOENT) {
-               if (strcmp(name, "INBOX") == 0 &&
-                   (list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
+               if (strcmp(box->name, "INBOX") == 0 &&
+                   (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
                        /* INBOX always exists, create it */
-                       if (create_dbox(_storage, list, path, name, FALSE) < 0) {
-                               mailbox_list_set_error_from_storage(list,
-                                                                   _storage);
-                               return NULL;
-                       }
-                       return dbox_open(storage, list, name, flags);
+                       if (create_dbox(box) < 0)
+                               return -1;
+                       return box->opened ? 0 :
+                               index_storage_mailbox_open(box);
                }
 
-               mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
-                       T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                       T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               return -1;
        } else if (errno == EACCES) {
-               mailbox_list_set_critical(list, "%s",
-                       mail_error_eacces_msg("stat", path));
+               mail_storage_set_critical(box->storage, "%s",
+                       mail_error_eacces_msg("stat", box->path));
+               return -1;
        } else {
-               mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
+               mail_storage_set_critical(box->storage,
+                                         "stat(%s) failed: %m", box->path);
+               return -1;
        }
-       return NULL;
 }
 
-static int dbox_storage_mailbox_close(struct mailbox *box)
+static void dbox_mailbox_close(struct mailbox *box)
 {
        struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
 
        maildir_uidlist_deinit(&mbox->maildir_uidlist);
-       return index_storage_mailbox_close(box);
+       index_storage_mailbox_close(box);
 }
 
 static int
@@ -335,7 +310,9 @@ dbox_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
                    const char *name, bool directory)
 {
        const char *path, *alt_path;
+       struct mailbox *box;
        struct stat st;
+       int ret;
 
        path = mailbox_list_get_path(list, name,
                                     directory ? MAILBOX_LIST_PATH_TYPE_DIR :
@@ -346,18 +323,39 @@ dbox_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
                return -1;
        }
 
+       if (directory) {
+               mode_t mode;
+               gid_t gid;
+
+               mailbox_list_get_dir_permissions(list, NULL, &mode, &gid);
+               if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) == 0)
+                       return 0;
+               else if (errno == EEXIST) {
+                       mail_storage_set_error(storage, MAIL_ERROR_EXISTS,
+                                              "Mailbox already exists");
+               } else if (!mail_storage_set_error_from_errno(storage)) {
+                       mail_storage_set_critical(storage,
+                                                 "mkdir(%s) failed: %m", path);
+               }
+               return -1;
+       }
+
        /* make sure the alt path doesn't exist yet. it shouldn't (except with
           race conditions with RENAME/DELETE), but if something crashed and
           left it lying around we don't want to start overwriting files in
           it. */
-       alt_path = directory ? NULL : dbox_get_alt_path(list, path);
+       alt_path = dbox_get_alt_path(list, path);
        if (alt_path != NULL && stat(alt_path, &st) == 0) {
                mail_storage_set_error(storage, MAIL_ERROR_EXISTS,
                                       "Mailbox already exists");
                return -1;
        }
 
-       return create_dbox(storage, list, path, name, directory);
+       box = dbox_mailbox_alloc(storage, list, name, NULL,
+                                MAILBOX_FLAG_KEEP_RECENT);
+       ret = create_dbox(box);
+       mailbox_close(&box);
+       return ret;
 }
 
 static int
@@ -381,11 +379,15 @@ dbox_mailbox_unref_mails(struct mailbox_list *list, const char *path)
        tmp_set = *list->mail_set;
        tmp_set.mail_full_filesystem_access = TRUE;
        list->mail_set = &tmp_set;
-       box = dbox_open(storage, list, path, MAILBOX_OPEN_IGNORE_ACLS |
-                       MAILBOX_OPEN_KEEP_RECENT);
+       box = dbox_mailbox_alloc(&storage->storage, list, path, NULL,
+                                MAILBOX_FLAG_IGNORE_ACLS |
+                                MAILBOX_FLAG_KEEP_RECENT);
+       ret = mailbox_open(box);
        list->mail_set = old_set;
-       if (box == NULL)
+       if (ret < 0) {
+               mailbox_close(&box);
                return -1;
+       }
        mbox = (struct dbox_mailbox *)box;
 
        /* get a list of all map_uids in this mailbox */
@@ -644,7 +646,7 @@ static void dbox_notify_changes(struct mailbox *box)
                index_mailbox_check_remove_all(&mbox->ibox);
        else {
                path = t_strdup_printf("%s/"DBOX_INDEX_PREFIX".log",
-                                      mbox->path);
+                                      mbox->ibox.box.path);
                index_mailbox_check_add(&mbox->ibox, path);
        }
 }
@@ -757,7 +759,7 @@ struct mail_storage dbox_storage = {
                dbox_storage_add_list,
                dbox_storage_get_list_settings,
                NULL,
-               dbox_mailbox_open,
+               dbox_mailbox_alloc,
                dbox_mailbox_create,
                dbox_sync_purge
        }
@@ -772,7 +774,8 @@ struct mailbox dbox_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               dbox_storage_mailbox_close,
+               dbox_mailbox_open,
+               dbox_mailbox_close,
                index_storage_get_status,
                NULL,
                NULL,
index 9471910cd2d4697089d373fdee3a6776f5a2e47a..ad6eb0f1cc0199914e6e6252d23e27ae403e6e3d 100644 (file)
@@ -73,7 +73,7 @@ struct dbox_mailbox {
 
        uint32_t dbox_ext_id, dbox_hdr_ext_id, guid_ext_id;
 
-       const char *path, *alt_path;
+       const char *alt_path;
 };
 
 struct dbox_transaction_context {
@@ -90,9 +90,10 @@ void dbox_transaction_class_init(void);
 void dbox_transaction_class_deinit(void);
 
 struct mailbox *
-dbox_mailbox_open(struct mail_storage *_storage, struct mailbox_list *list,
-                 const char *name, struct istream *input,
-                 enum mailbox_open_flags flags);
+dbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input,
+                  enum mailbox_flags flags);
+int dbox_mailbox_open(struct mailbox *box);
 
 struct mail *
 dbox_mail_alloc(struct mailbox_transaction_context *t,
index 6e66dfa7dea654b224a025e75e46857430bc1f2e..62942fe77b56587c9015599182e4b44965c3e0c2 100644 (file)
@@ -191,7 +191,7 @@ dbox_sync_add_uid_file(struct dbox_sync_rebuild_context *ctx,
        uid = strtoul(fname, &p, 10);
        if (*p != '\0' || uid == 0 || uid >= (uint32_t)-1) {
                i_warning("dbox %s: Ignoring invalid filename %s",
-                         ctx->mbox->path, fname);
+                         ctx->mbox->ibox.box.path, fname);
                return 0;
        }
 
@@ -234,7 +234,7 @@ dbox_sync_add_maildir_file(struct dbox_sync_rebuild_context *ctx,
        ret = maildir_uidlist_sync_next(ctx->maildir_sync_ctx, fname, 0);
        if (ret == 0) {
                i_warning("%s: Ignoring duplicate maildir file: %s",
-                         ctx->mbox->path, fname);
+                         ctx->mbox->ibox.box.path, fname);
        }
        return ret;
 }
@@ -334,7 +334,8 @@ static int dbox_sync_maildir_finish(struct dbox_sync_rebuild_context *ctx)
        while (maildir_uidlist_iter_next(iter, &uid, &flags, &fname)) {
                file = dbox_file_init_single(mbox, uid);
                file->current_path =
-                       i_strdup_printf("%s/%s", ctx->mbox->path, fname);
+                       i_strdup_printf("%s/%s", ctx->mbox->ibox.box.path,
+                                       fname);
 
                ret = dbox_sync_add_file_index(ctx, file);
                dbox_file_unref(&file);
@@ -411,7 +412,7 @@ int dbox_sync_index_rebuild_singles(struct dbox_sync_rebuild_context *ctx)
        int ret = 0;
 
        dbox_sync_set_uidvalidity(ctx);
-       if (dbox_sync_index_rebuild_dir(ctx, ctx->mbox->path, TRUE) < 0)
+       if (dbox_sync_index_rebuild_dir(ctx, ctx->mbox->ibox.box.path, TRUE) < 0)
                ret = -1;
        else if (ctx->mbox->alt_path != NULL) {
                if (dbox_sync_index_rebuild_dir(ctx, ctx->mbox->alt_path,
index 41509ef80f0543795fee71f2851af1a5082b07ca..c9687eeaf55b77bb2e0fb151769e3135062ec701 100644 (file)
@@ -221,7 +221,7 @@ static int dbox_refresh_header(struct dbox_mailbox *mbox, bool retry)
                   data_size=4 is for backwards compatibility */
                if (data_size != 0 && data_size != 4) {
                        i_warning("dbox %s: Invalid dbox header size",
-                                 mbox->path);
+                                 mbox->ibox.box.path);
                }
                ret = -1;
        } else {
@@ -301,17 +301,17 @@ int dbox_sync_begin(struct dbox_mailbox *mbox, enum dbox_sync_flags flags,
                        if (mbox->storage->have_multi_msgs) {
                                mail_storage_set_critical(storage,
                                        "dbox %s: Storage keeps breaking",
-                                       ctx->mbox->path);
+                                       ctx->mbox->ibox.box.path);
                                ret = -1;
                        } else if (i >= DBOX_REBUILD_COUNT) {
                                mail_storage_set_critical(storage,
                                        "dbox %s: Index keeps breaking",
-                                       ctx->mbox->path);
+                                       ctx->mbox->ibox.box.path);
                                ret = -1;
                        } else {
                                /* do a full resync and try again. */
                                i_warning("dbox %s: Rebuilding index",
-                                         ctx->mbox->path);
+                                         ctx->mbox->ibox.box.path);
                                ret = dbox_sync_index_rebuild(mbox);
                        }
                }
@@ -373,7 +373,7 @@ dbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        int ret = 0;
 
        if (!box->opened) {
-               if (index_storage_mailbox_open(&mbox->ibox) < 0)
+               if (mailbox_open(box) < 0)
                        ret = -1;
        }
 
index 77f15051edb89389cc59090d8d39af5444ac789c..a1b06da7a2ed8a79e9be8de254613edc996fa152 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
-#include "buffer.h"
+#include "istream.h"
 #include "ioloop.h"
 #include "imap-parser.h"
 #include "mkdir-parents.h"
@@ -107,11 +107,11 @@ static int create_index_dir(struct mailbox_list *list, const char *name)
 
 static const char *
 get_index_dir(struct mailbox_list *list, const char *name,
-             enum mailbox_open_flags flags, struct stat *st_r)
+             enum mailbox_flags flags, struct stat *st_r)
 {
        const char *index_dir;
 
-       index_dir = (flags & MAILBOX_OPEN_NO_INDEX_FILES) != 0 ? "" :
+       index_dir = (flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
                mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_INDEX);
        if (*index_dir == '\0') {
                /* disabled */
@@ -139,9 +139,9 @@ get_index_dir(struct mailbox_list *list, const char *name,
        return index_dir;
 }
 
-struct mail_index *
+static struct mail_index *
 index_storage_alloc(struct mailbox_list *list, const char *name,
-                   enum mailbox_open_flags flags, const char *prefix)
+                   enum mailbox_flags flags, const char *prefix)
 {
        struct index_list **indexp, *rec;
        struct mail_index *index;
@@ -149,6 +149,7 @@ index_storage_alloc(struct mailbox_list *list, const char *name,
        const char *index_dir, *mailbox_path;
        int destroy_count;
 
+       // FIXME: failure handling when dirs don't exist yet?
        mailbox_path = mailbox_list_get_path(list, name,
                                             MAILBOX_LIST_PATH_TYPE_MAILBOX);
        index_dir = get_index_dir(list, name, flags, &st);
@@ -365,16 +366,30 @@ void index_storage_lock_notify_reset(struct index_mailbox *ibox)
        ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE;
 }
 
-int index_storage_mailbox_open(struct index_mailbox *ibox)
+int index_storage_mailbox_open(struct mailbox *box)
 {
-       struct mail_storage *storage = ibox->box.storage;
-       enum file_lock_method lock_method = storage->set->parsed_lock_method;
+       struct index_mailbox *ibox = (struct index_mailbox *)box;
+       enum file_lock_method lock_method =
+               box->storage->set->parsed_lock_method;
        enum mail_index_open_flags index_flags;
+       gid_t dir_gid;
        int ret;
 
-       i_assert(!ibox->box.opened);
+       i_assert(!box->opened);
 
-       index_flags = mail_storage_settings_to_index_flags(storage->set);
+       if (box->file_create_mode == 0) {
+               mailbox_list_get_permissions(box->list, box->name,
+                                            &box->file_create_mode,
+                                            &box->file_create_gid);
+               mailbox_list_get_dir_permissions(box->list, box->name,
+                                                &box->dir_create_mode,
+                                                &dir_gid);
+               mail_index_set_permissions(ibox->index,
+                                          box->file_create_mode,
+                                          box->file_create_gid);
+       }
+
+       index_flags = mail_storage_settings_to_index_flags(box->storage->set);
        if (!ibox->move_to_memory)
                index_flags |= MAIL_INDEX_OPEN_FLAG_CREATE;
        if (ibox->keep_index_backups)
@@ -407,55 +422,52 @@ int index_storage_mailbox_open(struct index_mailbox *ibox)
        MODULE_CONTEXT_SET_FULL(ibox->view, mail_storage_mail_index_module,
                                ibox, &ibox->view_module_ctx);
 
-       ibox->box.opened = TRUE;
+       box->opened = TRUE;
 
        index_thread_mailbox_index_opened(ibox);
        if (hook_mailbox_index_opened != NULL)
-               hook_mailbox_index_opened(&ibox->box);
+               hook_mailbox_index_opened(box);
        return 0;
 }
 
-int index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
-                              enum mailbox_open_flags flags,
-                              bool move_to_memory)
+void index_storage_mailbox_alloc(struct index_mailbox *ibox, const char *name,
+                                struct istream *input,
+                                enum mailbox_flags flags,
+                                const char *index_prefix)
 {
-       struct mail_storage *storage = ibox->box.storage;
        struct mailbox *box = &ibox->box;
-       gid_t dir_gid;
+       const char *path;
 
-       i_assert(name != NULL);
+       if (name != NULL)
+               box->name = p_strdup(box->pool, name);
+       else {
+               i_assert(input != NULL);
+               box->name = "(read-only input stream)";
+       }
 
-       box->storage = storage;
-       box->name = p_strdup(box->pool, name);
-       box->open_flags = flags;
-       if (box->file_create_mode == 0) {
-               mailbox_list_get_permissions(box->list, name,
-                                            &box->file_create_mode,
-                                            &box->file_create_gid);
-               mailbox_list_get_dir_permissions(box->list, name,
-                                                &box->dir_create_mode,
-                                                &dir_gid);
-               mail_index_set_permissions(ibox->index, box->file_create_mode,
-                                          box->file_create_gid);
+       if (input != NULL) {
+               flags |= MAILBOX_FLAG_READONLY;
+               box->input = input;
+               i_stream_ref(input);
        }
+       box->flags = flags;
 
        p_array_init(&box->search_results, box->pool, 16);
        array_create(&box->module_contexts,
                     box->pool, sizeof(void *), 5);
 
-       ibox->keep_recent = (flags & MAILBOX_OPEN_KEEP_RECENT) != 0;
-       ibox->keep_locked = (flags & MAILBOX_OPEN_KEEP_LOCKED) != 0;
-       ibox->move_to_memory = move_to_memory;
+       path = mailbox_list_get_path(box->list, name,
+                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
+       ibox->box.path = p_strdup(box->pool, path);
+
+       ibox->keep_recent = (flags & MAILBOX_FLAG_KEEP_RECENT) != 0;
+       ibox->keep_locked = (flags & MAILBOX_FLAG_KEEP_LOCKED) != 0;
 
        ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL;
        ibox->commit_log_file_seq = 0;
-
+       ibox->index = index_storage_alloc(box->list, name, flags, index_prefix);
        ibox->md5hdr_ext_idx =
                mail_index_ext_register(ibox->index, "header-md5", 0, 16, 1);
-
-       if ((flags & MAILBOX_OPEN_FAST) == 0)
-               return index_storage_mailbox_open(ibox);
-       return 0;
 }
 
 int index_storage_mailbox_enable(struct mailbox *box,
@@ -466,7 +478,7 @@ int index_storage_mailbox_enable(struct mailbox *box,
        if ((feature & MAILBOX_FEATURE_CONDSTORE) != 0) {
                box->enabled_features |= MAILBOX_FEATURE_CONDSTORE;
                if (!box->opened) {
-                       if (index_storage_mailbox_open(ibox) < 0)
+                       if (mailbox_open(box) < 0)
                                return -1;
                }
                mail_index_modseq_enable(ibox->index);
@@ -474,7 +486,7 @@ int index_storage_mailbox_enable(struct mailbox *box,
        return 0;
 }
 
-int index_storage_mailbox_close(struct mailbox *box)
+void index_storage_mailbox_close(struct mailbox *box)
 {
        struct index_mailbox *ibox = (struct index_mailbox *) box;
 
@@ -482,6 +494,8 @@ int index_storage_mailbox_close(struct mailbox *box)
                mail_index_view_close(&ibox->view);
 
        index_mailbox_check_remove_all(ibox);
+       if (ibox->box.input != NULL)
+               i_stream_unref(&ibox->box.input);
        if (ibox->index != NULL)
                index_storage_unref(ibox->index);
        if (array_is_created(&ibox->recent_flags))
@@ -489,14 +503,13 @@ int index_storage_mailbox_close(struct mailbox *box)
        i_free(ibox->cache_fields);
 
        pool_unref(&box->pool);
-       return 0;
 }
 
 bool index_storage_is_readonly(struct mailbox *box)
 {
        struct index_mailbox *ibox = (struct index_mailbox *) box;
 
-       return (ibox->box.open_flags & MAILBOX_OPEN_READONLY) != 0 ||
+       return (box->flags & MAILBOX_FLAG_READONLY) != 0 ||
                ibox->backend_readonly;
 }
 
index 0807ecff43b3e35dd66f2f45126a74db434e7641..1d4c0660d9ac069a6d7c6c17e86c0b216149b2b7 100644 (file)
@@ -85,20 +85,18 @@ void index_storage_lock_notify(struct index_mailbox *ibox,
                               unsigned int secs_left);
 void index_storage_lock_notify_reset(struct index_mailbox *ibox);
 
-struct mail_index *
-index_storage_alloc(struct mailbox_list *list, const char *name,
-                   enum mailbox_open_flags flags, const char *prefix);
 void index_storage_unref(struct mail_index *index);
 void index_storage_destroy_unrefed(void);
 void index_storage_destroy(struct mail_storage *storage ATTR_UNUSED);
 
-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);
+void index_storage_mailbox_alloc(struct index_mailbox *ibox, const char *name,
+                                struct istream *input,
+                                enum mailbox_flags flags,
+                                const char *index_prefix);
+int index_storage_mailbox_open(struct mailbox *box);
 int index_storage_mailbox_enable(struct mailbox *box,
                                 enum mailbox_feature feature);
-int index_storage_mailbox_close(struct mailbox *box);
+void index_storage_mailbox_close(struct mailbox *box);
 
 bool index_storage_is_readonly(struct mailbox *box);
 bool index_storage_allow_new_keywords(struct mailbox *box);
index cd4b3baebe7a69fb47ea28b5d0039d6998897c9b..6d4d241910d02016e9b116981a8325eef77566d4 100644 (file)
@@ -609,10 +609,9 @@ mail_thread_iterate_init(struct mail_thread_context *ctx,
                                             thread_type, write_seqs);
 }
 
-static int mail_thread_mailbox_close(struct mailbox *box)
+static void mail_thread_mailbox_close(struct mailbox *box)
 {
        struct mail_thread_mailbox *tbox = MAIL_THREAD_CONTEXT(box);
-       int ret;
 
        i_assert(tbox->ctx == NULL);
 
@@ -624,9 +623,8 @@ static int mail_thread_mailbox_close(struct mailbox *box)
        array_free(&tbox->cache->thread_nodes);
        i_free(tbox->cache);
 
-       ret = tbox->module_ctx.super.close(box);
+       tbox->module_ctx.super.close(box);
        i_free(tbox);
-       return ret;
 }
 
 void index_thread_mailbox_index_opened(struct index_mailbox *ibox)
index 3cfa76e5fd177eae44135d275bb8adc8393ca9c8..2e0d158632b2cd2574dea3e1b22c085df3fe5b25 100644 (file)
@@ -211,7 +211,7 @@ maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
                /* keywords, hardlink to tmp/ with basename and later when we
                   have uidlist locked, move it to new/cur. */
                str_printfa(do_ctx.dest_path, "%s/tmp/%s",
-                           dest_mbox->path, do_ctx.dest_fname);
+                           dest_mbox->ibox.box.path, do_ctx.dest_fname);
                do_ctx.base_end_pos = str_len(do_ctx.dest_path);
        }
        if (src_mbox != NULL) {
index 71698a9968b2cb786820cd379374e1d395982486..c243c5433ce2cf32462fdf78cfa69e46e6a5ded0 100644 (file)
@@ -372,7 +372,7 @@ static int maildir_keywords_commit(struct maildir_keywords *mk)
                }
                /* the control dir doesn't exist. create it unless the whole
                   mailbox was just deleted. */
-               if (!maildir_set_deleted(mk->mbox))
+               if (!maildir_set_deleted(&mk->mbox->ibox.box))
                        return -1;
        }
 
index ab498b9062886e232cec209647be10955ad8cc12..e0ff0a6460cda0bc69699510e3664fbd0b184642 100644 (file)
@@ -226,8 +226,7 @@ static int maildir_get_pop3_state(struct index_mail *mail)
                /* either nothing is cached, or only vsize is cached. */
                mail->pop3_state = 1;
        } else if (vsize_dec != MAIL_CACHE_DECISION_YES &&
-                  (mail->ibox->box.open_flags &
-                   MAILBOX_OPEN_POP3_SESSION) == 0) {
+                  (mail->ibox->box.flags & MAILBOX_FLAG_POP3_SESSION) == 0) {
                /* if virtual size isn't cached permanently,
                   POP3 isn't being used */
                mail->pop3_state = -1;
@@ -502,7 +501,7 @@ static void maildir_mail_set_cache_corrupted(struct mail *_mail,
                                "new" : "cur";
                        mail_storage_set_critical(_mail->box->storage,
                                "Maildir filename has wrong W value: %s/%s/%s",
-                               mbox->path, subdir, fname);
+                               mbox->ibox.box.path, subdir, fname);
                } else if (maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
                                MAILDIR_UIDLIST_REC_EXT_VSIZE) != NULL) {
                        maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
index 248e74d8fdedd2089dea774730cb20fac9b1aa29..49f05f9a90939e16bf8ed627300ee9650430903c 100644 (file)
@@ -122,9 +122,9 @@ maildir_save_transaction_init(struct maildir_transaction_context *t)
        ctx->files_tail = &ctx->files;
        ctx->fd = -1;
 
-       ctx->tmpdir = p_strconcat(pool, mbox->path, "/tmp", NULL);
-       ctx->newdir = p_strconcat(pool, mbox->path, "/new", NULL);
-       ctx->curdir = p_strconcat(pool, mbox->path, "/cur", NULL);
+       ctx->tmpdir = p_strconcat(pool, mbox->ibox.box.path, "/tmp", NULL);
+       ctx->newdir = p_strconcat(pool, mbox->ibox.box.path, "/new", NULL);
+       ctx->curdir = p_strconcat(pool, mbox->ibox.box.path, "/cur", NULL);
 
        ctx->keywords_buffer = buffer_create_const_data(pool, NULL, 0);
        array_create_from_buffer(&ctx->keywords_array, ctx->keywords_buffer,
@@ -525,7 +525,8 @@ static int maildir_save_finish_real(struct mail_save_context *_ctx)
                                MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE);
                } else if (errno != 0) {
                        mail_storage_set_critical(storage,
-                               "write(%s) failed: %m", ctx->mbox->path);
+                               "write(%s) failed: %m",
+                               ctx->mbox->ibox.box.path);
                }
 
                /* remove from the linked list */
index e703204b4dc6a3ae26f4a62c4807e5147b217f2e..60b3eb4a833e967f2d92e024128998277795f1d6 100644 (file)
@@ -295,19 +295,17 @@ create_maildir(struct mail_storage *storage, struct mail_namespace *ns,
        unsigned int i;
        int ret;
 
-       ret = maildir_check_tmp(storage, dir);
-       if (ret > 0) {
-               if (!verify) {
+       if (!verify) {
+               ret = maildir_check_tmp(storage, dir);
+               if (ret > 0) {
                        mail_storage_set_error(storage,
                                MAIL_ERROR_EXISTS, "Mailbox already exists");
                        return -1;
                }
-               return 1;
+               if (ret < 0)
+                       return -1;
        }
-       if (ret < 0)
-               return -1;
 
-       /* doesn't exist, create */
        for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
                path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
                if (mkdir_verify(storage, ns, path, mode, gid, verify) < 0)
@@ -331,140 +329,114 @@ static mode_t get_dir_mode(mode_t mode)
 }
 
 static struct mailbox *
-maildir_open(struct mail_storage *storage, struct mail_namespace *ns,
-            const char *name, enum mailbox_open_flags flags)
+maildir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                     const char *name, struct istream *input,
+                     enum mailbox_flags flags)
 {
        struct maildir_mailbox *mbox;
-       struct mail_index *index;
-       const char *path, *control_dir;
-       struct stat st;
        pool_t pool;
 
-       path = mailbox_list_get_path(ns->list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       control_dir = mailbox_list_get_path(ns->list, name,
-                                           MAILBOX_LIST_PATH_TYPE_CONTROL);
-
        pool = pool_alloconly_create("maildir mailbox", 1024+512);
        mbox = p_new(pool, struct maildir_mailbox, 1);
        mbox->ibox.box = maildir_mailbox;
        mbox->ibox.box.pool = pool;
        mbox->ibox.box.storage = storage;
-       mbox->ibox.box.list = ns->list;
+       mbox->ibox.box.list = list;
        mbox->ibox.mail_vfuncs = &maildir_mail_vfuncs;
 
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
+                                   MAILDIR_INDEX_PREFIX);
+
        mbox->storage = (struct maildir_storage *)storage;
-       mbox->path = p_strdup(pool, path);
+       mbox->maildir_ext_id =
+               mail_index_ext_register(mbox->ibox.index, "maildir",
+                                       sizeof(mbox->maildir_hdr), 0, 0);
+       mbox->uidlist = maildir_uidlist_init(mbox);
+       mbox->keywords = maildir_keywords_init(mbox);
+       return &mbox->ibox.box;
+}
 
-       index = index_storage_alloc(ns->list, name, flags,
-                                   MAILDIR_INDEX_PREFIX);
-       mbox->ibox.index = index;
+static int maildir_mailbox_open_existing(struct mailbox *box)
+{
+       struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
+       struct stat st;
 
        /* for shared mailboxes get the create mode from the
           permissions of dovecot-shared file. */
-       if (stat(t_strconcat(path, "/dovecot-shared", NULL), &st) == 0) {
+       if (stat(t_strconcat(box->path, "/dovecot-shared", NULL), &st) == 0) {
                if ((st.st_mode & S_ISGID) != 0 ||
                    (st.st_mode & 0060) == 0) {
                        /* Ignore GID */
                        st.st_gid = (gid_t)-1;
                }
-               mail_index_set_permissions(index, st.st_mode & 0666, st.st_gid);
+               mail_index_set_permissions(mbox->ibox.index,
+                                          st.st_mode & 0666, st.st_gid);
 
-               mbox->ibox.box.file_create_mode = st.st_mode & 0666;
-               mbox->ibox.box.dir_create_mode =
-                       get_dir_mode(st.st_mode & 0666);
-               mbox->ibox.box.file_create_gid = st.st_gid;
-               mbox->ibox.box.private_flags_mask = MAIL_SEEN;
+               box->file_create_mode = st.st_mode & 0666;
+               box->dir_create_mode = get_dir_mode(st.st_mode & 0666);
+               box->file_create_gid = st.st_gid;
+               box->private_flags_mask = MAIL_SEEN;
        }
 
-       mbox->maildir_ext_id =
-               mail_index_ext_register(index, "maildir",
-                                       sizeof(mbox->maildir_hdr), 0, 0);
-
-       index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
-       mbox->uidlist = maildir_uidlist_init(mbox);
-       if ((flags & MAILBOX_OPEN_KEEP_LOCKED) != 0) {
-               if (maildir_uidlist_lock(mbox->uidlist) <= 0) {
-                       struct mailbox *box = &mbox->ibox.box;
-
-                       mailbox_close(&box);
-                       mailbox_list_set_error_from_storage(ns->list, storage);
-                       return NULL;
-               }
+       if ((box->flags & MAILBOX_FLAG_KEEP_LOCKED) != 0) {
+               if (maildir_uidlist_lock(mbox->uidlist) <= 0)
+                       return -1;
                mbox->keep_lock_to = timeout_add(MAILDIR_LOCK_TOUCH_SECS * 1000,
                                                 maildir_lock_touch_timeout,
                                                 mbox);
        }
 
-       if (access(t_strconcat(path, "/cur", NULL), W_OK) < 0 &&
+       if (access(t_strconcat(box->path, "/cur", NULL), W_OK) < 0 &&
            errno == EACCES)
                mbox->ibox.backend_readonly = TRUE;
-
-       mbox->keywords = maildir_keywords_init(mbox);
-       return &mbox->ibox.box;
+       return index_storage_mailbox_open(box);
 }
 
-static struct mailbox *
-maildir_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                    const char *name, struct istream *input,
-                    enum mailbox_open_flags flags)
+static int maildir_mailbox_open(struct mailbox *box)
 {
-       const char *path;
        struct stat st;
        mode_t mode;
        gid_t gid;
        int ret;
+       bool inbox;
 
-       if (input != NULL) {
-               mailbox_list_set_critical(list,
+       if (box->input != NULL) {
+               mail_storage_set_critical(box->storage,
                        "Maildir doesn't support streamed mailboxes");
-               return NULL;
+               return -1;
        }
 
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (strcmp(name, "INBOX") == 0 &&
-           (list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
-               /* INBOX always exists */
-               mailbox_list_get_dir_permissions(list, NULL, &mode, &gid);
-               if (create_maildir(storage, list->ns, path,
-                                  mode, gid, TRUE) < 0) {
-                       mailbox_list_set_error_from_storage(list, storage);
-                       return NULL;
-               }
-               return maildir_open(storage, list->ns, "INBOX", flags);
-       }
+       inbox = strcmp(box->name, "INBOX") == 0 &&
+               (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0;
 
        /* begin by checking if tmp/ directory exists and if it should be
           cleaned up. */
-       ret = maildir_check_tmp(storage, path);
+       ret = maildir_check_tmp(box->storage, box->path);
        if (ret > 0) {
                /* exists */
-               return maildir_open(storage, list->ns, name, flags);
-       }
-       if (ret < 0) {
-               mailbox_list_set_error_from_storage(list, storage);
-               return NULL;
+               return maildir_mailbox_open_existing(box);
        }
+       if (ret < 0)
+               return -1;
 
        /* tmp/ directory doesn't exist. does the maildir? */
-       if (stat(path, &st) == 0) {
+       if (inbox || stat(box->path, &st) == 0) {
                /* yes, we'll need to create the missing dirs */
-               mailbox_list_get_dir_permissions(list, name, &mode, &gid);
-               if (create_maildir(storage, list->ns, path,
-                                  mode, gid, TRUE) < 0) {
-                       mailbox_list_set_error_from_storage(list, storage);
-                       return NULL;
-               }
+               mailbox_list_get_dir_permissions(box->list, box->name,
+                                                &mode, &gid);
+               if (create_maildir(box->storage, box->list->ns, box->path,
+                                  mode, gid, TRUE) < 0)
+                       return -1;
 
-               return maildir_open(storage, list->ns, name, flags);
+               return maildir_mailbox_open_existing(box);
        } else if (errno == ENOENT) {
-               mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
-                       T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
-               return NULL;
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                       T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               return -1;
        } else {
-               mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
-               return NULL;
+               mail_storage_set_critical(box->storage,
+                                         "stat(%s) failed: %m", box->path);
+               return -1;
        }
 }
 
@@ -786,7 +758,7 @@ maildir_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
                               rename_children);
 }
 
-static int maildir_storage_mailbox_close(struct mailbox *box)
+static void maildir_mailbox_close(struct mailbox *box)
 {
        struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
 
@@ -800,7 +772,7 @@ static int maildir_storage_mailbox_close(struct mailbox *box)
        if (mbox->keywords != NULL)
                maildir_keywords_deinit(&mbox->keywords);
        maildir_uidlist_deinit(&mbox->uidlist);
-       return index_storage_mailbox_close(box);
+       index_storage_mailbox_close(box);
 }
 
 static void maildir_notify_changes(struct mailbox *box)
@@ -811,9 +783,9 @@ static void maildir_notify_changes(struct mailbox *box)
                index_mailbox_check_remove_all(&mbox->ibox);
        else {
                index_mailbox_check_add(&mbox->ibox,
-                                       t_strconcat(mbox->path, "/new", NULL));
+                       t_strconcat(mbox->ibox.box.path, "/new", NULL));
                index_mailbox_check_add(&mbox->ibox,
-                                       t_strconcat(mbox->path, "/cur", NULL));
+                       t_strconcat(mbox->ibox.box.path, "/cur", NULL));
        }
 }
 
@@ -1040,7 +1012,7 @@ struct mail_storage maildir_storage = {
                maildir_storage_add_list,
                maildir_storage_get_list_settings,
                maildir_storage_autodetect,
-               maildir_mailbox_open,
+               maildir_mailbox_alloc,
                maildir_mailbox_create,
                NULL
        }
@@ -1055,7 +1027,8 @@ struct mailbox maildir_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               maildir_storage_mailbox_close,
+               maildir_mailbox_open,
+               maildir_mailbox_close,
                index_storage_get_status,
                maildir_list_index_has_changed,
                maildir_list_index_update_sync,
index 4e0880bce9e6bed6159a0ec5ee79827a73962c56..c572597536982ebd3beb59c6ff9dc454fa2ca24d 100644 (file)
@@ -83,7 +83,6 @@ struct maildir_mailbox {
        struct maildir_storage *storage;
        struct mail_index_view *flags_view;
 
-       const char *path;
        struct timeout *keep_lock_to;
 
        /* maildir sync: */
@@ -122,7 +121,7 @@ int maildir_file_do(struct maildir_mailbox *mbox, uint32_t uid,
        maildir_file_do(mbox, seq, (maildir_file_do_func *)callback, context)
 #endif
 
-bool maildir_set_deleted(struct maildir_mailbox *mbox);
+bool maildir_set_deleted(struct mailbox *box);
 uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list);
 
 void maildir_transaction_class_init(void);
index cb671eb015286b3a75e380f0c15d3c422e270070..b0834db66e676d1ac96184c7d1a583b3f6e545a4 100644 (file)
@@ -160,7 +160,8 @@ static int maildir_handle_uid_insertion(struct maildir_index_sync_context *ctx,
        maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);
 
        i_warning("Maildir %s: Expunged message reappeared, giving a new UID "
-                 "(old uid=%u, file=%s)", ctx->mbox->path, uid, filename);
+                 "(old uid=%u, file=%s)", ctx->mbox->ibox.box.path,
+                 uid, filename);
        return 0;
 }
 
@@ -402,7 +403,7 @@ int maildir_sync_index(struct maildir_index_sync_context *ctx,
                   first time, reset the index so we can add all messages as
                   new */
                i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)",
-                         mbox->path, hdr->uid_validity, uid_validity);
+                         mbox->ibox.box.path, hdr->uid_validity, uid_validity);
                mail_index_reset(trans);
                index_mailbox_reset_uidvalidity(&mbox->ibox);
                maildir_uidlist_set_next_uid(mbox->uidlist, 1, TRUE);
@@ -564,7 +565,7 @@ int maildir_sync_index(struct maildir_index_sync_context *ctx,
        if (mbox->ibox.box.v.sync_notify != NULL)
                mbox->ibox.box.v.sync_notify(&mbox->ibox.box, 0, 0);
 
-       if (stat(t_strconcat(mbox->path, "/cur", NULL), &st) == 0) {
+       if (stat(t_strconcat(mbox->ibox.box.path, "/cur", NULL), &st) == 0) {
                mbox->maildir_hdr.new_check_time =
                        I_MAX(st.st_mtime, time_before_sync);
                mbox->maildir_hdr.cur_mtime = st.st_mtime;
index 6eca491d481672f6d5feceee83f7810f9248bf7c..2b61b912dc1604cfcdb6042bdce59c390a7b86d6 100644 (file)
@@ -255,8 +255,8 @@ maildir_sync_context_new(struct maildir_mailbox *mbox,
 
        ctx = t_new(struct maildir_sync_context, 1);
        ctx->mbox = mbox;
-       ctx->new_dir = t_strconcat(mbox->path, "/new", NULL);
-       ctx->cur_dir = t_strconcat(mbox->path, "/cur", NULL);
+       ctx->new_dir = t_strconcat(mbox->ibox.box.path, "/new", NULL);
+       ctx->cur_dir = t_strconcat(mbox->ibox.box.path, "/cur", NULL);
        ctx->last_touch = ioloop_time;
        ctx->last_notify = ioloop_time;
        ctx->flags = flags;
@@ -321,7 +321,8 @@ static int maildir_fix_duplicate(struct maildir_sync_context *ctx,
        }
 
        new_fname = maildir_filename_generate();
-       new_path = t_strconcat(ctx->mbox->path, "/new/", new_fname, NULL);
+       new_path = t_strconcat(ctx->mbox->ibox.box.path, "/new/",
+                              new_fname, NULL);
 
        if (rename(path2, new_path) == 0)
                i_warning("Fixed a duplicate: %s -> %s", path2, new_fname);
@@ -337,6 +338,7 @@ static int maildir_fix_duplicate(struct maildir_sync_context *ctx,
 static int
 maildir_stat(struct maildir_mailbox *mbox, const char *path, struct stat *st_r)
 {
+       struct mailbox *box = &mbox->ibox.box;
        int i;
 
        for (i = 0;; i++) {
@@ -345,13 +347,12 @@ maildir_stat(struct maildir_mailbox *mbox, const char *path, struct stat *st_r)
                if (errno != ENOENT || i == MAILDIR_DELETE_RETRY_COUNT)
                        break;
 
-               if (!maildir_set_deleted(mbox))
+               if (!maildir_set_deleted(box))
                        return -1;
                /* try again */
        }
 
-       mail_storage_set_critical(mbox->ibox.box.storage,
-                                 "stat(%s) failed: %m", path);
+       mail_storage_set_critical(box->storage, "stat(%s) failed: %m", path);
        return -1;
 }
 
@@ -386,7 +387,7 @@ static int maildir_scan_dir(struct maildir_sync_context *ctx, bool new_dir)
                        return -1;
                }
 
-               if (!maildir_set_deleted(ctx->mbox))
+               if (!maildir_set_deleted(&ctx->mbox->ibox.box))
                        return -1;
                /* try again */
        }
@@ -909,8 +910,10 @@ maildir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        bool lost_files, force_resync;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       return index_mailbox_sync_init(box, flags, TRUE);
+       }
 
        force_resync = (flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0;
        if (index_mailbox_want_full_sync(&mbox->ibox, flags)) {
@@ -967,8 +970,8 @@ int maildir_sync_is_synced(struct maildir_mailbox *mbox)
        T_BEGIN {
                const char *new_dir, *cur_dir;
 
-               new_dir = t_strconcat(mbox->path, "/new", NULL);
-               cur_dir = t_strconcat(mbox->path, "/cur", NULL);
+               new_dir = t_strconcat(mbox->ibox.box.path, "/new", NULL);
+               cur_dir = t_strconcat(mbox->ibox.box.path, "/cur", NULL);
 
                ret = maildir_sync_quick_check(mbox, FALSE, new_dir, cur_dir,
                                               &new_changed, &cur_changed);
index b70b847600e709dbcfe3eca5c2f471e7e42a87cf..6085ab5172ed8e20b447ee7ce4ee3e0e1c6a86ae 100644 (file)
@@ -174,7 +174,7 @@ static int maildir_uidlist_lock_timeout(struct maildir_uidlist *uidlist,
                }
                /* the control dir doesn't exist. create it unless the whole
                   mailbox was just deleted. */
-               if (!maildir_set_deleted(uidlist->mbox))
+               if (!maildir_set_deleted(&uidlist->mbox->ibox.box))
                        return -1;
        }
 
@@ -1221,7 +1221,7 @@ static int maildir_uidlist_recreate(struct maildir_uidlist *uidlist)
                }
                /* the control dir doesn't exist. create it unless the whole
                   mailbox was just deleted. */
-               if (!maildir_set_deleted(uidlist->mbox))
+               if (!maildir_set_deleted(&uidlist->mbox->ibox.box))
                        return -1;
        }
 
index 026d5d05e536c0dd305a2d8b451ac032ac8d76cf..f0b19e32a0977e5c6612ce86f62fd1d502f877a2 100644 (file)
@@ -74,13 +74,13 @@ static int maildir_file_do_try(struct maildir_mailbox *mbox, uint32_t uid,
 
        if ((flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0) {
                /* probably in new/ dir */
-               path = t_strconcat(mbox->path, "/new/", fname, NULL);
+               path = t_strconcat(mbox->ibox.box.path, "/new/", fname, NULL);
                ret = callback(mbox, path, context);
                if (ret != 0)
                        return ret;
        }
 
-       path = t_strconcat(mbox->path, "/cur/", fname, NULL);
+       path = t_strconcat(mbox->ibox.box.path, "/cur/", fname, NULL);
        ret = callback(mbox, path, context);
        return ret;
 }
@@ -169,11 +169,10 @@ static int maildir_create_path(struct mailbox *box, const char *path,
        }
 }
 
-static int maildir_create_subdirs(struct maildir_mailbox *mbox)
+static int maildir_create_subdirs(struct mailbox *box)
 {
        static const char *subdirs[] = { "cur", "new", "tmp" };
        const char *dirs[N_ELEMENTS(subdirs) + 2];
-       struct mailbox *box = &mbox->ibox.box;
        struct stat st;
        const char *path;
        unsigned int i;
@@ -181,7 +180,7 @@ static int maildir_create_subdirs(struct maildir_mailbox *mbox)
 
        /* @UNSAFE: get a list of directories we want to create */
        for (i = 0; i < N_ELEMENTS(subdirs); i++)
-               dirs[i] = t_strconcat(mbox->path, "/", subdirs[i], NULL);
+               dirs[i] = t_strconcat(box->path, "/", subdirs[i], NULL);
        dirs[i++] = mailbox_list_get_path(box->list, box->name,
                                          MAILBOX_LIST_PATH_TYPE_CONTROL);
        dirs[i++] = mailbox_list_get_path(box->list, box->name,
@@ -204,25 +203,24 @@ static int maildir_create_subdirs(struct maildir_mailbox *mbox)
        return i == N_ELEMENTS(dirs) ? 0 : -1;
 }
 
-bool maildir_set_deleted(struct maildir_mailbox *mbox)
+bool maildir_set_deleted(struct mailbox *box)
 {
-       struct mailbox *box = &mbox->ibox.box;
        struct stat st;
        int ret;
 
-       if (stat(mbox->path, &st) < 0) {
+       if (stat(box->path, &st) < 0) {
                if (errno == ENOENT)
                        mailbox_set_deleted(box);
                else {
                        mail_storage_set_critical(box->storage,
-                               "stat(%s) failed: %m", mbox->path);
+                               "stat(%s) failed: %m", box->path);
                }
                return FALSE;
        }
        /* maildir itself exists. create all of its subdirectories in case
           they got lost. */
        T_BEGIN {
-               ret = maildir_create_subdirs(mbox);
+               ret = maildir_create_subdirs(box);
        } T_END;
        return ret < 0 ? FALSE : TRUE;
 }
index ff4361df290f9ff9ab45c0752f5988d58e695ffb..46c5b3e97b5777a5da9d9c1d56fc8974594cf69f 100644 (file)
@@ -23,10 +23,11 @@ int mbox_file_open(struct mbox_mailbox *mbox)
                return 0;
        }
 
-       fd = open(mbox->path, mbox->ibox.backend_readonly ? O_RDONLY : O_RDWR);
+       fd = open(mbox->ibox.box.path,
+                 mbox->ibox.backend_readonly ? O_RDONLY : O_RDWR);
        if (fd == -1 && errno == EACCES && !mbox->ibox.backend_readonly) {
                 mbox->ibox.backend_readonly = TRUE;
-               fd = open(mbox->path, O_RDONLY);
+               fd = open(mbox->ibox.box.path, O_RDONLY);
        }
 
        if (fd == -1) {
@@ -83,7 +84,7 @@ int mbox_file_open_stream(struct mbox_mailbox *mbox)
        }
 
        mbox->mbox_stream = i_stream_create_raw_mbox(mbox->mbox_file_stream,
-                                                    mbox->path);
+                                                    mbox->ibox.box.path);
        if (mbox->mbox_lock_type != F_UNLCK)
                istream_raw_mbox_set_locked(mbox->mbox_stream);
        return 0;
@@ -106,7 +107,7 @@ static void mbox_file_fix_atime(struct mbox_mailbox *mbox)
                if (st.st_atime >= st.st_mtime) {
                        buf.modtime = st.st_mtime;
                        buf.actime = buf.modtime - 1;
-                       if (utime(mbox->path, &buf) < 0) {
+                       if (utime(mbox->ibox.box.path, &buf) < 0) {
                                mbox_set_syscall_error(mbox, "utimes()");
                                return;
                        }
@@ -146,7 +147,7 @@ int mbox_file_lookup_offset(struct mbox_mailbox *mbox,
        if (data == NULL) {
                mail_storage_set_critical(&mbox->storage->storage,
                        "Cached message offset lost for seq %u in mbox file %s",
-                       seq, mbox->path);
+                       seq, mbox->ibox.box.path);
                 mbox->mbox_hdr.dirty_flag = TRUE;
                 mbox->mbox_broken_offsets = TRUE;
                return 0;
@@ -183,7 +184,7 @@ int mbox_file_seek(struct mbox_mailbox *mbox, struct mail_index_view *view,
 
                mail_storage_set_critical(&mbox->storage->storage,
                        "Cached message offset %s is invalid for mbox file %s",
-                       dec2str(offset), mbox->path);
+                       dec2str(offset), mbox->ibox.box.path);
                mbox->mbox_hdr.dirty_flag = TRUE;
                mbox->mbox_broken_offsets = TRUE;
                return 0;
index ce4a287aaa9454340ac7d1202a683b0d620603e1..72a9b70113d60b330a981ac813656d3e36257f65 100644 (file)
@@ -174,7 +174,7 @@ static int mbox_file_open_latest(struct mbox_lock_context *ctx, int lock_type)
                   be sure that the file is latest, but mbox files get rarely
                   deleted and the flushing might cause errors (e.g. EBUSY for
                   trying to flush a /var/mail mountpoint) */
-               if (nfs_safe_stat(mbox->path, &st) < 0) {
+               if (nfs_safe_stat(mbox->ibox.box.path, &st) < 0) {
                        if (errno == ENOENT)
                                mailbox_set_deleted(&mbox->ibox.box);
                        else
@@ -268,12 +268,12 @@ static int mbox_dotlock_privileged_op(struct mbox_mailbox *mbox,
              privileged group
            - DoS other users by dotlocking their mailboxes infinitely
        */
-       fname = strrchr(mbox->path, '/');
+       fname = strrchr(mbox->ibox.box.path, '/');
        if (fname == NULL) {
                /* already relative */
-               fname = mbox->path;
+               fname = mbox->ibox.box.path;
        } else {
-               dir = t_strdup_until(mbox->path, fname);
+               dir = t_strdup_until(mbox->ibox.box.path, fname);
                if (chdir(dir) < 0) {
                        mail_storage_set_critical(&mbox->storage->storage,
                                "chdir(%s) failed: %m", dir);
@@ -285,7 +285,7 @@ static int mbox_dotlock_privileged_op(struct mbox_mailbox *mbox,
        if (op == MBOX_DOTLOCK_OP_LOCK) {
                if (access(fname, R_OK) < 0) {
                        mail_storage_set_critical(&mbox->storage->storage,
-                               "access(%s) failed: %m", mbox->path);
+                               "access(%s) failed: %m", mbox->ibox.box.path);
                        return -1;
                }
        }
@@ -410,7 +410,8 @@ mbox_lock_dotlock_int(struct mbox_lock_context *ctx, int lock_type, bool try)
        set.callback = dotlock_callback;
        set.context = ctx;
 
-       ret = file_dotlock_create(&set, mbox->path, 0, &mbox->mbox_dotlock);
+       ret = file_dotlock_create(&set, mbox->ibox.box.path, 0,
+                                 &mbox->mbox_dotlock);
        if (ret >= 0) {
                /* success / timeout */
        } else if (errno == EACCES && restrict_access_have_priv_gid() &&
@@ -419,7 +420,7 @@ mbox_lock_dotlock_int(struct mbox_lock_context *ctx, int lock_type, bool try)
                ret = mbox_dotlock_privileged_op(mbox, &set,
                                                 MBOX_DOTLOCK_OP_LOCK);
        } else if (errno == EACCES)
-               mbox_dotlock_log_eacces_error(mbox, mbox->path);
+               mbox_dotlock_log_eacces_error(mbox, mbox->ibox.box.path);
        else
                mbox_set_syscall_error(mbox, "file_dotlock_create()");
 
@@ -631,7 +632,7 @@ static int mbox_lock_fcntl(struct mbox_lock_context *ctx, int lock_type,
                        mail_storage_set_critical(&ctx->mbox->storage->storage,
                                "fcntl() failed with mbox file %s: "
                                "File is locked by another process (EACCES)",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                        return -1;
                }
 
@@ -766,6 +767,8 @@ static int mbox_update_locking(struct mbox_mailbox *mbox, int lock_type,
 int mbox_lock(struct mbox_mailbox *mbox, int lock_type,
              unsigned int *lock_id_r)
 {
+       const char *path = mbox->ibox.box.path;
+       int mbox_fd = mbox->mbox_fd;
        bool fcntl_locked;
        int ret;
 
@@ -783,14 +786,11 @@ int mbox_lock(struct mbox_mailbox *mbox, int lock_type,
 
                if (mbox->storage->storage.set->mail_nfs_storage) {
                        if (fcntl_locked) {
-                               nfs_flush_attr_cache_fd_locked(mbox->path,
-                                                              mbox->mbox_fd);
-                               nfs_flush_read_cache_locked(mbox->path,
-                                                           mbox->mbox_fd);
+                               nfs_flush_attr_cache_fd_locked(path, mbox_fd);
+                               nfs_flush_read_cache_locked(path, mbox_fd);
                        } else {
-                               nfs_flush_attr_cache_unlocked(mbox->path);
-                               nfs_flush_read_cache_unlocked(mbox->path,
-                                                             mbox->mbox_fd);
+                               nfs_flush_attr_cache_unlocked(path);
+                               nfs_flush_read_cache_unlocked(path, mbox_fd);
                        }
                }
 
index 41b8112294465e32e4ead9ab759692149025249f..35fbb2c8759ecd92523554ddb6d7cd4a4a287e65 100644 (file)
@@ -100,7 +100,7 @@ static int mbox_mail_seek(struct index_mail *mail)
        if (ret == 0) {
                mail_storage_set_critical(&mbox->storage->storage,
                        "Losing sync for mail uid=%u in mbox file %s",
-                       mail->mail.mail.uid, mbox->path);
+                       mail->mail.mail.uid, mbox->ibox.box.path);
        }
        return 0;
 }
@@ -284,7 +284,7 @@ static int mbox_mail_init_stream(struct index_mail *mail)
                if (ret < 0) {
                        i_warning("mbox %s: Can't find next message offset "
                                  "for uid=%u",
-                                 mbox->path, mail->mail.mail.uid);
+                                 mbox->ibox.box.path, mail->mail.mail.uid);
                }
        }
        if (ret <= 0)
index 9b9c90ca4c43f8519dea4de248b3a000a6c6257d..17442b29bb6b92861a220b8179ae5180d6300cbb 100644 (file)
@@ -734,7 +734,7 @@ int mbox_transaction_save_commit(struct mbox_save_context *ctx)
 
                buf.modtime = st.st_mtime;
                buf.actime = ctx->orig_atime;
-               if (utime(mbox->path, &buf) < 0)
+               if (utime(mbox->ibox.box.path, &buf) < 0)
                        mbox_set_syscall_error(mbox, "utime()");
        }
 
index af7a37e7ee9bd3394bdda59e11a666722c201cee..3e5a0b741e419bd1af3bfaffa160230c8825a308 100644 (file)
@@ -83,7 +83,7 @@ int mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function)
        } else {
                mail_storage_set_critical(&mbox->storage->storage,
                                          "%s failed with mbox file %s: %m",
-                                         function, mbox->path);
+                                         function, mbox->ibox.box.path);
        }
        return -1;
 }
@@ -313,6 +313,57 @@ static bool mbox_storage_autodetect(const struct mail_namespace *ns,
        return TRUE;
 }
 
+static bool want_memory_indexes(struct mbox_storage *storage, const char *path)
+{
+       struct stat st;
+
+       if (storage->set->mbox_min_index_size == 0)
+               return FALSE;
+
+       if (stat(path, &st) < 0) {
+               if (errno == ENOENT)
+                       st.st_size = 0;
+               else {
+                       mail_storage_set_critical(&storage->storage,
+                                                 "stat(%s) failed: %m", path);
+                       return FALSE;
+               }
+       }
+       return st.st_size / 1024 < storage->set->mbox_min_index_size;
+}
+
+static struct mailbox *
+mbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input,
+                  enum mailbox_flags flags)
+{
+       struct mbox_mailbox *mbox;
+       pool_t pool;
+
+       pool = pool_alloconly_create("mbox mailbox", 1024+512);
+       mbox = p_new(pool, struct mbox_mailbox, 1);
+       mbox->ibox.box = mbox_mailbox;
+       mbox->ibox.box.pool = pool;
+       mbox->ibox.box.storage = storage;
+       mbox->ibox.box.list = list;
+       mbox->ibox.mail_vfuncs = &mbox_mail_vfuncs;
+
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
+                                   MBOX_INDEX_PREFIX);
+
+       mbox->storage = (struct mbox_storage *)storage;
+       mbox->mbox_fd = -1;
+       mbox->mbox_lock_type = F_UNLCK;
+       mbox->mbox_ext_idx =
+               mail_index_ext_register(mbox->ibox.index, "mbox",
+                                       sizeof(mbox->mbox_hdr),
+                                       sizeof(uint64_t), sizeof(uint64_t));
+
+       if ((storage->flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0)
+               mbox->mbox_save_md5 = TRUE;
+       return &mbox->ibox.box;
+}
+
 static int verify_inbox(struct mailbox_list *list)
 {
        const char *inbox_path, *rootdir;
@@ -353,101 +404,37 @@ static int verify_inbox(struct mailbox_list *list)
        return 0;
 }
 
-static bool want_memory_indexes(struct mbox_storage *storage, const char *path)
-{
-       struct stat st;
-
-       if (storage->set->mbox_min_index_size == 0)
-               return FALSE;
-
-       if (stat(path, &st) < 0) {
-               if (errno == ENOENT)
-                       st.st_size = 0;
-               else {
-                       mail_storage_set_critical(&storage->storage,
-                                                 "stat(%s) failed: %m", path);
-                       return FALSE;
-               }
-       }
-       return st.st_size / 1024 < storage->set->mbox_min_index_size;
-}
-
 static void mbox_lock_touch_timeout(struct mbox_mailbox *mbox)
 {
        mbox_dotlock_touch(mbox);
 }
 
-static struct mbox_mailbox *
-mbox_alloc_mailbox(struct mbox_storage *storage, struct mail_index *index,
-                  const char *name, const char *path,
-                  enum mailbox_open_flags flags)
+static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
 {
-       struct mbox_mailbox *mbox;
-       pool_t pool;
+       struct mailbox *box = &mbox->ibox.box;
+       const char *rootdir;
 
-       pool = pool_alloconly_create("mbox mailbox", 1024+512);
-       mbox = p_new(pool, struct mbox_mailbox, 1);
-       mbox->ibox.box = mbox_mailbox;
-       mbox->ibox.box.pool = pool;
-       mbox->ibox.box.storage = &storage->storage;
-       mbox->ibox.mail_vfuncs = &mbox_mail_vfuncs;
-       mbox->ibox.index = index;
-
-       mbox->storage = storage;
-       mbox->path = p_strdup(mbox->ibox.box.pool, path);
-       mbox->mbox_fd = -1;
-       mbox->mbox_lock_type = F_UNLCK;
-       mbox->mbox_ext_idx =
-               mail_index_ext_register(index, "mbox",
-                                       sizeof(mbox->mbox_hdr),
-                                       sizeof(uint64_t), sizeof(uint64_t));
-
-       if ((storage->storage.flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0)
-               mbox->mbox_save_md5 = TRUE;
-
-       index_storage_mailbox_init(&mbox->ibox, name, flags,
-                                  want_memory_indexes(storage, path));
-       return mbox;
-}
-
-static struct mailbox *
-mbox_open(struct mbox_storage *storage, struct mailbox_list *list,
-         const char *name, enum mailbox_open_flags flags)
-{
-       struct mbox_mailbox *mbox;
-       struct mail_index *index;
-       const char *path, *rootdir;
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-
-       index = index_storage_alloc(list, name, flags, MBOX_INDEX_PREFIX);
-       mbox = mbox_alloc_mailbox(storage, index, name, path, flags);
-
-       if (access(path, R_OK|W_OK) < 0) {
-               if (errno < EACCES)
+       if (access(box->path, R_OK|W_OK) < 0) {
+               if (errno != EACCES) {
                        mbox_set_syscall_error(mbox, "access()");
-               else
-                       mbox->ibox.backend_readonly = TRUE;
+                       return -1;
+               }
+               mbox->ibox.backend_readonly = TRUE;
        }
+       mbox->ibox.move_to_memory =
+               want_memory_indexes(mbox->storage, box->path);
 
-       if (strcmp(name, "INBOX") == 0) {
+       if (strcmp(box->name, "INBOX") == 0) {
                /* if INBOX isn't under the root directory, it's probably in
                   /var/mail and we want to allow privileged dotlocking */
-               rootdir = mailbox_list_get_path(list, NULL,
+               rootdir = mailbox_list_get_path(box->list, NULL,
                                                MAILBOX_LIST_PATH_TYPE_DIR);
-               if (strncmp(path, rootdir, strlen(rootdir)) != 0)
+               if (strncmp(box->path, rootdir, strlen(rootdir)) != 0)
                        mbox->mbox_privileged_locking = TRUE;
        }
-       if ((flags & MAILBOX_OPEN_KEEP_LOCKED) != 0) {
-               if (mbox_lock(mbox, F_WRLCK, &mbox->mbox_global_lock_id) <= 0) {
-                       struct mailbox *box = &mbox->ibox.box;
-
-                       mailbox_close(&box);
-                       mailbox_list_set_error_from_storage(list,
-                                                           &storage->storage);
-                       return NULL;
-               }
+       if ((box->flags & MAILBOX_FLAG_KEEP_LOCKED) != 0) {
+               if (mbox_lock(mbox, F_WRLCK, &mbox->mbox_global_lock_id) <= 0)
+                       return -1;
 
                if (mbox->mbox_dotlock != NULL) {
                        mbox->keep_lock_to =
@@ -455,77 +442,48 @@ mbox_open(struct mbox_storage *storage, struct mailbox_list *list,
                                            mbox_lock_touch_timeout, mbox);
                }
        }
-       return &mbox->ibox.box;
-}
-
-static struct mailbox *
-mbox_mailbox_open_stream(struct mbox_storage *storage,
-                        struct mailbox_list *list, const char *name,
-                        struct istream *input, enum mailbox_open_flags flags)
-{
-       struct mail_index *index;
-       struct mbox_mailbox *mbox;
-       const char *path;
-
-       flags |= MAILBOX_OPEN_READONLY;
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       index = index_storage_alloc(list, name, flags, MBOX_INDEX_PREFIX);
-       mbox = mbox_alloc_mailbox(storage, index, name, path, flags);
-
-       i_stream_ref(input);
-       mbox->mbox_file_stream = input;
-       mbox->ibox.backend_readonly = TRUE;
-       mbox->no_mbox_file = TRUE;
-
-       mbox->path = "(read-only mbox stream)";
-       return &mbox->ibox.box;
+       return index_storage_mailbox_open(box);
 }
 
-static struct mailbox *
-mbox_mailbox_open(struct mail_storage *_storage, struct mailbox_list *list,
-                 const char *name, struct istream *input,
-                 enum mailbox_open_flags flags)
+static int mbox_mailbox_open(struct mailbox *box)
 {
-       struct mbox_storage *storage = (struct mbox_storage *)_storage;
-       const char *path;
+       struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
        struct stat st;
+       int ret;
 
-       if (input != NULL) {
-               return mbox_mailbox_open_stream(storage, list, name,
-                                               input, flags);
+       if (box->input != NULL) {
+               mbox->mbox_file_stream = box->input;
+               mbox->ibox.backend_readonly = TRUE;
+               mbox->no_mbox_file = TRUE;
+               return 0;
        }
 
-       if (strcmp(name, "INBOX") == 0 &&
-           (list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
+       if (strcmp(box->name, "INBOX") == 0 &&
+           (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
                /* make sure INBOX exists */
-               if (verify_inbox(list) < 0)
-                       return NULL;
-               return mbox_open(storage, list, "INBOX", flags);
-       }
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (stat(path, &st) == 0) {
-               if (S_ISDIR(st.st_mode)) {
-                       mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
-                               t_strdup_printf("Mailbox isn't selectable: %s",
-                                               name));
-                       return NULL;
-               }
-
-               return mbox_open(storage, list, name, flags);
+               if (verify_inbox(box->list) < 0)
+                       return -1;
+               return mbox_mailbox_open_existing(mbox);
        }
 
-       if (ENOTFOUND(errno)) {
-               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, "stat(%s) failed: %m", path);
+       if ((ret = stat(box->path, &st)) == 0 && !S_ISDIR(st.st_mode))
+               return mbox_mailbox_open_existing(mbox);
+       else if (ret == 0) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
+                       t_strdup_printf("Mailbox isn't selectable: %s",
+                                       box->name));
+               return -1;
+       } else if (ENOTFOUND(errno)) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                       T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               return -1;
+       } else if (mail_storage_set_error_from_errno(box->storage)) {
+               return -1;
+       } else {
+               mail_storage_set_critical(box->storage,
+                                         "stat(%s) failed: %m", box->path);
+               return -1;
        }
-
-       return NULL;
 }
 
 static int
@@ -596,12 +554,11 @@ mbox_mailbox_create(struct mail_storage *_storage, struct mailbox_list *list,
        return -1;
 }
 
-static int mbox_storage_mailbox_close(struct mailbox *box)
+static void mbox_mailbox_close(struct mailbox *box)
 {
        struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
        const struct mail_index_header *hdr;
        enum mbox_sync_flags sync_flags = 0;
-       int ret = 0;
 
        if (mbox->mbox_stream != NULL &&
            istream_raw_mbox_is_corrupted(mbox->mbox_stream)) {
@@ -618,10 +575,8 @@ static int mbox_storage_mailbox_close(struct mailbox *box)
                        sync_flags |= MBOX_SYNC_REWRITE;
                }
        }
-       if (sync_flags != 0 && !mbox->invalid_mbox_file) {
-               if (mbox_sync(mbox, sync_flags) < 0)
-                       ret = -1;
-       }
+       if (sync_flags != 0 && !mbox->invalid_mbox_file)
+               (void)mbox_sync(mbox, sync_flags);
 
        if (mbox->mbox_global_lock_id != 0)
                (void)mbox_unlock(mbox, mbox->mbox_global_lock_id);
@@ -632,7 +587,7 @@ static int mbox_storage_mailbox_close(struct mailbox *box)
        if (mbox->mbox_file_stream != NULL)
                i_stream_destroy(&mbox->mbox_file_stream);
 
-       return index_storage_mailbox_close(box) < 0 ? -1 : ret;
+       index_storage_mailbox_close(box);
 }
 
 static void mbox_notify_changes(struct mailbox *box)
@@ -642,7 +597,7 @@ static void mbox_notify_changes(struct mailbox *box)
        if (box->notify_callback == NULL)
                index_mailbox_check_remove_all(&mbox->ibox);
        else if (!mbox->no_mbox_file)
-               index_mailbox_check_add(&mbox->ibox, mbox->path);
+               index_mailbox_check_add(&mbox->ibox, mbox->ibox.box.path);
 }
 
 static bool
@@ -873,7 +828,7 @@ struct mail_storage mbox_storage = {
                mbox_storage_add_list,
                mbox_storage_get_list_settings,
                mbox_storage_autodetect,
-               mbox_mailbox_open,
+               mbox_mailbox_alloc,
                mbox_mailbox_create,
                NULL
        }
@@ -888,7 +843,8 @@ struct mailbox mbox_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               mbox_storage_mailbox_close,
+               mbox_mailbox_open,
+               mbox_mailbox_close,
                index_storage_get_status,
                NULL,
                NULL,
index ca99a4342bc5432844271b1cb76c48ab82e2f170..fd6cb1ab625750867a5a9518ccd199a615b06ab5 100644 (file)
@@ -34,8 +34,6 @@ struct mbox_mailbox {
        struct index_mailbox ibox;
        struct mbox_storage *storage;
 
-       const char *path;
-
        int mbox_fd;
        struct istream *mbox_stream, *mbox_file_stream;
        int mbox_lock_type;
index 8e5d7f55725559161f2b1d9a9affdd471c649466..b53bac74d8d7d4613c7954c40ca2c16bca5bed34 100644 (file)
@@ -44,8 +44,8 @@ int mbox_move(struct mbox_sync_context *sync_ctx,
        else if (ret >= 0) {
                mbox_sync_set_critical(sync_ctx,
                        "mbox_move(%"PRIuUOFF_T", %"PRIuUOFF_T", %"PRIuUOFF_T
-                       ") moved only %"PRIuUOFF_T" bytes in mbox file %s",
-                       dest, source, size, (uoff_t)ret, sync_ctx->mbox->path);
+                       ") moved only %"PRIuUOFF_T" bytes",
+                       dest, source, size, (uoff_t)ret);
                ret = -1;
        } else if (ret < 0) {
                errno = output->stream_errno;
@@ -416,11 +416,10 @@ static int mbox_sync_read_and_move(struct mbox_sync_context *sync_ctx,
                        mbox_sync_file_update_ext_modified(sync_ctx);
 
                        mbox_sync_set_critical(sync_ctx,
-                               "mbox %s: seq=%u uid=%u uid_broken=%d "
+                               "seq=%u uid=%u uid_broken=%d "
                                "originally needed %"PRIuUOFF_T
                                " bytes, now needs %"PRIuSIZE_T" bytes",
-                               sync_ctx->mbox->path, seq, mails[idx].uid,
-                               mails[idx].uid_broken,
+                               seq, mails[idx].uid, mails[idx].uid_broken,
                                (uoff_t)-mails[idx].space, need_space);
                }
        }
index 9478ee00d9be4e89a4b262ceeee95084d6175093..64dc6d3c942e2c7931a43fb60ad00b709baf6264 100644 (file)
@@ -72,12 +72,15 @@ void mbox_sync_set_critical(struct mbox_sync_context *sync_ctx,
        if (sync_ctx->ext_modified) {
                mail_storage_set_critical(&sync_ctx->mbox->storage->storage,
                        "mbox file %s was modified while we were syncing, "
-                       "check your locking settings", sync_ctx->mbox->path);
+                       "check your locking settings",
+                       sync_ctx->mbox->ibox.box.path);
        }
 
        va_start(va, fmt);
        mail_storage_set_critical(&sync_ctx->mbox->storage->storage,
-                                 "%s", t_strdup_vprintf(fmt, va));
+                                 "Sync failed for mbox file %s: %s",
+                                 sync_ctx->mbox->ibox.box.path,
+                                 t_strdup_vprintf(fmt, va));
        va_end(va);
 }
 
@@ -85,9 +88,8 @@ int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset)
 {
        if (istream_raw_mbox_seek(sync_ctx->input, from_offset) < 0) {
                mbox_sync_set_critical(sync_ctx,
-                       "Unexpectedly lost From-line at offset %"PRIuUOFF_T
-                       " from mbox file %s", from_offset,
-                       sync_ctx->mbox->path);
+                       "Unexpectedly lost From-line at offset %"PRIuUOFF_T,
+                       from_offset);
                return -1;
        }
        return 0;
@@ -208,16 +210,16 @@ mbox_sync_read_index_rec(struct mbox_sync_context *sync_ctx,
        if (rec == NULL && uid < sync_ctx->idx_next_uid) {
                /* this UID was already in index and it was expunged */
                mbox_sync_set_critical(sync_ctx,
-                       "mbox sync: Expunged message reappeared in mailbox %s "
+                       "Expunged message reappeared to mailbox "
                        "(UID %u < %u, seq=%u, idx_msgs=%u)",
-                       sync_ctx->mbox->path, uid, sync_ctx->idx_next_uid,
+                       uid, sync_ctx->idx_next_uid,
                        sync_ctx->seq, messages_count);
                ret = FALSE; rec = NULL;
        } else if (rec != NULL && rec->uid != uid) {
                /* new UID in the middle of the mailbox - shouldn't happen */
                mbox_sync_set_critical(sync_ctx,
-                       "mbox sync: UID inserted in the middle of mailbox %s "
-                       "(%u > %u, seq=%u, idx_msgs=%u)", sync_ctx->mbox->path,
+                       "UID inserted in the middle of mailbox "
+                       "(%u > %u, seq=%u, idx_msgs=%u)",
                        rec->uid, uid, sync_ctx->seq, messages_count);
                ret = FALSE; rec = NULL;
        } else {
@@ -516,8 +518,7 @@ static int mbox_rewrite_base_uid_last(struct mbox_sync_context *sync_ctx)
        }
        if (ret == 0) {
                mbox_sync_set_critical(sync_ctx,
-                       "X-IMAPbase uid-last unexpectedly points outside "
-                       "mbox file %s", sync_ctx->mbox->path);
+                       "X-IMAPbase uid-last offset unexpectedly outside mbox");
                return -1;
        }
 
@@ -531,8 +532,7 @@ static int mbox_rewrite_base_uid_last(struct mbox_sync_context *sync_ctx)
 
        if (uid_last != sync_ctx->base_uid_last) {
                mbox_sync_set_critical(sync_ctx,
-                       "X-IMAPbase uid-last unexpectedly lost in mbox file %s",
-                       sync_ctx->mbox->path);
+                       "X-IMAPbase uid-last unexpectedly lost");
                return -1;
        }
 
@@ -822,8 +822,7 @@ mbox_sync_seek_to_seq(struct mbox_sync_context *sync_ctx, uint32_t seq)
                if (ret < 0) {
                        if (deleted) {
                                mbox_sync_set_critical(sync_ctx,
-                                       "Message was expunged unexpectedly "
-                                       "in mbox file %s", mbox->path);
+                                       "Message was expunged unexpectedly");
                        }
                        return -1;
                }
@@ -832,8 +831,7 @@ mbox_sync_seek_to_seq(struct mbox_sync_context *sync_ctx, uint32_t seq)
                                                  old_offset) < 0) {
                                mbox_sync_set_critical(sync_ctx,
                                        "Error seeking back to original "
-                                       "offset %s in mbox file %s",
-                                       dec2str(old_offset), mbox->path);
+                                       "offset %s", dec2str(old_offset));
                                return -1;
                        }
                        return 0;
@@ -885,8 +883,7 @@ mbox_sync_seek_to_uid(struct mbox_sync_context *sync_ctx, uint32_t uid)
                if (istream_raw_mbox_seek(sync_ctx->mbox->mbox_stream,
                                          size) < 0) {
                        mbox_sync_set_critical(sync_ctx,
-                               "Error seeking to end of mbox file %s",
-                               sync_ctx->mbox->path);
+                               "Error seeking to end of mbox");
                        return -1;
                }
                sync_ctx->idx_seq =
@@ -968,7 +965,7 @@ static bool mbox_sync_uidvalidity_changed(struct mbox_sync_context *sync_ctx)
                i_warning("UIDVALIDITY changed (%u -> %u) in mbox file %s",
                          sync_ctx->hdr->uid_validity,
                          sync_ctx->base_uid_validity,
-                         sync_ctx->mbox->path);
+                         sync_ctx->mbox->ibox.box.path);
                sync_ctx->index_reset = TRUE;
                return TRUE;
        }
@@ -1020,8 +1017,7 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx,
                                return 0;
 
                        mbox_sync_set_critical(sync_ctx,
-                               "UIDs broken with partial sync in mbox file %s",
-                               sync_ctx->mbox->path);
+                               "UIDs broken with partial sync");
 
                        sync_ctx->mbox->mbox_hdr.dirty_flag = TRUE;
                        return 0;
@@ -1089,7 +1085,8 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx,
                                mail_storage_set_critical(
                                        &sync_ctx->mbox->storage->storage,
                                        "Out of UIDs, renumbering them in mbox "
-                                       "file %s", sync_ctx->mbox->path);
+                                       "file %s",
+                                       sync_ctx->mbox->ibox.box.path);
                                sync_ctx->renumber_uids = TRUE;
                                return 0;
                        }
@@ -1241,9 +1238,8 @@ static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx,
 
        if (file_size < sync_ctx->file_input->v_offset) {
                mbox_sync_set_critical(sync_ctx,
-                       "file size unexpectedly shrank in mbox file %s "
-                       "(%"PRIuUOFF_T" vs %"PRIuUOFF_T")",
-                       sync_ctx->mbox->path, file_size,
+                       "file size unexpectedly shrank "
+                       "(%"PRIuUOFF_T" vs %"PRIuUOFF_T")", file_size,
                        sync_ctx->file_input->v_offset);
                return -1;
        }
@@ -1382,7 +1378,7 @@ static int mbox_sync_update_index_header(struct mbox_sync_context *sync_ctx)
                   quite minimal (an extra logged error message). */
                while (sync_ctx->orig_mtime == st->st_mtime) {
                        usleep(500000);
-                       if (utime(sync_ctx->mbox->path, NULL) < 0) {
+                       if (utime(sync_ctx->mbox->ibox.box.path, NULL) < 0) {
                                mbox_set_syscall_error(sync_ctx->mbox,
                                                       "utime()");
                                return -1;
@@ -1630,7 +1626,7 @@ int mbox_sync_has_changed_full(struct mbox_mailbox *mbox, bool leave_dirty,
                        return -1;
                }
        } else {
-               if (stat(mbox->path, &statbuf) < 0) {
+               if (stat(mbox->ibox.box.path, &statbuf) < 0) {
                        if (errno == ENOENT) {
                                mailbox_set_deleted(&mbox->ibox.box);
                                return 0;
@@ -1866,7 +1862,7 @@ again:
                else {
                        buf.modtime = st.st_mtime;
                        buf.actime = sync_ctx.orig_atime;
-                       if (utime(mbox->path, &buf) < 0)
+                       if (utime(mbox->ibox.box.path, &buf) < 0)
                                mbox_set_syscall_error(mbox, "utime()");
                }
        }
@@ -1926,10 +1922,12 @@ mbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        enum mbox_sync_flags mbox_sync_flags = 0;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       ret = -1;
+       }
 
-       if (index_mailbox_want_full_sync(&mbox->ibox, flags)) {
+       if (index_mailbox_want_full_sync(&mbox->ibox, flags) && ret == 0) {
                if ((flags & MAILBOX_SYNC_FLAG_FULL_READ) != 0 &&
                    !mbox->storage->set->mbox_very_dirty_syncs)
                        mbox_sync_flags |= MBOX_SYNC_UNDIRTY;
index 2e20c60c368e4a528b3979f897385390f9fe0492..20aa3fa1c5ea640fa4c329638a08079cb7fff497 100644 (file)
@@ -19,10 +19,10 @@ static int raw_mail_stat(struct mail *mail)
                return mail_set_aborted(mail);
 
        p->stats_fstat_lookup_count++;
-       st = i_stream_stat(mbox->input, TRUE);
+       st = i_stream_stat(mail->box->input, TRUE);
        if (st == NULL) {
                mail_storage_set_critical(mail->box->storage,
-                                         "stat(%s) failed: %m", mbox->path);
+                       "stat(%s) failed: %m", mail->box->path);
                return -1;
        }
 
@@ -81,13 +81,12 @@ raw_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
                    struct message_size *body_size, struct istream **stream_r)
 {
        struct index_mail *mail = (struct index_mail *)_mail;
-       struct raw_mailbox *mbox = (struct raw_mailbox *)_mail->box;
 
        if (mail->data.stream == NULL) {
                /* we can't just reference mbox->input, because
                   index_mail_close() expects to be able to free the stream */
                mail->data.stream =
-                       i_stream_create_limit(mbox->input, (uoff_t)-1);
+                       i_stream_create_limit(_mail->box->input, (uoff_t)-1);
        }
 
        return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
@@ -104,7 +103,7 @@ raw_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
                *value_r = mbox->envelope_sender;
                return 0;
        case MAIL_FETCH_UIDL_FILE_NAME:
-               *value_r = mbox->have_filename ? mbox->path : "";
+               *value_r = mbox->have_filename ? _mail->box->path : "";
                return 0;
        default:
                return index_mail_get_special(_mail, field, value_r);
index 8f8f4d44fc69895b7ed6e4eedcd6787448eb89c5..22374432faa41b77c102dbc0b12c76186524bb80 100644 (file)
@@ -9,10 +9,6 @@
 #include "raw-sync.h"
 #include "raw-storage.h"
 
-struct raw_mailbox_list {
-       union mailbox_list_module_context module_ctx;
-};
-
 extern struct mail_storage raw_storage;
 extern struct mailbox raw_mailbox;
 
@@ -38,78 +34,59 @@ raw_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
                set->subscription_fname = RAW_SUBSCRIPTION_FILE_NAME;
 }
 
-static int
-raw_mailbox_open_input(struct mailbox_list *list, const char *name,
-                      const char *path, struct istream **input_r)
-{
-       int fd;
-
-       fd = open(path, O_RDONLY);
-       if (fd == -1) {
-               if (ENOTFOUND(errno)) {
-                       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, "open(%s) failed: %m",
-                                                 path);
-               }
-               return -1;
-       }
-       *input_r = i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE);
-       return 0;
-}
-
 static struct mailbox *
-raw_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                const char *name, struct istream *input,
-                enum mailbox_open_flags flags)
+raw_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                 const char *name, struct istream *input,
+                 enum mailbox_flags flags)
 {
        struct raw_mailbox *mbox;
-       const char *path;
        pool_t pool;
-       bool stream = input != NULL;
-
-       flags |= MAILBOX_OPEN_READONLY | MAILBOX_OPEN_NO_INDEX_FILES;
 
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (input != NULL)
-               i_stream_ref(input);
-       else {
-               if (raw_mailbox_open_input(list, name, path, &input) < 0)
-                       return NULL;
-       }
+       flags |= MAILBOX_FLAG_READONLY | MAILBOX_FLAG_NO_INDEX_FILES;
 
        pool = pool_alloconly_create("raw mailbox", 1024+512);
        mbox = p_new(pool, struct raw_mailbox, 1);
        mbox->ibox.box = raw_mailbox;
        mbox->ibox.box.pool = pool;
        mbox->ibox.box.storage = storage;
+       mbox->ibox.box.list = list;
        mbox->ibox.mail_vfuncs = &raw_mail_vfuncs;
-       mbox->ibox.index = index_storage_alloc(list, name, flags, NULL);
+
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags, NULL);
 
        mbox->storage = (struct raw_storage *)storage;
-       mbox->path = p_strdup(pool, path);
-       mbox->input = input;
 
-       if (stream)
+       if (input != NULL)
                mbox->mtime = mbox->ctime = ioloop_time;
        else {
                mbox->mtime = mbox->ctime = (time_t)-1;
                mbox->have_filename = TRUE;
        }
        mbox->size = (uoff_t)-1;
-
-       index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
        return &mbox->ibox.box;
 }
 
-static int raw_mailbox_close(struct mailbox *box)
+static int raw_mailbox_open(struct mailbox *box)
 {
-       struct raw_mailbox *mbox = (struct raw_mailbox *)box;
+       int fd;
+
+       if (box->input != NULL)
+               return index_storage_mailbox_open(box);
 
-       i_stream_unref(&mbox->input);
-       return index_storage_mailbox_close(box);
+       fd = open(box->path, O_RDONLY);
+       if (fd == -1) {
+               if (ENOTFOUND(errno)) {
+                       mail_storage_set_error(box->storage,
+                               MAIL_ERROR_NOTFOUND,
+                               T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               } else if (!mail_storage_set_error_from_errno(box->storage)) {
+                       mail_storage_set_critical(box->storage,
+                               "open(%s) failed: %m", box->path);
+               }
+               return -1;
+       }
+       box->input = i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE);
+       return index_storage_mailbox_open(box);
 }
 
 static int
@@ -207,7 +184,7 @@ struct mail_storage raw_storage = {
                raw_storage_add_list,
                raw_storage_get_list_settings,
                NULL,
-               raw_mailbox_open,
+               raw_mailbox_alloc,
                raw_mailbox_create,
                NULL
        }
@@ -222,7 +199,8 @@ struct mailbox raw_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               raw_mailbox_close,
+               raw_mailbox_open,
+               index_storage_mailbox_close,
                index_storage_get_status,
                NULL,
                NULL,
index c9267945cba184f758c4119d0a2a92d967b4b62f..9bc3443645d8217d2b703c19d962beb2729538df 100644 (file)
@@ -16,9 +16,6 @@ struct raw_mailbox {
        struct index_mailbox ibox;
        struct raw_storage *storage;
 
-       const char *path;
-       struct istream *input;
-
        time_t mtime, ctime;
        uoff_t size;
        const char *envelope_sender;
index 770f8b69e73871be18b6325af7ae9a359369b61f..f2f77e03cb815122668081f2262f23d057cefec5 100644 (file)
@@ -52,10 +52,12 @@ raw_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        struct raw_mailbox *mbox = (struct raw_mailbox *)box;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       ret = -1;
+       }
 
-       if (!mbox->synced)
+       if (!mbox->synced && ret == 0)
                ret = raw_sync(mbox);
 
        return index_mailbox_sync_init(box, flags, ret < 0);
index e13ddfb81ce5109d1e721188b7d97b063a89fa2a..ee6e8fea519d0b5e66c881e30d39ffcc004b82ac 100644 (file)
@@ -47,11 +47,11 @@ static void (*index_list_next_hook_mailbox_created)(struct mailbox *box);
 static MODULE_CONTEXT_DEFINE_INIT(index_list_storage_module,
                                  &mail_storage_module_register);
 
-static int index_list_box_close(struct mailbox *box)
+static void index_list_box_close(struct mailbox *box)
 {
        struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
 
-       return ibox->module_ctx.super.close(box);
+       ibox->module_ctx.super.close(box);
 }
 
 static int index_list_update_mail_index(struct index_mailbox_list *ilist,
@@ -352,7 +352,7 @@ static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
        return 0;
 }
 
-static void index_list_mail_mailbox_opened(struct mailbox *box)
+static void index_list_mail_mailbox_allocated(struct mailbox *box)
 {
        struct index_mailbox_list *ilist =
                INDEX_LIST_CONTEXT(box->list);
@@ -391,6 +391,6 @@ void index_mailbox_list_sync_init_list(struct mailbox_list *list)
 
 void index_mailbox_list_sync_init(void)
 {
-       index_list_next_hook_mailbox_created = hook_mailbox_opened;
-       hook_mailbox_opened = index_list_mail_mailbox_opened;
+       index_list_next_hook_mailbox_created = hook_mailbox_allocated;
+       hook_mailbox_allocated = index_list_mail_mailbox_allocated;
 }
index b74602d9471de1e759b51b659404b4a58c849f48..4ff4953bd02e8f114b275a73c1fbcfc8acc49b58 100644 (file)
@@ -12,8 +12,8 @@
 
 /* Called after mail storage has been created */
 extern void (*hook_mail_storage_created)(struct mail_storage *storage);
-/* Called after mailbox has been opened */
-extern void (*hook_mailbox_opened)(struct mailbox *box);
+/* Called after mailbox has been allocated */
+extern void (*hook_mailbox_allocated)(struct mailbox *box);
 /* Called after mailbox index has been opened */
 extern void (*hook_mailbox_index_opened)(struct mailbox *box);
 
@@ -43,11 +43,11 @@ struct mail_storage_vfuncs {
        bool (*autodetect)(const struct mail_namespace *ns,
                           struct mailbox_list_settings *set);
 
-       struct mailbox *(*mailbox_open)(struct mail_storage *storage,
-                                       struct mailbox_list *list,
-                                       const char *name,
-                                       struct istream *input,
-                                       enum mailbox_open_flags flags);
+       struct mailbox *(*mailbox_alloc)(struct mail_storage *storage,
+                                        struct mailbox_list *list,
+                                        const char *name,
+                                        struct istream *input,
+                                        enum mailbox_flags flags);
 
        int (*mailbox_create)(struct mail_storage *storage,
                              struct mailbox_list *list, const char *name,
@@ -101,7 +101,8 @@ struct mailbox_vfuncs {
        bool (*allow_new_keywords)(struct mailbox *box);
 
        int (*enable)(struct mailbox *box, enum mailbox_feature features);
-       int (*close)(struct mailbox *box);
+       int (*open)(struct mailbox *box);
+       void (*close)(struct mailbox *box);
 
        void (*get_status)(struct mailbox *box, enum mailbox_status_items items,
                           struct mailbox_status *status_r);
@@ -212,7 +213,7 @@ union mailbox_module_context {
 };
 
 struct mailbox {
-       char *name;
+       const char *name;
        struct mail_storage *storage;
        struct mailbox_list *list;
 
@@ -220,7 +221,10 @@ struct mailbox {
 /* private: */
        pool_t pool;
 
-       enum mailbox_open_flags open_flags;
+       /* mailbox's MAILBOX_LIST_PATH_TYPE_MAILBOX */
+       const char *path;
+       struct istream *input;
+       enum mailbox_flags flags;
        unsigned int transaction_count;
        enum mailbox_feature enabled_features;
 
index 3ac994181020712b2fa442ef1fa8b941a9189097..5c1588b41e9e5995c2788e974fdfc759d4cfd06f 100644 (file)
@@ -24,7 +24,7 @@ struct mail_storage_mail_index_module mail_storage_mail_index_module =
        MODULE_CONTEXT_INIT(&mail_index_module_register);
 
 void (*hook_mail_storage_created)(struct mail_storage *storage);
-void (*hook_mailbox_opened)(struct mailbox *box) = NULL;
+void (*hook_mailbox_allocated)(struct mailbox *box) = NULL;
 void (*hook_mailbox_index_opened)(struct mailbox *box) = NULL;
 
 ARRAY_TYPE(mail_storage) mail_storage_classes;
@@ -463,42 +463,49 @@ bool mail_storage_set_error_from_errno(struct mail_storage *storage)
        return TRUE;
 }
 
-struct mailbox *mailbox_open(struct mailbox_list *list, const char *name,
-                            struct istream *input,
-                            enum mailbox_open_flags flags)
+struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *name,
+                             struct istream *input,
+                             enum mailbox_flags flags)
 {
        struct mailbox_list *new_list = list;
        struct mail_storage *storage;
        struct mailbox *box;
 
-       if (mailbox_list_get_storage(&new_list, &name, &storage) < 0)
-               return NULL;
+       if (mailbox_list_get_storage(&new_list, &name, &storage) < 0) {
+               /* just use the first storage. FIXME: does this break? */
+               storage = list->ns->storage;
+       }
+
+       T_BEGIN {
+               box = storage->v.mailbox_alloc(storage, new_list,
+                                              name, input, flags);
+               if (hook_mailbox_allocated != NULL)
+                       hook_mailbox_allocated(box);
+       } T_END;
+       return box;
+}
 
-       mailbox_list_clear_error(list);
+int mailbox_open(struct mailbox *box)
+{
+       int ret;
 
-       if (!mailbox_list_is_valid_existing_name(new_list, name)) {
-               mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
+       mail_storage_clear_error(box->storage);
+
+       if (!mailbox_list_is_valid_existing_name(box->list, box->name)) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
                                       "Invalid mailbox name");
-               return NULL;
+               return -1;
        }
 
        T_BEGIN {
-               box = storage->v.mailbox_open(storage, new_list,
-                                             name, input, flags);
-               if (hook_mailbox_opened != NULL && box != NULL)
-                       hook_mailbox_opened(box);
+               ret = box->v.open(box);
        } T_END;
 
-       if (box != NULL)
-               box->list->ns->flags |= NAMESPACE_FLAG_USABLE;
-       else if (new_list != list) {
-               const char *str;
-               enum mail_error error;
+       if (ret < 0)
+               return -1;
 
-               str = mailbox_list_get_last_error(new_list, &error);
-               mailbox_list_set_error(list, error, str);
-       }
-       return box;
+       box->list->ns->flags |= NAMESPACE_FLAG_USABLE;
+       return 0;
 }
 
 int mailbox_enable(struct mailbox *box, enum mailbox_feature features)
@@ -511,7 +518,7 @@ enum mailbox_feature mailbox_get_enabled_features(struct mailbox *box)
        return box->enabled_features;
 }
 
-int mailbox_close(struct mailbox **_box)
+void mailbox_close(struct mailbox **_box)
 {
        struct mailbox *box = *_box;
 
@@ -521,7 +528,7 @@ int mailbox_close(struct mailbox **_box)
        }
 
        *_box = NULL;
-       return box->v.close(box);
+       box->v.close(box);
 }
 
 struct mail_storage *mailbox_get_storage(const struct mailbox *box)
index 190b39373e3fa585d3fa32a5404f4295d33049a0..c16532fb6874e79ed0a4a0685e405e1798c50f8d 100644 (file)
@@ -23,28 +23,25 @@ enum mail_storage_flags {
        MAIL_STORAGE_FLAG_NO_AUTOCREATE         = 0x04
 };
 
-enum mailbox_open_flags {
+enum mailbox_flags {
        /* Mailbox must not be modified even if asked */
-       MAILBOX_OPEN_READONLY           = 0x01,
+       MAILBOX_FLAG_READONLY           = 0x01,
        /* Only saving/copying mails to mailbox works. */
-       MAILBOX_OPEN_SAVEONLY           = 0x02,
-       /* Delay opening index files (and possibly other files) until mailbox
-          is being synchronized. */
-       MAILBOX_OPEN_FAST               = 0x04,
+       MAILBOX_FLAG_SAVEONLY           = 0x02,
        /* Don't reset MAIL_RECENT flags when syncing */
-       MAILBOX_OPEN_KEEP_RECENT        = 0x08,
+       MAILBOX_FLAG_KEEP_RECENT        = 0x08,
        /* Don't create index files for the mailbox */
-       MAILBOX_OPEN_NO_INDEX_FILES     = 0x10,
+       MAILBOX_FLAG_NO_INDEX_FILES     = 0x10,
        /* Keep mailbox exclusively locked all the time while it's open */
-       MAILBOX_OPEN_KEEP_LOCKED        = 0x20,
+       MAILBOX_FLAG_KEEP_LOCKED        = 0x20,
        /* Enable if mailbox is used for serving POP3. This allows making
           better caching decisions. */
-       MAILBOX_OPEN_POP3_SESSION       = 0x40,
+       MAILBOX_FLAG_POP3_SESSION       = 0x40,
        /* Enable if mailbox is used for saving a mail delivery using MDA.
           This causes ACL plugin to use POST right rather than INSERT. */
-       MAILBOX_OPEN_POST_SESSION       = 0x80,
+       MAILBOX_FLAG_POST_SESSION       = 0x80,
        /* Force opening mailbox and ignoring any ACLs */
-       MAILBOX_OPEN_IGNORE_ACLS        = 0x100
+       MAILBOX_FLAG_IGNORE_ACLS        = 0x100
 };
 
 enum mailbox_feature {
@@ -289,18 +286,20 @@ const char *mail_storage_get_last_error(struct mail_storage *storage,
 /* Returns TRUE if mailboxes are files. */
 bool mail_storage_is_mailbox_file(struct mail_storage *storage) ATTR_PURE;
 
-/* Open a mailbox. If input stream is given, mailbox is opened read-only
-   using it as a backend. If storage doesn't support stream backends and its
-   tried to be used, NULL is returned.
+/* Initialize mailbox without actually opening any files or verifying that
+   it exists. If input stream is given, mailbox is opened read-only
+   using it as a backend.
 
    Note that append and copy may open the selected mailbox again
    with possibly different readonly-state. */
-struct mailbox *mailbox_open(struct mailbox_list *list, const char *name,
-                            struct istream *input,
-                            enum mailbox_open_flags flags);
-/* Close the box. Returns -1 if some cleanup errors occurred, but
-   the mailbox was closed anyway. */
-int mailbox_close(struct mailbox **box);
+struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *name,
+                             struct istream *input,
+                             enum mailbox_flags flags);
+/* Open the mailbox. If this function isn't called explicitly, it's also called
+   internally by lib-storage when necessary. */
+int mailbox_open(struct mailbox *box);
+/* Close the box. */
+void mailbox_close(struct mailbox **box);
 
 /* Enable the given feature for the mailbox. */
 int mailbox_enable(struct mailbox *box, enum mailbox_feature features);
index 38139c9357babbf5cca1984e4fdc8ac24e896f70..3b93fff4c2049052a07c7ee3d2c12234a2cc1ba7 100644 (file)
@@ -149,7 +149,5 @@ 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);
-void mailbox_list_set_error_from_storage(struct mailbox_list *list,
-                                        struct mail_storage *storage);
 
 #endif
index 45715b670d4e1cf09fceb7b3f521e468703789bd..a252ae239b5d8e244771d79e215556d0d654c900 100644 (file)
@@ -321,6 +321,13 @@ mailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
                        i_info("Namespace %s: Permission lookup failed from %s",
                               list->ns->prefix, path);
                }
+               if (name != NULL) {
+                       /* return defaults */
+                       mailbox_list_get_permissions_full(list, NULL,
+                                                         file_mode_r,
+                                                         dir_mode_r, gid_r);
+                       return;
+               }
                /* return safe defaults */
                *file_mode_r = 0600;
                *dir_mode_r = 0700;
@@ -914,13 +921,3 @@ bool mailbox_list_set_error_from_errno(struct mailbox_list *list)
        mailbox_list_set_error(list, error, error_string);
        return TRUE;
 }
-
-void mailbox_list_set_error_from_storage(struct mailbox_list *list,
-                                        struct mail_storage *storage)
-{
-       const char *str;
-       enum mail_error error;
-
-       str = mail_storage_get_last_error(storage, &error);
-       mailbox_list_set_error(list, error, str);
-}
index 46d5fd865633b5790c62fd15efb1c2bd5e6c9c3c..1c218e55e756a12be1d61958a6d3076eb62f7803 100644 (file)
@@ -55,7 +55,7 @@ struct mail_storage test_storage = {
                NULL,
                test_storage_get_list_settings,
                NULL,
-               test_mailbox_open,
+               test_mailbox_alloc,
                test_mailbox_create,
                NULL
        }
index 4d68eabe5647538a076a41be68a24fd1dff71373..77d9d4dc1dc345aaa792b3ea79f9156dcd6dec2f 100644 (file)
@@ -4,9 +4,9 @@
 struct mail_storage *test_mail_storage_create(void);
 
 struct mailbox *
-test_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                 const char *name, struct istream *input,
-                 enum mailbox_open_flags flags);
+test_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input,
+                  enum mailbox_flags flags);
 
 struct mail *
 test_mailbox_mail_alloc(struct mailbox_transaction_context *t,
index 7b993bbb4f5d29c26446c171ec034f695f4176ea..243654c63f38686581bcdcb4aa360841fd1d2008 100644 (file)
@@ -24,11 +24,15 @@ static int test_mailbox_enable(struct mailbox *box,
        return 0;
 }
 
-static int test_mailbox_close(struct mailbox *box ATTR_UNUSED)
+static int test_mailbox_open(struct mailbox *box ATTR_UNUSED)
 {
        return 0;
 }
 
+static void test_mailbox_close(struct mailbox *box ATTR_UNUSED)
+{
+}
+
 static void test_mailbox_get_status(struct mailbox *box ATTR_UNUSED,
                                    enum mailbox_status_items items ATTR_UNUSED,
                                    struct mailbox_status *status_r)
@@ -277,6 +281,7 @@ struct mailbox test_mailbox = {
                test_mailbox_is_readonly,
                test_mailbox_allow_new_keywords,
                test_mailbox_enable,
+               test_mailbox_open,
                test_mailbox_close,
                test_mailbox_get_status,
                NULL,
@@ -318,9 +323,9 @@ struct mailbox test_mailbox = {
 };
 
 struct mailbox *
-test_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                 const char *name, struct istream *input ATTR_UNUSED,
-                 enum mailbox_open_flags flags)
+test_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input ATTR_UNUSED,
+                  enum mailbox_flags flags)
 {
        struct mailbox *box;
        pool_t pool;
@@ -333,7 +338,7 @@ test_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
        box->list = list;
 
        box->pool = pool;
-       box->open_flags = flags;
+       box->flags = flags;
 
        p_array_init(&box->search_results, pool, 16);
        p_array_init(&box->module_contexts, pool, 5);
index 656c4e83434c2261491d567f0d8d833f1d77a813..248c7fd0e67dbac2e725442ca0783555a82678e5 100644 (file)
@@ -290,18 +290,14 @@ static int client_open_raw_mail(struct client *client)
                                                  client->state.mail_data->used);
        }
        client->state.raw_box = box =
-               mailbox_open(raw_list, "Dovecot Delivery Mail", input,
-                            MAILBOX_OPEN_NO_INDEX_FILES);
+               mailbox_alloc(raw_list, "Dovecot Delivery Mail", input,
+                             MAILBOX_FLAG_NO_INDEX_FILES);
        i_stream_unref(&input);
-       if (box == NULL) {
+       if (mailbox_open(box) < 0 ||
+           mailbox_sync(box, 0, 0, NULL) < 0) {
                i_error("Can't open delivery mail as raw: %s",
-                       mailbox_list_get_last_error(raw_list, &error));
-               client_rcpt_fail_all(client);
-               return -1;
-       }
-       if (mailbox_sync(box, 0, 0, NULL) < 0) {
-               i_error("Can't sync delivery mail: %s",
-                       mailbox_list_get_last_error(raw_list, &error));
+                       mail_storage_get_last_error(box->storage, &error));
+               mailbox_close(&box);
                client_rcpt_fail_all(client);
                return -1;
        }
index 77d6084d91dabb19d40e80e9d2aa72cf41bc9e60..7971b7a8c8fca8be0db7f1a8379cdff25c1ef8da 100644 (file)
@@ -65,7 +65,7 @@ static bool acl_is_readonly(struct mailbox *box)
        if (abox->module_ctx.super.is_readonly(box))
                return TRUE;
 
-       save_right = (box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ?
+       save_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
                ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
        if (acl_mailbox_right_lookup(box, save_right) > 0)
                return FALSE;
@@ -95,12 +95,12 @@ static bool acl_allow_new_keywords(struct mailbox *box)
        return acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0;
 }
 
-static int acl_mailbox_close(struct mailbox *box)
+static void acl_mailbox_close(struct mailbox *box)
 {
        struct acl_mailbox *abox = ACL_CONTEXT(box);
 
        acl_object_deinit(&abox->aclobj);
-       return abox->module_ctx.super.close(box);
+       abox->module_ctx.super.close(box);
 }
 
 static int
@@ -262,7 +262,7 @@ acl_save_begin(struct mail_save_context *ctx, struct istream *input)
        struct acl_mailbox *abox = ACL_CONTEXT(box);
        enum acl_storage_rights save_right;
 
-       save_right = (box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ?
+       save_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
                ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
        if (acl_mailbox_right_lookup(box, save_right) <= 0)
                return -1;
@@ -279,7 +279,7 @@ acl_copy(struct mail_save_context *ctx, struct mail *mail)
        struct acl_mailbox *abox = ACL_CONTEXT(t->box);
        enum acl_storage_rights save_right;
 
-       save_right = (t->box->open_flags & MAILBOX_OPEN_POST_SESSION) != 0 ?
+       save_right = (t->box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
                ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
        if (acl_mailbox_right_lookup(t->box, save_right) <= 0)
                return -1;
@@ -336,19 +336,78 @@ acl_keywords_create(struct mailbox *box, const char *const keywords[],
                                                      keywords_r, skip_invalid);
 }
 
-struct mailbox *acl_mailbox_open_box(struct mailbox *box)
+static int acl_mailbox_open_check_acl(struct mailbox *box)
 {
+       struct acl_mailbox *abox = ACL_CONTEXT(box);
        struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
+       const unsigned int *idx_arr = alist->rights.acl_storage_right_idx;
+       enum acl_storage_rights open_right;
+       int ret;
+
+       /* mailbox can be opened either for reading or appending new messages */
+       if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0 ||
+           (box->list->ns->flags & NAMESPACE_FLAG_NOACL) != 0)
+               return 0;
+
+       if ((box->flags & MAILBOX_FLAG_SAVEONLY) != 0) {
+               open_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
+                       ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
+       } else {
+               open_right = ACL_STORAGE_RIGHT_READ;
+       }
+
+       ret = acl_object_have_right(abox->aclobj, idx_arr[open_right]);
+       if (ret > 0)
+               return 0;
+       if (ret < 0)
+               return -1;
+
+       /* no access. */
+       ret = acl_object_have_right(abox->aclobj,
+                                   idx_arr[ACL_STORAGE_RIGHT_LOOKUP]);
+       if (ret < 0)
+               return -1;
+       if (ret > 0) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
+                                      MAIL_ERRSTR_NO_PERMISSION);
+       } else {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                               T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+       }
+       return -1;
+}
+
+static int acl_mailbox_open(struct mailbox *box)
+{
+       struct acl_mailbox *abox = ACL_CONTEXT(box);
+
+       if (acl_mailbox_open_check_acl(box) < 0)
+               return -1;
+
+       return abox->module_ctx.super.open(box);
+}
+
+struct mailbox *
+acl_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                 const char *name, struct istream *input,
+                 enum mailbox_flags flags)
+{
+       union mail_storage_module_context *astorage = ACL_CONTEXT(storage);
+       struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list);
        struct acl_mailbox *abox;
+       struct mailbox *box;
+
+       box = astorage->super.mailbox_alloc(storage, list, name, input, flags);
 
        abox = p_new(box->pool, struct acl_mailbox, 1);
        abox->module_ctx.super = box->v;
        abox->aclobj = acl_object_init_from_name(alist->rights.backend,
                                                 mailbox_get_name(box));
 
-       if ((box->open_flags & MAILBOX_OPEN_IGNORE_ACLS) == 0) {
+       if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) == 0) {
                box->v.is_readonly = acl_is_readonly;
                box->v.allow_new_keywords = acl_allow_new_keywords;
+               box->v.open = acl_mailbox_open;
                box->v.close = acl_mailbox_close;
                box->v.mail_alloc = acl_mail_alloc;
                box->v.save_begin = acl_save_begin;
index 924e76b1aca5ebfb74cb8909a935fd303fcfdf16..ae5f233fe5663704a5683f3f5dc9b3c38ed3ef84 100644 (file)
@@ -46,7 +46,10 @@ void acl_mail_storage_created(struct mail_storage *storage);
 void acl_mailbox_list_created(struct mailbox_list *list);
 void acl_mail_user_created(struct mail_user *list);
 
-struct mailbox *acl_mailbox_open_box(struct mailbox *box);
+struct mailbox *
+acl_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                 const char *name, struct istream *input,
+                 enum mailbox_flags flags);
 
 struct acl_backend *acl_mailbox_list_get_backend(struct mailbox_list *list);
 int acl_mailbox_list_have_right(struct mailbox_list *list, const char *name,
index 27f097b63abe9faaaa261d4b5e431730b14e6270..741e871c6935d8db6b7d051c306774aef5e3ec78 100644 (file)
@@ -16,51 +16,6 @@ struct acl_storage_module acl_storage_module =
 struct acl_user_module acl_user_module =
        MODULE_CONTEXT_INIT(&mail_user_module_register);
 
-static struct mailbox *
-acl_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                const char *name, struct istream *input,
-                enum mailbox_open_flags flags)
-{
-       union mail_storage_module_context *astorage = ACL_CONTEXT(storage);
-       struct mailbox *box;
-       enum acl_storage_rights save_right;
-       bool can_see;
-       int ret;
-
-       /* mailbox can be opened either for reading or appending new messages */
-       if ((flags & MAILBOX_OPEN_IGNORE_ACLS) != 0 ||
-           (list->ns->flags & NAMESPACE_FLAG_NOACL) != 0) {
-               ret = 1;
-       } else if ((flags & MAILBOX_OPEN_SAVEONLY) == 0) {
-               ret = acl_mailbox_list_have_right(list, name, FALSE,
-                                                 ACL_STORAGE_RIGHT_READ,
-                                                 &can_see);
-       } else {
-               save_right = (flags & MAILBOX_OPEN_POST_SESSION) != 0 ?
-                       ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
-               ret = acl_mailbox_list_have_right(list, name, FALSE,
-                                                 save_right, &can_see);
-       }
-       if (ret <= 0) {
-               if (ret < 0)
-                       return NULL;
-               if (can_see) {
-                       mailbox_list_set_error(list, MAIL_ERROR_PERM,
-                                              MAIL_ERRSTR_NO_PERMISSION);
-               } else {
-                       mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
-                               T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
-               }
-               return NULL;
-       }
-
-       box = astorage->super.mailbox_open(storage, list, name, input, flags);
-       if (box == NULL)
-               return NULL;
-
-       return acl_mailbox_open_box(box);
-}
-
 static int
 acl_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
                   const char *name, bool directory)
@@ -103,7 +58,7 @@ void acl_mail_storage_created(struct mail_storage *storage)
                astorage = p_new(storage->pool,
                                 union mail_storage_module_context, 1);
                astorage->super = storage->v;
-               storage->v.mailbox_open = acl_mailbox_open;
+               storage->v.mailbox_alloc = acl_mailbox_alloc;
                storage->v.mailbox_create = acl_mailbox_create;
 
                MODULE_CONTEXT_SET_SELF(storage, acl_storage_module, astorage);
index 0328d54ee0e4748de6f2445c692a459bf3be4a6c..ece802a3fb52a15832a3a41fc48229bd8c38c4a8 100644 (file)
@@ -29,13 +29,6 @@ static const char *storage_error(struct mail_storage *storage)
        return mail_storage_get_last_error(storage, &error);
 }
 
-static const char *list_error(struct mailbox_list *list)
-{
-       enum mail_error error;
-
-       return mailbox_list_get_last_error(list, &error);
-}
-
 static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox,
                              struct dotlock *dotlock, const char **error_r)
 {
@@ -298,15 +291,17 @@ static int mailbox_convert_list_item(struct mail_namespace *source_ns,
 
        /* First open the source mailbox. If we can't open it, don't create
           the destination mailbox either. */
-       srcbox = mailbox_open(source_ns->list, name, NULL,
-                             MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
-       if (srcbox == NULL) {
+       srcbox = mailbox_alloc(source_ns->list, name, NULL,
+                              MAILBOX_FLAG_READONLY |
+                              MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(srcbox) < 0) {
                if (set->skip_broken_mailboxes)
                        return 0;
 
                i_error("Mailbox conversion: "
                        "Couldn't open source mailbox %s: %s",
-                       name, list_error(source_ns->list));
+                       name, storage_error(mailbox_get_storage(srcbox)));
+               mailbox_close(&srcbox);
                return -1;
        }
 
@@ -322,12 +317,13 @@ static int mailbox_convert_list_item(struct mail_namespace *source_ns,
                }
        }
 
-       destbox = mailbox_open(dest_ns->list, dest_name, NULL,
-                              MAILBOX_OPEN_KEEP_RECENT);
-       if (destbox == NULL) {
+       destbox = mailbox_alloc(dest_ns->list, dest_name, NULL,
+                               MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(destbox) < 0) {
                i_error("Mailbox conversion: Couldn't open dest mailbox %s: %s",
-                       dest_name, list_error(dest_ns->list));
+                       dest_name, storage_error(mailbox_get_storage(destbox)));
                mailbox_close(&srcbox);
+               mailbox_close(&destbox);
                return -1;
        }
 
index baa800bed7b09e4a45b16d152a8cc82248b6cce0..c4ead8f266afd3372ddc360a12ecb5f9df2d5e7b 100644 (file)
@@ -43,7 +43,7 @@ struct expire_transaction_context {
 
 const char *expire_plugin_version = PACKAGE_VERSION;
 
-static void (*next_hook_mail_storage_created)(struct mail_storage *storage);
+static void (*next_hook_mailbox_allocated)(struct mailbox *box);
 static void (*next_hook_mail_user_created)(struct mail_user *user);
 
 static MODULE_CONTEXT_DEFINE_INIT(expire_storage_module,
@@ -254,50 +254,27 @@ mailbox_expire_hook(struct mailbox *box, time_t expire_secs, bool altmove)
        MODULE_CONTEXT_SET(box, expire_storage_module, xpr_box);
 }
 
-static struct mailbox *
-expire_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                   const char *name, struct istream *input,
-                   enum mailbox_open_flags flags)
+static void expire_mailbox_allocated(struct mailbox *box)
 {
-       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(storage->user);
-       union mail_storage_module_context *xpr_storage =
-               EXPIRE_CONTEXT(storage);
-       struct mailbox *box;
+       struct expire_mail_user *euser =
+               EXPIRE_USER_CONTEXT(box->storage->user);
+       struct mail_namespace *ns = mailbox_list_get_namespace(box->list);
        string_t *vname;
        unsigned int secs;
        bool altmove;
 
-       box = xpr_storage->super.mailbox_open(storage, list, name, input, flags);
-       if (box != NULL) {
+       if (euser != NULL) {
                vname = t_str_new(128);
-               (void)mail_namespace_get_vname(mailbox_list_get_namespace(list),
-                                              vname, name);
+               (void)mail_namespace_get_vname(ns, vname, box->name);
 
                secs = expire_box_find_min_secs(euser->env, str_c(vname),
                                                &altmove);
                if (secs != 0)
                        mailbox_expire_hook(box, secs, altmove);
        }
-       return box;
-}
-
-static void expire_mail_storage_created(struct mail_storage *storage)
-{
-       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(storage->user);
-       union mail_storage_module_context *xpr_storage;
-
-       if (euser != NULL) {
-               xpr_storage = p_new(storage->pool,
-                                   union mail_storage_module_context, 1);
-               xpr_storage->super = storage->v;
-               storage->v.mailbox_open = expire_mailbox_open;
-
-               MODULE_CONTEXT_SET_SELF(storage, expire_storage_module,
-                                       xpr_storage);
-       }
 
-       if (next_hook_mail_storage_created != NULL)
-               next_hook_mail_storage_created(storage);
+       if (next_hook_mailbox_allocated != NULL)
+               next_hook_mailbox_allocated(box);
 }
 
 static void expire_mail_user_deinit(struct mail_user *user)
@@ -349,8 +326,8 @@ static void expire_mail_user_created(struct mail_user *user)
 
 void expire_plugin_init(void)
 {
-       next_hook_mail_storage_created = hook_mail_storage_created;
-       hook_mail_storage_created = expire_mail_storage_created;
+       next_hook_mailbox_allocated = hook_mailbox_allocated;
+       hook_mailbox_allocated = expire_mailbox_allocated;
 
        next_hook_mail_user_created = hook_mail_user_created;
        hook_mail_user_created = expire_mail_user_created;
@@ -358,6 +335,6 @@ void expire_plugin_init(void)
 
 void expire_plugin_deinit(void)
 {
-       hook_mail_storage_created = next_hook_mail_storage_created;
+       hook_mailbox_allocated = next_hook_mailbox_allocated;
        hook_mail_user_created = next_hook_mail_user_created;
 }
index 59692591f91d93e6e0e52e968096f316b878d595..505dbcaaf07769576fd80c94a6316a291371152d 100644 (file)
@@ -80,9 +80,11 @@ mailbox_delete_old_mails(struct expire_context *ctx, const char *user,
                return 0;
        }
 
-       box = mailbox_open(ns->list, ns_mailbox, NULL, 0);
-       if (box == NULL) {
-               errstr = mailbox_list_get_last_error(ns->list, &error);
+       box = mailbox_alloc(ns->list, ns_mailbox, NULL, 0);
+       if (mailbox_open(box) < 0) {
+               errstr = mail_storage_get_last_error(mailbox_get_storage(box),
+                                                    &error);
+               mailbox_close(&box);
                if (error != MAIL_ERROR_NOTFOUND) {
                        i_error("%s: Opening mailbox %s failed: %s",
                                user, mailbox, errstr);
index 1f7baf3ec971191e4f589404b306c86cb38e2f9d..165bd0c175f9891a2398fa9da8259da3123a051f 100644 (file)
@@ -12,11 +12,11 @@ void (*fts_next_hook_mailbox_opened)(struct mailbox *box);
 
 void fts_plugin_init(void)
 {
-       fts_next_hook_mailbox_opened = hook_mailbox_opened;
-       hook_mailbox_opened = fts_mailbox_opened;
+       fts_next_hook_mailbox_allocated = hook_mailbox_allocated;
+       hook_mailbox_allocated = fts_mailbox_allocated;
 }
 
 void fts_plugin_deinit(void)
 {
-       hook_mailbox_opened = fts_next_hook_mailbox_opened;
+       hook_mailbox_allocated = fts_next_hook_mailbox_allocated;
 }
index 35e32a1b4ab36f7127fde04988c561d5f6ae9c07..93fc68b1194452990d68f5931d64224d2317c0d8 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef FTS_PLUGIN_H
 #define FTS_PLUGIN_H
 
-extern void (*fts_next_hook_mailbox_opened)(struct mailbox *box);
+extern void (*fts_next_hook_mailbox_allocated)(struct mailbox *box);
 
-void fts_mailbox_opened(struct mailbox *box);
+void fts_mailbox_allocated(struct mailbox *box);
 
 void fts_plugin_init(void);
 void fts_plugin_deinit(void);
index 18453da123c41005e2b0d7a3660ce85ac7fa8522..8766b86d4a3cc4a075fb93ca64b4692fd7f4c54f 100644 (file)
@@ -58,19 +58,17 @@ static MODULE_CONTEXT_DEFINE_INIT(fts_storage_module,
                                  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(fts_mail_module, &mail_module_register);
 
-static int fts_mailbox_close(struct mailbox *box)
+static void fts_mailbox_close(struct mailbox *box)
 {
        struct fts_mailbox *fbox = FTS_CONTEXT(box);
-       int ret;
 
        if (fbox->backend_substr != NULL)
                fts_backend_deinit(&fbox->backend_substr);
        if (fbox->backend_fast != NULL)
                fts_backend_deinit(&fbox->backend_fast);
 
-       ret = fbox->module_ctx.super.close(box);
+       fbox->module_ctx.super.close(box);
        i_free(fbox);
-       return ret;
 }
 
 static int fts_build_mail_flush_headers(struct fts_storage_build_context *ctx)
@@ -1057,7 +1055,7 @@ static void fts_mailbox_init(struct mailbox *box, const char *env)
        MODULE_CONTEXT_SET(box, fts_storage_module, fbox);
 }
 
-void fts_mailbox_opened(struct mailbox *box)
+void fts_mailbox_allocated(struct mailbox *box)
 {
        const char *env;
 
@@ -1065,6 +1063,6 @@ void fts_mailbox_opened(struct mailbox *box)
        if (env != NULL)
                fts_mailbox_init(box, env);
 
-       if (fts_next_hook_mailbox_opened != NULL)
-               fts_next_hook_mailbox_opened(box);
+       if (fts_next_hook_mailbox_allocated != NULL)
+               fts_next_hook_mailbox_allocated(box);
 }
index 7ad6d85e5141cdadbf0c62a00666f09276740fe5..23b32b1ca120a3850acc077442318ffbc11bb1d4 100644 (file)
@@ -17,8 +17,8 @@
 #define ERROR_NOT_ADMIN "["IMAP_RESP_CODE_NOPERM"] " \
        "You lack administrator privileges on this mailbox."
 
-#define ACL_MAILBOX_OPEN_FLAGS \
-       (MAILBOX_OPEN_READONLY | MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT)
+#define ACL_MAILBOX_FLAGS \
+       (MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT)
 
 #define IMAP_ACL_ANYONE "anyone"
 #define IMAP_ACL_AUTHENTICATED "authenticated"
@@ -69,13 +69,8 @@ acl_mailbox_open_as_admin(struct client_command_context *cmd, const char *name)
 
        /* Force opening the mailbox so that we can give a nicer error message
           if mailbox isn't selectable but is listable. */
-       box = mailbox_open(ns->list, name, NULL, ACL_MAILBOX_OPEN_FLAGS |
-                          MAILBOX_OPEN_IGNORE_ACLS);
-       if (box == NULL) {
-               client_send_list_error(cmd, ns->list);
-               return NULL;
-       }
-
+       box = mailbox_alloc(ns->list, name, NULL, ACL_MAILBOX_FLAGS |
+                           MAILBOX_FLAG_IGNORE_ACLS);
        ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_ADMIN);
        if (ret > 0)
                return box;
@@ -304,13 +299,8 @@ static bool cmd_myrights(struct client_command_context *cmd)
        if (ns == NULL)
                return TRUE;
 
-       box = mailbox_open(ns->list, real_mailbox, NULL,
-                          ACL_MAILBOX_OPEN_FLAGS | MAILBOX_OPEN_IGNORE_ACLS);
-       if (box == NULL) {
-               client_send_list_error(cmd, ns->list);
-               return TRUE;
-       }
-
+       box = mailbox_alloc(ns->list, real_mailbox, NULL,
+                           ACL_MAILBOX_FLAGS | MAILBOX_FLAG_IGNORE_ACLS);
        if (acl_object_get_my_rights(acl_mailbox_get_aclobj(box),
                                     pool_datastack_create(), &rights) < 0) {
                client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
index 9700fb6f386187aba4c727ffac2509c92877e6b5..41f6b8dcf3a5b4e4817e2a3f2790ade38c8ffd06 100644 (file)
@@ -84,26 +84,19 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
        if (ns == NULL)
                return TRUE;
 
-       box = mailbox_open(ns->list, mailbox, NULL, (MAILBOX_OPEN_READONLY |
-                                                    MAILBOX_OPEN_FAST |
-                                                    MAILBOX_OPEN_KEEP_RECENT));
-       if (box == NULL) {
-               client_send_list_error(cmd, ns->list);
-               return TRUE;
-       }
-
        if (quser == NULL) {
-               mailbox_close(&box);
                client_send_tagline(cmd, "OK No quota.");
                return TRUE;
        }
        if (ns->owner != NULL && ns->owner != client->user &&
            !client->user->admin) {
-               mailbox_close(&box);
                client_send_tagline(cmd, "NO Not showing other users' quota.");
                return TRUE;
        }
 
+       box = mailbox_alloc(ns->list, mailbox, NULL, MAILBOX_FLAG_READONLY |
+                           MAILBOX_FLAG_KEEP_RECENT);
+
        /* send QUOTAROOT reply */
        str = t_str_new(128);
        str_append(str, "* QUOTAROOT ");
index 86eda5ac36b89e0083078138ddd10b2aadca36a9..84623b4378c7b2819f45cd3f6eaf0d15e4d4446c 100644 (file)
@@ -48,10 +48,6 @@ struct lazy_expunge_mailbox_list {
        bool internal_namespace;
 };
 
-struct lazy_expunge_mail_storage {
-       union mail_storage_module_context module_ctx;
-};
-
 struct lazy_expunge_transaction {
        union mailbox_transaction_module_context module_ctx;
 
@@ -65,8 +61,7 @@ const char *lazy_expunge_plugin_version = PACKAGE_VERSION;
 
 static void (*lazy_expunge_next_hook_mail_namespaces_created)
        (struct mail_namespace *namespaces);
-static void (*lazy_expunge_next_hook_mail_storage_created)
-       (struct mail_storage *storage);
+static void (*lazy_expunge_next_hook_mailbox_allocated)(struct mailbox *box);
 static void (*lazy_expunge_next_hook_mailbox_list_created)
        (struct mailbox_list *list);
 static void (*lazy_expunge_next_hook_mail_user_created)(struct mail_user *user);
@@ -88,13 +83,16 @@ mailbox_open_or_create(struct mailbox_list *list, const char *name,
        struct mail_storage *storage;
        enum mail_error error;
 
-       box = mailbox_open(list, name, NULL, MAILBOX_OPEN_FAST |
-                          MAILBOX_OPEN_KEEP_RECENT |
-                          MAILBOX_OPEN_NO_INDEX_FILES);
-       if (box != NULL)
+       box = mailbox_alloc(list, name, NULL, MAILBOX_FLAG_KEEP_RECENT |
+                           MAILBOX_FLAG_NO_INDEX_FILES);
+       if (mailbox_open(box) == 0) {
+               *error_r = NULL;
                return box;
+       }
 
-       *error_r = mailbox_list_get_last_error(list, &error);
+       *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
+                                              &error);
+       mailbox_close(&box);
        if (error != MAIL_ERROR_NOTFOUND)
                return NULL;
 
@@ -106,10 +104,13 @@ mailbox_open_or_create(struct mailbox_list *list, const char *name,
        }
 
        /* and try opening again */
-       box = mailbox_open(list, name, NULL, MAILBOX_OPEN_FAST |
-                          MAILBOX_OPEN_KEEP_RECENT);
-       if (box == NULL)
-               *error_r = mailbox_list_get_last_error(list, &error);
+       box = mailbox_alloc(list, name, NULL, MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(box) < 0) {
+               *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
+                                                      &error);
+               mailbox_close(&box);
+               return NULL;
+       }
        return box;
 }
 
@@ -252,33 +253,26 @@ lazy_expunge_mail_alloc(struct mailbox_transaction_context *t,
        return _mail;
 }
 
-static struct mailbox *
-lazy_expunge_mailbox_open(struct mail_storage *storage,
-                         struct mailbox_list *list,
-                         const char *name, struct istream *input,
-                         enum mailbox_open_flags flags)
+static void lazy_expunge_mailbox_allocated(struct mailbox *box)
 {
-       struct lazy_expunge_mail_storage *lstorage =
-               LAZY_EXPUNGE_CONTEXT(storage);
        struct lazy_expunge_mailbox_list *llist =
-               LAZY_EXPUNGE_LIST_CONTEXT(list);
-       struct mailbox *box;
+               LAZY_EXPUNGE_LIST_CONTEXT(box->list);
        union mailbox_module_context *mbox;
 
-       box = lstorage->module_ctx.super.
-               mailbox_open(storage, list, name, input, flags);
-       if (box == NULL || llist == NULL || llist->internal_namespace)
-               return box;
+       if (llist != NULL && !llist->internal_namespace) {
+               mbox = p_new(box->pool, union mailbox_module_context, 1);
+               mbox->super = box->v;
 
-       mbox = p_new(box->pool, union mailbox_module_context, 1);
-       mbox->super = box->v;
+               box->v.transaction_begin = lazy_expunge_transaction_begin;
+               box->v.transaction_commit = lazy_expunge_transaction_commit;
+               box->v.transaction_rollback = lazy_expunge_transaction_rollback;
+               box->v.mail_alloc = lazy_expunge_mail_alloc;
+               MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module,
+                                       mbox);
+       }
 
-       box->v.transaction_begin = lazy_expunge_transaction_begin;
-       box->v.transaction_commit = lazy_expunge_transaction_commit;
-       box->v.transaction_rollback = lazy_expunge_transaction_rollback;
-       box->v.mail_alloc = lazy_expunge_mail_alloc;
-       MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module, mbox);
-       return box;
+       if (lazy_expunge_next_hook_mailbox_allocated != NULL)
+               lazy_expunge_next_hook_mailbox_allocated(box);
 }
 
 static int
@@ -373,25 +367,6 @@ lazy_expunge_mailbox_list_delete(struct mailbox_list *list, const char *name)
        return 0;
 }
 
-static void lazy_expunge_mail_storage_init(struct mail_storage *storage)
-{
-       struct lazy_expunge_mail_storage *lstorage;
-
-       lstorage = p_new(storage->pool, struct lazy_expunge_mail_storage, 1);
-       lstorage->module_ctx.super = storage->v;
-       storage->v.mailbox_open = lazy_expunge_mailbox_open;
-
-       MODULE_CONTEXT_SET(storage, lazy_expunge_mail_storage_module, lstorage);
-}
-
-static void lazy_expunge_mail_storage_created(struct mail_storage *storage)
-{
-       lazy_expunge_mail_storage_init(storage);
-
-       if (lazy_expunge_next_hook_mail_storage_created != NULL)
-               lazy_expunge_next_hook_mail_storage_created(storage);
-}
-
 static void lazy_expunge_mailbox_list_created(struct mailbox_list *list)
 {
        struct lazy_expunge_mail_user *luser =
@@ -485,8 +460,8 @@ void lazy_expunge_plugin_init(void)
        hook_mail_namespaces_created =
                lazy_expunge_hook_mail_namespaces_created;
 
-       lazy_expunge_next_hook_mail_storage_created = hook_mail_storage_created;
-       hook_mail_storage_created = lazy_expunge_mail_storage_created;
+       lazy_expunge_next_hook_mailbox_allocated = hook_mailbox_allocated;
+       hook_mailbox_allocated = lazy_expunge_mailbox_allocated;
 
        lazy_expunge_next_hook_mailbox_list_created = hook_mailbox_list_created;
        hook_mailbox_list_created = lazy_expunge_mailbox_list_created;
@@ -499,7 +474,7 @@ void lazy_expunge_plugin_deinit(void)
 {
        hook_mail_namespaces_created =
                lazy_expunge_hook_mail_namespaces_created;
-       hook_mail_storage_created = lazy_expunge_next_hook_mail_storage_created;
+       hook_mailbox_allocated = lazy_expunge_next_hook_mailbox_allocated;
        hook_mailbox_list_created = lazy_expunge_next_hook_mailbox_list_created;
        hook_mail_user_created = lazy_expunge_next_hook_mail_user_created;
 }
index 3423e8836d0e29710dbf259c40ef8fac955146c0..93284e2eeb053222707beb6a066c7b299d9c2561 100644 (file)
@@ -163,9 +163,10 @@ listescape_mailbox_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
 }
 
 static struct mailbox *
-listescape_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                       const char *name, struct istream *input,
-                       enum mailbox_open_flags flags)
+listescape_mailbox_alloc(struct mail_storage *storage,
+                        struct mailbox_list *list,
+                        const char *name, struct istream *input,
+                        enum mailbox_flags flags)
 {
        struct listescape_mail_storage *mstorage = LIST_ESCAPE_CONTEXT(storage);
        struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
@@ -173,7 +174,7 @@ listescape_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
        if (!mlist->name_escaped && list->hierarchy_sep != list->ns->sep)
                name = list_escape(list->ns, name, TRUE);
        return mstorage->module_ctx.super.
-               mailbox_open(storage, list, name, input, flags);
+               mailbox_alloc(storage, list, name, input, flags);
 }
 
 static int
@@ -266,7 +267,7 @@ static void listescape_mail_storage_created(struct mail_storage *storage)
 
        mstorage = p_new(storage->pool, struct listescape_mail_storage, 1);
        mstorage->module_ctx.super = storage->v;
-       storage->v.mailbox_open = listescape_mailbox_open;
+       storage->v.mailbox_alloc = listescape_mailbox_alloc;
        storage->v.mailbox_create = listescape_mailbox_create;
 
        MODULE_CONTEXT_SET(storage, listescape_storage_module, mstorage);
index dea1996ac19a955ff30fb281ef365696566d4bcb..e51d85a982fe2e9196522e1451256020ff28f5b5 100644 (file)
@@ -555,17 +555,15 @@ mail_log_transaction_rollback(struct mailbox_transaction_context *t)
 }
 
 static struct mailbox *
-mail_log_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                     const char *name, struct istream *input,
-                     enum mailbox_open_flags flags)
+mail_log_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                      const char *name, struct istream *input,
+                      enum mailbox_flags flags)
 {
        union mail_storage_module_context *lstorage = MAIL_LOG_CONTEXT(storage);
        struct mailbox *box;
        union mailbox_module_context *lbox;
 
-       box = lstorage->super.mailbox_open(storage, list, name, input, flags);
-       if (box == NULL)
-               return NULL;
+       box = lstorage->super.mailbox_alloc(storage, list, name, input, flags);
 
        lbox = p_new(box->pool, union mailbox_module_context, 1);
        lbox->super = box->v;
@@ -625,7 +623,7 @@ static void mail_log_mail_storage_created(struct mail_storage *storage)
 
        lstorage = p_new(storage->pool, union mail_storage_module_context, 1);
        lstorage->super = storage->v;
-       storage->v.mailbox_open = mail_log_mailbox_open;
+       storage->v.mailbox_alloc = mail_log_mailbox_alloc;
 
        MODULE_CONTEXT_SET_SELF(storage, mail_log_storage_module, lstorage);
 
index 06a1753c26ac3bf6f401d83716a07549874315a4..f89345c24d13166ffb6e52d98793d75b44dde1ce 100644 (file)
@@ -113,31 +113,30 @@ mbox_snarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
                /* try to open the spool mbox */
                mstorage->open_spool_inbox = TRUE;
                mbox->spool_mbox =
-                       mailbox_open(box->list, "INBOX", NULL,
-                                    MAILBOX_OPEN_KEEP_RECENT |
-                                    MAILBOX_OPEN_NO_INDEX_FILES);
+                       mailbox_alloc(box->list, "INBOX", NULL,
+                                     MAILBOX_FLAG_KEEP_RECENT |
+                                     MAILBOX_FLAG_NO_INDEX_FILES);
                mstorage->open_spool_inbox = FALSE;
        }
-
-       if (mbox->spool_mbox != NULL)
-               mbox_snarf(mbox->spool_mbox, box);
+       (void)mbox_snarf(mbox->spool_mbox, box);
 
        return mbox->module_ctx.super.sync_init(box, flags);
 }
 
-static int mbox_snarf_close(struct mailbox *box)
+static void mbox_snarf_close(struct mailbox *box)
 {
        struct mbox_snarf_mailbox *mbox = MBOX_SNARF_CONTEXT(box);
 
        if (mbox->spool_mbox != NULL)
                mailbox_close(&mbox->spool_mbox);
-       return mbox->module_ctx.super.close(box);
+       mbox->module_ctx.super.close(box);
 }
 
 static struct mailbox *
-mbox_snarf_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                       const char *name, struct istream *input,
-                       enum mailbox_open_flags flags)
+mbox_snarf_mailbox_alloc(struct mail_storage *storage,
+                        struct mailbox_list *list,
+                        const char *name, struct istream *input,
+                        enum mailbox_flags flags)
 {
        struct mbox_snarf_mail_storage *mstorage =
                MBOX_SNARF_CONTEXT(storage);
@@ -164,7 +163,7 @@ mbox_snarf_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
        }
 
        box = mstorage->module_ctx.super.
-               mailbox_open(storage, list, name, input, flags);
+               mailbox_alloc(storage, list, name, input, flags);
        storage->flags = old_flags;
        list->flags = old_list_flags;
 
@@ -189,7 +188,7 @@ mbox_snarf_mail_storage_create(struct mail_storage *storage, const char *path)
        mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1);
        mstorage->snarf_inbox_path = p_strdup(storage->pool, path);
        mstorage->module_ctx.super = storage->v;
-       storage->v.mailbox_open = mbox_snarf_mailbox_open;
+       storage->v.mailbox_alloc = mbox_snarf_mailbox_alloc;
 
        MODULE_CONTEXT_SET(storage, mbox_snarf_storage_module, mstorage);
 }
index 33294651a79ceb71b6099b4dad767fdaf3c31c88..4f425621a799929f574b32c625b4b9a1a9055c5e 100644 (file)
@@ -27,10 +27,11 @@ quota_count_mailbox(struct quota_root *root, struct mail_namespace *ns,
                return 0;
        }
 
-       box = mailbox_open(ns->list, name, NULL,
-                          MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT);
-       if (box == NULL) {
-               mailbox_list_get_last_error(ns->list, &error);
+       box = mailbox_alloc(ns->list, name, NULL,
+                           MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(box) < 0) {
+               mail_storage_get_last_error(mailbox_get_storage(box), &error);
+               mailbox_close(&box);
                if (error == MAIL_ERROR_TEMP)
                        return -1;
                /* non-temporary error, e.g. ACLs denied access. */
index 34aa281741031b2981b8de97912ab7ae2916de4b..f3abdf3f919dedd74d13e6b2bb85d396810afb18 100644 (file)
@@ -341,7 +341,7 @@ static int quota_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
        return ret;
 }
 
-static int quota_mailbox_close(struct mailbox *box)
+static void quota_mailbox_close(struct mailbox *box)
 {
        struct quota_mailbox *qbox = QUOTA_CONTEXT(box);
 
@@ -352,19 +352,19 @@ static int quota_mailbox_close(struct mailbox *box)
        i_assert(qbox->expunge_qt == NULL ||
                 qbox->expunge_qt->tmp_mail == NULL);
 
-       return qbox->module_ctx.super.close(box);
+       qbox->module_ctx.super.close(box);
 }
 
 static struct mailbox *
-quota_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                  const char *name, struct istream *input,
-                  enum mailbox_open_flags flags)
+quota_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                   const char *name, struct istream *input,
+                   enum mailbox_flags flags)
 {
        union mail_storage_module_context *qstorage = QUOTA_CONTEXT(storage);
        struct mailbox *box;
        struct quota_mailbox *qbox;
 
-       box = qstorage->super.mailbox_open(storage, list, name, input, flags);
+       box = qstorage->super.mailbox_alloc(storage, list, name, input, flags);
        if (box == NULL || QUOTA_LIST_CONTEXT(list) == NULL)
                return box;
 
@@ -440,10 +440,11 @@ quota_mailbox_list_delete(struct mailbox_list *list, const char *name)
           and free the quota for all the messages existing in it. Open the
           mailbox locked so that other processes can't mess up the quota
           calculations by adding/removing mails while we're doing this. */
-       box = mailbox_open(list, name, NULL, MAILBOX_OPEN_KEEP_RECENT |
-                          MAILBOX_OPEN_KEEP_LOCKED);
-       if (box == NULL) {
-               str = mailbox_list_get_last_error(list, &error);
+       box = mailbox_alloc(list, name, NULL, MAILBOX_FLAG_KEEP_RECENT |
+                           MAILBOX_FLAG_KEEP_LOCKED);
+       if (mailbox_open(box) < 0) {
+               str = mail_storage_get_last_error(mailbox_get_storage(box),
+                                                 &error);
                if (error != MAIL_ERROR_NOTPOSSIBLE) {
                        ret = -1;
                } else {
@@ -518,7 +519,7 @@ void quota_mail_storage_created(struct mail_storage *storage)
 
        qstorage = p_new(storage->pool, union mail_storage_module_context, 1);
        qstorage->super = storage->v;
-       storage->v.mailbox_open = quota_mailbox_open;
+       storage->v.mailbox_alloc = quota_mailbox_alloc;
 
        MODULE_CONTEXT_SET_SELF(storage, quota_storage_module, qstorage);
        quota_maildir_storage_set(storage);
index 4f59847a14449b6b954c8c51404da36b673c9ce7..fee57e44f13cd2405c9b5660c60a864e8e78fe7c 100644 (file)
@@ -54,10 +54,12 @@ static int trash_clean_mailbox_open(struct trash_mailbox *trash)
 {
        struct mail_search_args *search_args;
 
-       trash->box = mailbox_open(trash->ns->list, trash->name, NULL,
-                                 MAILBOX_OPEN_KEEP_RECENT);
-       if (trash->box == NULL)
+       trash->box = mailbox_alloc(trash->ns->list, trash->name, NULL,
+                                  MAILBOX_FLAG_KEEP_RECENT);
+       if (mailbox_open(trash->box) < 0) {
+               mailbox_close(&trash->box);
                return 0;
+       }
 
        if (mailbox_sync(trash->box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0)
                return -1;
index f145e87fdca07f11445386fda2c28e0b013221fe..90174b132e3bab5487f6caf6d1cbc170b05b912a 100644 (file)
@@ -323,7 +323,7 @@ int virtual_config_read(struct virtual_mailbox *mbox)
        i_array_init(&mbox->backend_boxes, 8);
        mbox->search_args_crc32 = (uint32_t)-1;
 
-       path = t_strconcat(mbox->path, "/"VIRTUAL_CONFIG_FNAME, NULL);
+       path = t_strconcat(mbox->ibox.box.path, "/"VIRTUAL_CONFIG_FNAME, NULL);
        fd = open(path, O_RDONLY);
        if (fd == -1) {
                if (errno == ENOENT) {
index 595386de97affd4b136f48c1017512fee6e9526b..4bb8fbe4f5a24083f042b32d181322a70aaf8ca4 100644 (file)
@@ -118,26 +118,27 @@ static bool virtual_mailbox_is_in_open_stack(struct virtual_storage *storage,
 }
 
 static int virtual_mailboxes_open(struct virtual_mailbox *mbox,
-                                 enum mailbox_open_flags open_flags)
+                                 enum mailbox_flags flags)
 {
        struct mail_user *user = mbox->storage->storage.user;
        struct virtual_backend_box *const *bboxes;
+       struct mail_storage *storage;
        struct mail_namespace *ns;
        unsigned int i, count;
        enum mail_error error;
        const char *str, *mailbox;
 
-       open_flags |= MAILBOX_OPEN_KEEP_RECENT;
+       flags |= MAILBOX_FLAG_KEEP_RECENT;
 
        bboxes = array_get(&mbox->backend_boxes, &count);
        for (i = 0; i < count; ) {
                mailbox = bboxes[i]->name;
                ns = mail_namespace_find(user->namespaces, &mailbox);
-               bboxes[i]->box = mailbox_open(ns->list, mailbox,
-                                             NULL, open_flags);
+               bboxes[i]->box = mailbox_alloc(ns->list, mailbox, NULL, flags);
 
-               if (bboxes[i]->box == NULL) {
-                       str = mailbox_list_get_last_error(ns->list, &error);
+               if (mailbox_open(bboxes[i]->box) < 0) {
+                       storage = mailbox_get_storage(bboxes[i]->box);
+                       str = mail_storage_get_last_error(storage, &error);
                        if (bboxes[i]->wildcard &&
                            (error == MAIL_ERROR_PERM ||
                             error == MAIL_ERROR_NOTFOUND)) {
@@ -148,11 +149,9 @@ static int virtual_mailboxes_open(struct virtual_mailbox *mbox,
                                bboxes = array_get(&mbox->backend_boxes, &count);
                                continue;
                        }
-                       if (ns->list != mbox->ibox.box.list) {
-                               /* copy the error */
-                               mailbox_list_set_error(mbox->ibox.box.list,
-                                                      error, str);
-                       }
+                       /* copy the error */
+                       mail_storage_set_error(mbox->ibox.box.storage,
+                                              error, str);
                        break;
                }
                i_array_init(&bboxes[i]->uids, 64);
@@ -166,7 +165,7 @@ static int virtual_mailboxes_open(struct virtual_mailbox *mbox,
        else {
                /* failed */
                for (; i > 0; i--) {
-                       (void)mailbox_close(&bboxes[i-1]->box);
+                       mailbox_close(&bboxes[i-1]->box);
                        array_free(&bboxes[i-1]->uids);
                }
                return -1;
@@ -174,96 +173,83 @@ static int virtual_mailboxes_open(struct virtual_mailbox *mbox,
 }
 
 static struct mailbox *
-virtual_open(struct virtual_storage *storage, struct mailbox_list *list,
-            const char *name, enum mailbox_open_flags flags)
+virtual_mailbox_alloc(struct mail_storage *_storage, struct mailbox_list *list,
+                     const char *name, struct istream *input,
+                     enum mailbox_flags flags)
 {
-       struct mail_storage *_storage = &storage->storage;
+       struct virtual_storage *storage = (struct virtual_storage *)storage;
        struct virtual_mailbox *mbox;
-       struct mail_index *index;
-       const char *path;
        pool_t pool;
-       bool failed;
-
-       if (virtual_mailbox_is_in_open_stack(storage, name)) {
-               mail_storage_set_critical(_storage,
-                                         "Virtual mailbox loops: %s", name);
-               return NULL;
-       }
-
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       index = index_storage_alloc(list, name, flags, VIRTUAL_INDEX_PREFIX);
 
        pool = pool_alloconly_create("virtual mailbox", 1024+512);
        mbox = p_new(pool, struct virtual_mailbox, 1);
        mbox->ibox.box = virtual_mailbox;
        mbox->ibox.box.pool = pool;
        mbox->ibox.box.storage = _storage;
+       mbox->ibox.box.list = list;
        mbox->ibox.mail_vfuncs = &virtual_mail_vfuncs;
-       mbox->ibox.index = index;
+
+       index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
+                                   VIRTUAL_INDEX_PREFIX);
 
        mbox->storage = storage;
-       mbox->path = p_strdup(pool, path);
        mbox->vseq_lookup_prev_mailbox = i_strdup("");
 
        mbox->virtual_ext_id =
-               mail_index_ext_register(index, "virtual", 0,
+               mail_index_ext_register(mbox->ibox.index, "virtual", 0,
                        sizeof(struct virtual_mail_index_record),
                        sizeof(uint32_t));
-
-       array_append(&storage->open_stack, &name, 1);
-       failed = virtual_config_read(mbox) < 0 ||
-               virtual_mailboxes_open(mbox, flags) < 0;
-       array_delete(&storage->open_stack,
-                    array_count(&storage->open_stack)-1, 1);
-       if (failed) {
-               virtual_config_free(mbox);
-               index_storage_mailbox_close(&mbox->ibox.box);
-               return NULL;
-       }
-
-       index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
        return &mbox->ibox.box;
 }
 
-static struct mailbox *
-virtual_mailbox_open(struct mail_storage *_storage, struct mailbox_list *list,
-                    const char *name, struct istream *input,
-                    enum mailbox_open_flags flags)
+static int virtual_mailbox_open(struct mailbox *box)
 {
-       struct virtual_storage *storage = (struct virtual_storage *)_storage;
-       const char *path;
+       struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
        struct stat st;
+       bool failed;
 
-       if (input != NULL) {
-               mailbox_list_set_critical(list,
+       if (virtual_mailbox_is_in_open_stack(mbox->storage, box->name)) {
+               mail_storage_set_critical(box->storage,
+                       "Virtual mailbox loops: %s", box->name);
+               return -1;
+       }
+
+       if (box->input != NULL) {
+               mail_storage_set_critical(box->storage,
                        "virtual doesn't support streamed mailboxes");
-               return NULL;
+               return -1;
        }
 
-       path = mailbox_list_get_path(list, name,
-                                    MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       if (stat(path, &st) == 0)
-               return virtual_open(storage, list, name, flags);
-       else if (errno == ENOENT) {
-               mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
-                       T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
+       if (stat(box->path, &st) == 0) {
+               /* exists, open it */
+       } else if (errno == ENOENT) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
+                       T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
+               return -1;
        } else if (errno == EACCES) {
-               mailbox_list_set_critical(list, "%s",
-                       mail_error_eacces_msg("stat", path));
+               mail_storage_set_critical(box->storage, "%s",
+                       mail_error_eacces_msg("stat", box->path));
+               return -1;
        } else {
-               mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
+               mail_storage_set_critical(box->storage,
+                                         "stat(%s) failed: %m", box->path);
+               return -1;
        }
-       return NULL;
+
+       array_append(&mbox->storage->open_stack, &box->name, 1);
+       failed = virtual_config_read(mbox) < 0 ||
+               virtual_mailboxes_open(mbox, box->flags) < 0;
+       array_delete(&mbox->storage->open_stack,
+                    array_count(&mbox->storage->open_stack)-1, 1);
+       return failed ? -1 : 0;
 }
 
-static int virtual_storage_mailbox_close(struct mailbox *box)
+static void virtual_mailbox_close(struct mailbox *box)
 {
        struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
        struct mail_storage *storage;
        struct virtual_backend_box **bboxes;
        unsigned int i, count;
-       int ret = 0;
 
        virtual_config_free(mbox);
 
@@ -273,14 +259,7 @@ static int virtual_storage_mailbox_close(struct mailbox *box)
                        mailbox_search_result_free(&bboxes[i]->search_result);
 
                storage = bboxes[i]->box->storage;
-               if (mailbox_close(&bboxes[i]->box) < 0) {
-                       const char *str;
-                       enum mail_error error;
-
-                       str = mail_storage_get_last_error(storage, &error);
-                       mail_storage_set_error(box->storage, error, str);
-                       ret = -1;
-               }
+               mailbox_close(&bboxes[i]->box);
                if (array_is_created(&bboxes[i]->sync_outside_expunges))
                        array_free(&bboxes[i]->sync_outside_expunges);
                array_free(&bboxes[i]->sync_pending_removes);
@@ -289,7 +268,7 @@ static int virtual_storage_mailbox_close(struct mailbox *box)
        array_free(&mbox->backend_boxes);
        i_free(mbox->vseq_lookup_prev_mailbox);
 
-       return index_storage_mailbox_close(box) < 0 ? -1 : ret;
+       index_storage_mailbox_close(box);
 }
 
 static int virtual_mailbox_create(struct mail_storage *_storage,
@@ -578,7 +557,7 @@ struct mail_storage virtual_storage = {
                virtual_storage_add_list,
                virtual_storage_get_list_settings,
                NULL,
-               virtual_mailbox_open,
+               virtual_mailbox_alloc,
                virtual_mailbox_create,
                NULL
        }
@@ -593,7 +572,8 @@ struct mailbox virtual_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               virtual_storage_mailbox_close,
+               virtual_mailbox_open,
+               virtual_mailbox_close,
                index_storage_get_status,
                NULL,
                NULL,
index 1822c59d7cc4c2e7b61163f3fdd32ea53577f85e..11c47a17adcb7e35350dee52408fdb7c0a69d928 100644 (file)
@@ -102,7 +102,6 @@ struct virtual_mailbox {
        struct index_mailbox ibox;
        struct virtual_storage *storage;
 
-       const char *path;
        uint32_t virtual_ext_id;
 
        uint32_t prev_uid_validity;
index b3f36f2cafd6292973808ca467590dbc18ef55f8..dbe90fccce7f77ed27601783b40c4b8ca69fb635 100644 (file)
@@ -169,7 +169,7 @@ static bool virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
                if (ext_name_offset >= ext_size ||
                    ext_hdr->mailbox_count > INT_MAX/sizeof(*mailboxes)) {
                        i_error("virtual index %s: Broken mailbox_count header",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                        ctx->index_broken = TRUE;
                        ext_mailbox_count = 0;
                        ret = FALSE;
@@ -184,18 +184,18 @@ static bool virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
                if (mailboxes[i].id > ext_hdr->highest_mailbox_id ||
                    mailboxes[i].id <= prev_mailbox_id) {
                        i_error("virtual index %s: Broken mailbox id",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                        break;
                }
                if (mailboxes[i].name_len == 0 ||
                    mailboxes[i].name_len > ext_size) {
                        i_error("virtual index %s: Broken mailbox name_len",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                        break;
                }
                if (ext_name_offset + mailboxes[i].name_len > ext_size) {
                        i_error("virtual index %s: Broken mailbox list",
-                               ctx->mbox->path);
+                               ctx->mbox->ibox.box.path);
                        break;
                }
                T_BEGIN {
@@ -999,8 +999,10 @@ static int virtual_sync_backend_box(struct virtual_sync_context *ctx,
        struct mailbox_status status;
        int ret;
 
-       if (!bbox->box->opened)
-               index_storage_mailbox_open(ibox);
+       if (!bbox->box->opened) {
+               if (mailbox_open(bbox->box) < 0)
+                       return -1;
+       }
 
        /* if we already did some changes to index, commit them before
           syncing starts. */
@@ -1391,7 +1393,7 @@ static int virtual_sync_finish(struct virtual_sync_context *ctx, bool success)
                        if (mail_index_unlink(ctx->index) < 0) {
                                i_error("virtual index %s: Failed to unlink() "
                                        "broken indexes: %m",
-                                       ctx->mbox->path);
+                                       ctx->mbox->ibox.box.path);
                        }
                }
                mail_index_sync_rollback(&ctx->index_sync_ctx);
@@ -1452,10 +1454,12 @@ virtual_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        struct mailbox_sync_context *sync_ctx;
        int ret = 0;
 
-       if (!box->opened)
-               index_storage_mailbox_open(&mbox->ibox);
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       ret = -1;
+       }
 
-       if (index_mailbox_want_full_sync(&mbox->ibox, flags))
+       if (index_mailbox_want_full_sync(&mbox->ibox, flags) && ret == 0)
                ret = virtual_sync(mbox, flags);
 
        sync_ctx = index_mailbox_sync_init(box, flags, ret < 0);
index a60ef36e0303c1fdf29947a20942e2178ffba267..507b3f2220da4671576ab3b0357cd19f42cc791b 100644 (file)
@@ -203,9 +203,9 @@ zlib_mailbox_open_input(struct mail_storage *storage, struct mailbox_list *list,
 }
 
 static struct mailbox *
-zlib_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
-                 const char *name, struct istream *input,
-                 enum mailbox_open_flags flags)
+zlib_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
+                  const char *name, struct istream *input,
+                  enum mailbox_flags flags)
 {
        union mail_storage_module_context *qstorage = ZLIB_CONTEXT(storage);
        struct mailbox *box;
@@ -216,12 +216,12 @@ zlib_mailbox_open(struct mail_storage *storage, struct mailbox_list *list,
                        zlib_mailbox_open_input(storage, list, name);
        }
 
-       box = qstorage->super.mailbox_open(storage, list, name, input, flags);
+       box = qstorage->super.mailbox_alloc(storage, list, name, input, flags);
 
        if (zlib_input != NULL)
                i_stream_unref(&zlib_input);
 
-       if (box != NULL && strcmp(storage->name, "maildir") == 0)
+       if (strcmp(box->storage->name, "maildir") == 0)
                zlib_maildir_open_init(box);
        return box;
 }
@@ -232,7 +232,7 @@ static void zlib_mail_storage_created(struct mail_storage *storage)
 
        qstorage = p_new(storage->pool, union mail_storage_module_context, 1);
        qstorage->super = storage->v;
-       storage->v.mailbox_open = zlib_mailbox_open;
+       storage->v.mailbox_alloc = zlib_mailbox_alloc;
 
        MODULE_CONTEXT_SET_SELF(storage, zlib_storage_module, qstorage);
 
index ec0fe2d2153fceaf12fee73d166181d07c7236f9..0d096ca33608b1a95abb4e262a72d78879dc1c28 100644 (file)
@@ -221,7 +221,7 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user,
        struct mail_storage *storage;
        const char *inbox, *ident;
        struct client *client;
-        enum mailbox_open_flags flags;
+        enum mailbox_flags flags;
        const char *errmsg;
        enum mail_error error;
 
@@ -257,22 +257,22 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user,
        }
        client->inbox_ns = ns;
 
-       flags = MAILBOX_OPEN_POP3_SESSION;
+       flags = MAILBOX_FLAG_POP3_SESSION;
        if (set->pop3_no_flag_updates)
-               flags |= MAILBOX_OPEN_KEEP_RECENT;
+               flags |= MAILBOX_FLAG_KEEP_RECENT;
        if (set->pop3_lock_session)
-               flags |= MAILBOX_OPEN_KEEP_LOCKED;
-       client->mailbox = mailbox_open(ns->list, "INBOX", NULL, flags);
-       if (client->mailbox == NULL) {
+               flags |= MAILBOX_FLAG_KEEP_LOCKED;
+       client->mailbox = mailbox_alloc(ns->list, "INBOX", NULL, flags);
+       storage = mailbox_get_storage(client->mailbox);
+       if (mailbox_open(client->mailbox) < 0) {
                errmsg = t_strdup_printf("Couldn't open INBOX: %s",
-                                        mailbox_list_get_last_error(ns->list,
+                                        mail_storage_get_last_error(storage,
                                                                     &error));
                i_error("%s", errmsg);
                client_send_line(client, "-ERR [IN-USE] %s", errmsg);
                client_destroy(client, "Couldn't open INBOX");
                return NULL;
        }
-       storage = mailbox_get_storage(client->mailbox);
        client->mail_set = mail_storage_get_settings(storage);
 
        if (!init_mailbox(client, &errmsg)) {
index cd49470c02a8cabfc9407fd121354e8dc4641629..94ef481bc06f9b6fd84a79fd8acd9b5bee09dc34 100644 (file)
@@ -58,11 +58,12 @@ mailbox_find_and_open(struct mail_user *user, const char *mailbox)
        if (ns == NULL)
                i_fatal("Can't find namespace for mailbox %s", mailbox);
 
-       box = mailbox_open(ns->list, mailbox, NULL, MAILBOX_OPEN_KEEP_RECENT |
-                          MAILBOX_OPEN_IGNORE_ACLS);
-       if (box == NULL) {
+       box = mailbox_alloc(ns->list, mailbox, NULL, MAILBOX_FLAG_KEEP_RECENT |
+                           MAILBOX_FLAG_IGNORE_ACLS);
+       if (mailbox_open(box) < 0) {
                i_fatal("Opening mailbox %s failed: %s", orig_mailbox,
-                       mailbox_list_get_last_error(ns->list, NULL));
+                       mail_storage_get_last_error(mailbox_get_storage(box),
+                                                   NULL));
        }
        return box;
 }