Mercurial > dovecot > core-2.2
changeset 9468:653183a81b6c HEAD
Mailbox opening and closing APIs changed.
line wrap: on
line diff
--- a/src/imap/cmd-append.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-append.c Mon Jun 15 14:28:55 2009 -0400 @@ -465,10 +465,11 @@ 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)
--- a/src/imap/cmd-close.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-close.c Mon Jun 15 14:28:55 2009 -0400 @@ -23,8 +23,7 @@ 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.");
--- a/src/imap/cmd-copy.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-copy.c Mon Jun 15 14:28:55 2009 -0400 @@ -127,11 +127,13 @@ 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)
--- a/src/imap/cmd-delete.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-delete.c Mon Jun 15 14:28:55 2009 -0400 @@ -33,8 +33,7 @@ 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 &&
--- a/src/imap/cmd-select.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-select.c Mon Jun 15 14:28:55 2009 -0400 @@ -263,13 +263,15 @@ { 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 @@ 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]"); }
--- a/src/imap/cmd-unselect.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/cmd-unselect.c Mon Jun 15 14:28:55 2009 -0400 @@ -18,8 +18,7 @@ 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.");
--- a/src/imap/imap-status.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/imap/imap-status.c Mon Jun 15 14:28:55 2009 -0400 @@ -62,13 +62,8 @@ } /* 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);
--- a/src/lda/main.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lda/main.c Mon Jun 15 14:28:55 2009 -0400 @@ -416,17 +416,17 @@ 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",
--- a/src/lib-lda/mail-deliver.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-lda/mail-deliver.c Mon Jun 15 14:28:55 2009 -0400 @@ -79,16 +79,16 @@ 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 @@ 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 @@ } /* 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;
--- a/src/lib-storage/index/cydir/cydir-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/cydir/cydir-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -48,13 +48,13 @@ 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 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; + + 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); mbox->storage = (struct cydir_storage *)storage; - mbox->path = p_strdup(pool, path); - - index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE); 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 @@ return -1; } - return create_cydir(storage, list->ns, path); + return create_cydir(storage, list, path); } static int @@ -261,7 +249,7 @@ 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 @@ cydir_storage_add_list, cydir_storage_get_list_settings, NULL, - cydir_mailbox_open, + cydir_mailbox_alloc, cydir_mailbox_create, NULL } @@ -371,6 +359,7 @@ 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,
--- a/src/lib-storage/index/cydir/cydir-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/cydir/cydir-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -16,8 +16,6 @@ struct cydir_mailbox { struct index_mailbox ibox; struct cydir_storage *storage; - - const char *path; }; struct cydir_transaction_context {
--- a/src/lib-storage/index/cydir/cydir-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/cydir/cydir-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -175,10 +175,12 @@ 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);
--- a/src/lib-storage/index/dbox/dbox-file.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-file.c Mon Jun 15 14:28:55 2009 -0400 @@ -151,7 +151,7 @@ { 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 @@ } 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 @@ 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);
--- a/src/lib-storage/index/dbox/dbox-mail.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-mail.c Mon Jun 15 14:28:55 2009 -0400 @@ -68,7 +68,8 @@ &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 @@ 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;
--- a/src/lib-storage/index/dbox/dbox-save.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-save.c Mon Jun 15 14:28:55 2009 -0400 @@ -445,9 +445,9 @@ 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);
--- a/src/lib-storage/index/dbox/dbox-storage-rebuild.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-storage-rebuild.c Mon Jun 15 14:28:55 2009 -0400 @@ -398,12 +398,13 @@ 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 @@ 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 @@ ret = -1; } - (void)mailbox_close(&box); + mailbox_close(&box); return ret < 0 ? -1 : 0; } @@ -484,7 +485,7 @@ { 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 @@ 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 @@ 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;
--- a/src/lib-storage/index/dbox/dbox-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -136,59 +136,49 @@ 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); - - ret = index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE); - mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox); + mail_index_ext_register(mbox->ibox.index, "guid", + 0, DBOX_GUID_BIN_LEN, 1); - box = &mbox->ibox.box; - if (ret < 0) - mailbox_close(&box); - return box; + mbox->maildir_uidlist = maildir_uidlist_init_readonly(&mbox->ibox); + return &mbox->ibox.box; } uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list) @@ -201,7 +191,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,
--- a/src/lib-storage/index/dbox/dbox-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -73,7 +73,7 @@ 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_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,
--- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c Mon Jun 15 14:28:55 2009 -0400 @@ -191,7 +191,7 @@ 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 @@ 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 @@ 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 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,
--- a/src/lib-storage/index/dbox/dbox-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/dbox/dbox-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -221,7 +221,7 @@ 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 @@ 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 @@ int ret = 0; if (!box->opened) { - if (index_storage_mailbox_open(&mbox->ibox) < 0) + if (mailbox_open(box) < 0) ret = -1; }
--- a/src/lib-storage/index/index-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/index-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -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 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 @@ 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 @@ 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 @@ 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 @@ 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; - - i_assert(name != NULL); + const char *path; - 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 (name != NULL) + box->name = p_strdup(box->pool, name); + else { + i_assert(input != NULL); + box->name = "(read-only input stream)"; } + 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 @@ 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 @@ 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 @@ 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 @@ 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; }
--- a/src/lib-storage/index/index-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/index-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -85,20 +85,18 @@ 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);
--- a/src/lib-storage/index/index-thread.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/index-thread.c Mon Jun 15 14:28:55 2009 -0400 @@ -609,10 +609,9 @@ 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 @@ 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)
--- a/src/lib-storage/index/maildir/maildir-copy.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-copy.c Mon Jun 15 14:28:55 2009 -0400 @@ -211,7 +211,7 @@ /* 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) {
--- a/src/lib-storage/index/maildir/maildir-keywords.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-keywords.c Mon Jun 15 14:28:55 2009 -0400 @@ -372,7 +372,7 @@ } /* 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; }
--- a/src/lib-storage/index/maildir/maildir-mail.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-mail.c Mon Jun 15 14:28:55 2009 -0400 @@ -226,8 +226,7 @@ /* 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 @@ "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,
--- a/src/lib-storage/index/maildir/maildir-save.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-save.c Mon Jun 15 14:28:55 2009 -0400 @@ -122,9 +122,9 @@ 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 @@ 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 */
--- a/src/lib-storage/index/maildir/maildir-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -295,19 +295,17 @@ 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 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); + return maildir_mailbox_open_existing(box); } - if (ret < 0) { - mailbox_list_set_error_from_storage(list, storage); - return NULL; - } + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,
--- a/src/lib-storage/index/maildir/maildir-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -83,7 +83,6 @@ struct maildir_storage *storage; struct mail_index_view *flags_view; - const char *path; struct timeout *keep_lock_to; /* maildir sync: */ @@ -122,7 +121,7 @@ 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);
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Mon Jun 15 14:28:55 2009 -0400 @@ -160,7 +160,8 @@ 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 @@ 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 @@ 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;
--- a/src/lib-storage/index/maildir/maildir-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -255,8 +255,8 @@ 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 @@ } 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_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 @@ 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 @@ return -1; } - if (!maildir_set_deleted(ctx->mbox)) + if (!maildir_set_deleted(&ctx->mbox->ibox.box)) return -1; /* try again */ } @@ -909,8 +910,10 @@ 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 @@ 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);
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Mon Jun 15 14:28:55 2009 -0400 @@ -174,7 +174,7 @@ } /* 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 @@ } /* 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; }
--- a/src/lib-storage/index/maildir/maildir-util.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-util.c Mon Jun 15 14:28:55 2009 -0400 @@ -74,13 +74,13 @@ 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_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 @@ /* @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 @@ 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; }
--- a/src/lib-storage/index/mbox/mbox-file.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-file.c Mon Jun 15 14:28:55 2009 -0400 @@ -23,10 +23,11 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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;
--- a/src/lib-storage/index/mbox/mbox-lock.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-lock.c Mon Jun 15 14:28:55 2009 -0400 @@ -174,7 +174,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); } }
--- a/src/lib-storage/index/mbox/mbox-mail.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-mail.c Mon Jun 15 14:28:55 2009 -0400 @@ -100,7 +100,7 @@ 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 @@ 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)
--- a/src/lib-storage/index/mbox/mbox-save.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-save.c Mon Jun 15 14:28:55 2009 -0400 @@ -734,7 +734,7 @@ 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()"); }
--- a/src/lib-storage/index/mbox/mbox-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -83,7 +83,7 @@ } 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 @@ 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 @@ 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; - - 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; + struct mailbox *box = &mbox->ibox.box; + const char *rootdir; - 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; + if (access(box->path, R_OK|W_OK) < 0) { + if (errno != EACCES) { + mbox_set_syscall_error(mbox, "access()"); + return -1; + } + mbox->ibox.backend_readonly = TRUE; + } + mbox->ibox.move_to_memory = + want_memory_indexes(mbox->storage, box->path); - 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) - mbox_set_syscall_error(mbox, "access()"); - else - mbox->ibox.backend_readonly = TRUE; - } - - 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_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 (strcmp(name, "INBOX") == 0 && - (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); + if (box->input != NULL) { + mbox->mbox_file_stream = box->input; + mbox->ibox.backend_readonly = TRUE; + mbox->no_mbox_file = TRUE; + return 0; } - 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 (strcmp(box->name, "INBOX") == 0 && + (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) { + /* make sure INBOX exists */ + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,
--- a/src/lib-storage/index/mbox/mbox-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -34,8 +34,6 @@ 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;
--- a/src/lib-storage/index/mbox/mbox-sync-rewrite.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-sync-rewrite.c Mon Jun 15 14:28:55 2009 -0400 @@ -44,8 +44,8 @@ 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 @@ 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); } }
--- a/src/lib-storage/index/mbox/mbox-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -72,12 +72,15 @@ 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 @@ { 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;
--- a/src/lib-storage/index/raw/raw-mail.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/raw/raw-mail.c Mon Jun 15 14:28:55 2009 -0400 @@ -19,10 +19,10 @@ 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 @@ 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 @@ *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);
--- a/src/lib-storage/index/raw/raw-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/raw/raw-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -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 @@ 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 @@ raw_storage_add_list, raw_storage_get_list_settings, NULL, - raw_mailbox_open, + raw_mailbox_alloc, raw_mailbox_create, NULL } @@ -222,7 +199,8 @@ 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,
--- a/src/lib-storage/index/raw/raw-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/raw/raw-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -16,9 +16,6 @@ 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;
--- a/src/lib-storage/index/raw/raw-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/index/raw/raw-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -52,10 +52,12 @@ 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);
--- a/src/lib-storage/list/index-mailbox-list-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/list/index-mailbox-list-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -47,11 +47,11 @@ 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 @@ 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(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; }
--- a/src/lib-storage/mail-storage-private.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/mail-storage-private.h Mon Jun 15 14:28:55 2009 -0400 @@ -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 @@ 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 @@ 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 @@ }; struct mailbox { - char *name; + const char *name; struct mail_storage *storage; struct mailbox_list *list; @@ -220,7 +221,10 @@ /* 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;
--- a/src/lib-storage/mail-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/mail-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -24,7 +24,7 @@ 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 @@ 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; - - mailbox_list_clear_error(list); - - if (!mailbox_list_is_valid_existing_name(new_list, name)) { - mailbox_list_set_error(list, MAIL_ERROR_PARAMS, - "Invalid mailbox name"); - 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_open(storage, new_list, - name, input, flags); - if (hook_mailbox_opened != NULL && box != NULL) - hook_mailbox_opened(box); + box = storage->v.mailbox_alloc(storage, new_list, + name, input, flags); + if (hook_mailbox_allocated != NULL) + hook_mailbox_allocated(box); + } T_END; + return box; +} + +int mailbox_open(struct mailbox *box) +{ + int ret; + + 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 -1; + } + + T_BEGIN { + 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 @@ return box->enabled_features; } -int mailbox_close(struct mailbox **_box) +void mailbox_close(struct mailbox **_box) { struct mailbox *box = *_box; @@ -521,7 +528,7 @@ } *_box = NULL; - return box->v.close(box); + box->v.close(box); } struct mail_storage *mailbox_get_storage(const struct mailbox *box)
--- a/src/lib-storage/mail-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/mail-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -23,28 +23,25 @@ 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 @@ /* 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);
--- a/src/lib-storage/mailbox-list-private.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/mailbox-list-private.h Mon Jun 15 14:28:55 2009 -0400 @@ -149,7 +149,5 @@ 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
--- a/src/lib-storage/mailbox-list.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/mailbox-list.c Mon Jun 15 14:28:55 2009 -0400 @@ -321,6 +321,13 @@ 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 @@ 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); -}
--- a/src/lib-storage/test-mail-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/test-mail-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -55,7 +55,7 @@ NULL, test_storage_get_list_settings, NULL, - test_mailbox_open, + test_mailbox_alloc, test_mailbox_create, NULL }
--- a/src/lib-storage/test-mail-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/test-mail-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -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,
--- a/src/lib-storage/test-mailbox.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lib-storage/test-mailbox.c Mon Jun 15 14:28:55 2009 -0400 @@ -24,11 +24,15 @@ 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 @@ 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_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 @@ 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);
--- a/src/lmtp/commands.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/lmtp/commands.c Mon Jun 15 14:28:55 2009 -0400 @@ -290,18 +290,14 @@ 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; }
--- a/src/plugins/acl/acl-mailbox.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/acl/acl-mailbox.c Mon Jun 15 14:28:55 2009 -0400 @@ -65,7 +65,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;
--- a/src/plugins/acl/acl-plugin.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/acl/acl-plugin.h Mon Jun 15 14:28:55 2009 -0400 @@ -46,7 +46,10 @@ 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,
--- a/src/plugins/acl/acl-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/acl/acl-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -16,51 +16,6 @@ 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 @@ 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);
--- a/src/plugins/convert/convert-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/convert/convert-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -29,13 +29,6 @@ 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 @@ /* 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 @@ } } - 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; }
--- a/src/plugins/expire/expire-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/expire/expire-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -43,7 +43,7 @@ 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 @@ 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 @@ 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_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; }
--- a/src/plugins/expire/expire-tool.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/expire/expire-tool.c Mon Jun 15 14:28:55 2009 -0400 @@ -80,9 +80,11 @@ 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);
--- a/src/plugins/fts/fts-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/fts/fts-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -12,11 +12,11 @@ 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; }
--- a/src/plugins/fts/fts-plugin.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/fts/fts-plugin.h Mon Jun 15 14:28:55 2009 -0400 @@ -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);
--- a/src/plugins/fts/fts-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/fts/fts-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -58,19 +58,17 @@ &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 @@ 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 @@ 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); }
--- a/src/plugins/imap-acl/imap-acl-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/imap-acl/imap-acl-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -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 @@ /* 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 @@ 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);
--- a/src/plugins/imap-quota/imap-quota-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -84,26 +84,19 @@ 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 ");
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -48,10 +48,6 @@ 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 @@ 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 @@ 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ { 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; }
--- a/src/plugins/listescape/listescape-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/listescape/listescape-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -163,9 +163,10 @@ } 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 @@ 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 @@ 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);
--- a/src/plugins/mail-log/mail-log-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/mail-log/mail-log-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -555,17 +555,15 @@ } 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 @@ 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);
--- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/mbox-snarf/mbox-snarf-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -113,31 +113,30 @@ /* 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 @@ } 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 @@ 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); }
--- a/src/plugins/quota/quota-count.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/quota/quota-count.c Mon Jun 15 14:28:55 2009 -0400 @@ -27,10 +27,11 @@ 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. */
--- a/src/plugins/quota/quota-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/quota/quota-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -341,7 +341,7 @@ 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 @@ 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 @@ 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 @@ 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);
--- a/src/plugins/trash/trash-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/trash/trash-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -54,10 +54,12 @@ { 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;
--- a/src/plugins/virtual/virtual-config.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/virtual/virtual-config.c Mon Jun 15 14:28:55 2009 -0400 @@ -323,7 +323,7 @@ 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) {
--- a/src/plugins/virtual/virtual-storage.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/virtual/virtual-storage.c Mon Jun 15 14:28:55 2009 -0400 @@ -118,26 +118,27 @@ } 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 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ virtual_storage_add_list, virtual_storage_get_list_settings, NULL, - virtual_mailbox_open, + virtual_mailbox_alloc, virtual_mailbox_create, NULL } @@ -593,7 +572,8 @@ 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,
--- a/src/plugins/virtual/virtual-storage.h Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/virtual/virtual-storage.h Mon Jun 15 14:28:55 2009 -0400 @@ -102,7 +102,6 @@ struct index_mailbox ibox; struct virtual_storage *storage; - const char *path; uint32_t virtual_ext_id; uint32_t prev_uid_validity;
--- a/src/plugins/virtual/virtual-sync.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/virtual/virtual-sync.c Mon Jun 15 14:28:55 2009 -0400 @@ -169,7 +169,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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);
--- a/src/plugins/zlib/zlib-plugin.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/plugins/zlib/zlib-plugin.c Mon Jun 15 14:28:55 2009 -0400 @@ -203,9 +203,9 @@ } 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_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 @@ 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);
--- a/src/pop3/pop3-client.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/pop3/pop3-client.c Mon Jun 15 14:28:55 2009 -0400 @@ -221,7 +221,7 @@ 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 @@ } 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)) {
--- a/src/util/doveadm.c Fri Jun 12 12:52:38 2009 -0400 +++ b/src/util/doveadm.c Mon Jun 15 14:28:55 2009 -0400 @@ -58,11 +58,12 @@ 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; }