]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Moved some items from mailbox_get_status() to a new mailbox_get_metadata().
authorTimo Sirainen <tss@iki.fi>
Sat, 1 Jan 2011 13:52:39 +0000 (15:52 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 1 Jan 2011 13:52:39 +0000 (15:52 +0200)
The idea is now that all status items are tracked all the time after mailbox
is opened and they can always be looked up without failure. The metadata
items are looked up lazily and the lookups may fail at any time.

mailbox_get_status() can be used after mailbox_alloc() to indicate that the
mailbox doesn't necessarily have to be opened, just that the status fields
get returned.

If mailbox is already known to be open, mailbox_get_open_status() can be
used. It never fails.

36 files changed:
src/doveadm/doveadm-mail-fetch.c
src/doveadm/doveadm-mail-mailbox-status.c
src/doveadm/doveadm-mail-search.c
src/doveadm/doveadm-mail.c
src/doveadm/doveadm-mail.h
src/dsync/dsync-worker-local.c
src/imap/cmd-enable.c
src/imap/cmd-select.c
src/imap/cmd-store.c
src/imap/imap-client.c
src/imap/imap-client.h
src/imap/imap-commands-util.c
src/imap/imap-fetch.c
src/imap/imap-search.c
src/imap/imap-status.c
src/imap/imap-status.h
src/imap/imap-sync.c
src/lib-storage/index/dbox-multi/mdbox-storage.c
src/lib-storage/index/dbox-single/sdbox-storage.c
src/lib-storage/index/index-search.c
src/lib-storage/index/index-status.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/list/index-mailbox-list-sync.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h
src/plugins/fts-solr/fts-backend-solr.c
src/plugins/fts-squat/fts-backend-squat.c
src/plugins/fts/fts-storage.c
src/plugins/virtual/virtual-save.c
src/plugins/virtual/virtual-storage.c
src/plugins/virtual/virtual-sync.c
src/pop3/pop3-client.c

index 4cb61d6e938a853b19fb2859e37dbe3954f5d147..fd8fe171a2e1de6b7f9a544514aa3172feae5fc5 100644 (file)
@@ -63,11 +63,12 @@ static int fetch_mailbox(struct fetch_cmd_context *ctx)
 
 static int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
 {
-       uint8_t guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
 
-       if (mailbox_get_guid(ctx->mail->box, guid) < 0)
+       if (mailbox_get_metadata(ctx->mail->box, MAILBOX_METADATA_GUID,
+                                &metadata) < 0)
                return -1;
-       doveadm_print(mail_guid_128_to_string(guid));
+       doveadm_print(mail_guid_128_to_string(metadata.guid));
        return 0;
 }
 
index 86587f250cfe60a40525c4c70e5f47fb9bcd5d1c..8a5fa6b04586701b2bd35e7bfd41d60a064e242e 100644 (file)
 #define ALL_STATUS_ITEMS \
        (STATUS_MESSAGES | STATUS_RECENT | \
         STATUS_UIDNEXT | STATUS_UIDVALIDITY | \
-        STATUS_UNSEEN | STATUS_HIGHESTMODSEQ | STATUS_VIRTUAL_SIZE)
+        STATUS_UNSEEN | STATUS_HIGHESTMODSEQ)
+#define ALL_METADATA_ITEMS \
+       (MAILBOX_METADATA_VIRTUAL_SIZE | MAILBOX_METADATA_GUID)
 
 #define TOTAL_STATUS_ITEMS \
-       (STATUS_MESSAGES | STATUS_RECENT | STATUS_UNSEEN | STATUS_VIRTUAL_SIZE)
+       (STATUS_MESSAGES | STATUS_RECENT | STATUS_UNSEEN)
+#define TOTAL_METADATA_ITEMS \
+       (MAILBOX_METADATA_VIRTUAL_SIZE)
 
 struct status_cmd_context {
        struct doveadm_mail_cmd_context ctx;
        struct mail_search_args *search_args;
-       enum mailbox_status_items items;
+
+       enum mailbox_status_items status_items;
+       enum mailbox_metadata_items metadata_items;
        struct mailbox_status total_status;
+       struct mailbox_metadata total_metadata;
 
-       unsigned int guid:1;
        unsigned int total_sum:1;
 };
 
@@ -37,40 +43,42 @@ static void status_parse_fields(struct status_cmd_context *ctx,
                const char *field = *fields;
 
                if (strcmp(field, "all") == 0) {
-                       if (ctx->total_sum)
-                               ctx->items |= TOTAL_STATUS_ITEMS;
-                       else {
-                               ctx->items |= ALL_STATUS_ITEMS;
-                               ctx->guid = TRUE;
+                       if (ctx->total_sum) {
+                               ctx->status_items |= TOTAL_STATUS_ITEMS;
+                               ctx->metadata_items |= TOTAL_METADATA_ITEMS;
+                       } else {
+                               ctx->status_items |= ALL_STATUS_ITEMS;
+                               ctx->metadata_items |= ALL_METADATA_ITEMS;
                        }
                } else if (strcmp(field, "messages") == 0)
-                       ctx->items |= STATUS_MESSAGES;
+                       ctx->status_items |= STATUS_MESSAGES;
                else if (strcmp(field, "recent") == 0)
-                       ctx->items |= STATUS_RECENT;
+                       ctx->status_items |= STATUS_RECENT;
                else if (strcmp(field, "uidnext") == 0)
-                       ctx->items |= STATUS_UIDNEXT;
+                       ctx->status_items |= STATUS_UIDNEXT;
                else if (strcmp(field, "uidvalidity") == 0)
-                       ctx->items |= STATUS_UIDVALIDITY;
+                       ctx->status_items |= STATUS_UIDVALIDITY;
                else if (strcmp(field, "unseen") == 0)
-                       ctx->items |= STATUS_UNSEEN;
+                       ctx->status_items |= STATUS_UNSEEN;
                else if (strcmp(field, "highestmodseq") == 0)
-                       ctx->items |= STATUS_HIGHESTMODSEQ;
+                       ctx->status_items |= STATUS_HIGHESTMODSEQ;
                else if (strcmp(field, "vsize") == 0)
-                       ctx->items |= STATUS_VIRTUAL_SIZE;
+                       ctx->metadata_items |= MAILBOX_METADATA_VIRTUAL_SIZE;
                else if (strcmp(field, "guid") == 0)
-                       ctx->guid = TRUE;
+                       ctx->metadata_items |= MAILBOX_METADATA_GUID;
                else
                        i_fatal("Unknown status field: %s", field);
 
                if (ctx->total_sum &&
-                   ((ctx->items & ~TOTAL_STATUS_ITEMS) != 0 || ctx->guid))
+                   ((ctx->status_items & ~TOTAL_STATUS_ITEMS) != 0 ||
+                    (ctx->metadata_items & ~TOTAL_METADATA_ITEMS) != 0))
                        i_fatal("Status field %s can't be used with -t", field);
        }
 }
 
 static void status_output(struct status_cmd_context *ctx, struct mailbox *box,
                          const struct mailbox_status *status,
-                         uint8_t mailbox_guid[MAIL_GUID_128_SIZE])
+                         const struct mailbox_metadata *metadata)
 {
        string_t *name;
 
@@ -83,34 +91,35 @@ static void status_output(struct status_cmd_context *ctx, struct mailbox *box,
                doveadm_print(str_c(name));
        }
 
-       if ((ctx->items & STATUS_MESSAGES) != 0)
+       if ((ctx->status_items & STATUS_MESSAGES) != 0)
                doveadm_print_num(status->messages);
-       if ((ctx->items & STATUS_RECENT) != 0)
+       if ((ctx->status_items & STATUS_RECENT) != 0)
                doveadm_print_num(status->recent);
-       if ((ctx->items & STATUS_UIDNEXT) != 0)
+       if ((ctx->status_items & STATUS_UIDNEXT) != 0)
                doveadm_print_num(status->uidnext);
-       if ((ctx->items & STATUS_UIDVALIDITY) != 0)
+       if ((ctx->status_items & STATUS_UIDVALIDITY) != 0)
                doveadm_print_num(status->uidvalidity);
-       if ((ctx->items & STATUS_UNSEEN) != 0)
+       if ((ctx->status_items & STATUS_UNSEEN) != 0)
                doveadm_print_num(status->unseen);
-       if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0)
+       if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0)
                doveadm_print_num(status->highest_modseq);
-       if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0)
-               doveadm_print_num(status->virtual_size);
-       if (ctx->guid)
-               doveadm_print(mail_guid_128_to_string(mailbox_guid));
+       if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0)
+               doveadm_print_num(metadata->virtual_size);
+       if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0)
+               doveadm_print(mail_guid_128_to_string(metadata->guid));
 }
 
 static void
 status_sum(struct status_cmd_context *ctx,
-          const struct mailbox_status *status)
+          const struct mailbox_status *status,
+          const struct mailbox_metadata *metadata)
 {
        struct mailbox_status *dest = &ctx->total_status;
 
        dest->messages += status->messages;
        dest->recent += status->recent;
        dest->unseen += status->unseen;
-       dest->virtual_size += status->virtual_size;
+       ctx->total_metadata.virtual_size += metadata->virtual_size;
 }
 
 static void
@@ -118,7 +127,7 @@ status_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info)
 {
        struct mailbox *box;
        struct mailbox_status status;
-       uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
        string_t *mailbox_name = t_str_new(128);
 
        if (imap_utf7_to_utf8(info->name, mailbox_name) < 0) {
@@ -126,20 +135,17 @@ status_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info)
                str_append(mailbox_name, info->name);
        }
 
-       if (doveadm_mailbox_find_and_sync(ctx->ctx.cur_mail_user,
-                                         str_c(mailbox_name), &box) < 0 ||
-          mailbox_get_status(box, ctx->items, &status) < 0) {
+       box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, str_c(mailbox_name));
+       if (mailbox_get_status(box, ctx->status_items, &status) < 0 ||
+           mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) {
                ctx->ctx.failed = TRUE;
+               mailbox_free(&box);
                return;
        }
-       if (ctx->guid) {
-               if (mailbox_get_guid(box, mailbox_guid) < 0)
-                       memset(mailbox_guid, 0, sizeof(mailbox_guid));
-       }
        if (!ctx->total_sum)
-               status_output(ctx, box, &status, mailbox_guid);
+               status_output(ctx, box, &status, &metadata);
        else
-               status_sum(ctx, &status);
+               status_sum(ctx, &status, &metadata);
        mailbox_free(&box);
 }
 
@@ -165,8 +171,10 @@ cmd_mailbox_status_run(struct doveadm_mail_cmd_context *_ctx,
        }
        doveadm_mail_list_iter_deinit(&iter);
 
-       if (ctx->total_sum)
-               status_output(ctx, NULL, &ctx->total_status, NULL);
+       if (ctx->total_sum) {
+               status_output(ctx, NULL, &ctx->total_status,
+                             &ctx->total_metadata);
+       }
 }
 
 static void cmd_mailbox_status_init(struct doveadm_mail_cmd_context *_ctx,
@@ -185,21 +193,21 @@ static void cmd_mailbox_status_init(struct doveadm_mail_cmd_context *_ctx,
                doveadm_print_header("mailbox", "mailbox",
                                     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
        }
-       if ((ctx->items & STATUS_MESSAGES) != 0)
+       if ((ctx->status_items & STATUS_MESSAGES) != 0)
                doveadm_print_header_simple("messages");
-       if ((ctx->items & STATUS_RECENT) != 0)
+       if ((ctx->status_items & STATUS_RECENT) != 0)
                doveadm_print_header_simple("recent");
-       if ((ctx->items & STATUS_UIDNEXT) != 0)
+       if ((ctx->status_items & STATUS_UIDNEXT) != 0)
                doveadm_print_header_simple("uidnext");
-       if ((ctx->items & STATUS_UIDVALIDITY) != 0)
+       if ((ctx->status_items & STATUS_UIDVALIDITY) != 0)
                doveadm_print_header_simple("uidvalidity");
-       if ((ctx->items & STATUS_UNSEEN) != 0)
+       if ((ctx->status_items & STATUS_UNSEEN) != 0)
                doveadm_print_header_simple("unseen");
-       if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0)
+       if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0)
                doveadm_print_header_simple("highestmodseq");
-       if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0)
+       if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0)
                doveadm_print_header_simple("vsize");
-       if (ctx->guid)
+       if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0)
                doveadm_print_header_simple("guid");
 }
 
index c9709c089c85edfcaeb92c45d47c6332f9833a25..0c77439178a05d86f6117102242efc9955ccc9ef 100644 (file)
@@ -16,7 +16,7 @@ cmd_search_box(struct doveadm_mail_cmd_context *ctx,
        struct doveadm_mail_iter *iter;
        struct mailbox_transaction_context *trans;
        struct mail *mail;
-       uint8_t guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
        const char *guid_str;
        int ret = 0;
 
@@ -24,10 +24,12 @@ cmd_search_box(struct doveadm_mail_cmd_context *ctx,
                return -1;
 
        mail = mail_alloc(trans, 0, NULL);
-       if (mailbox_get_guid(mail->box, guid) < 0)
+
+       if (mailbox_get_metadata(mail->box, MAILBOX_METADATA_GUID,
+                                &metadata) < 0)
                ret = -1;
        else {
-               guid_str = mail_guid_128_to_string(guid);
+               guid_str = mail_guid_128_to_string(metadata.guid);
                while (doveadm_mail_iter_next(iter, mail)) {
                        doveadm_print(guid_str);
                        T_BEGIN {
index 3d51c50fafe18bcc9dc8402b7fce91c0c8d827cf..53a6d442b713e26635989d828798e719458a50d9 100644 (file)
@@ -71,13 +71,11 @@ static struct doveadm_mail_cmd_context *cmd_purge_alloc(void)
        return ctx;
 }
 
-static int mailbox_find_and_open(struct mail_user *user, const char *mailbox,
-                                struct mailbox **box_r)
+struct mailbox *
+doveadm_mailbox_find(struct mail_user *user, const char *mailbox)
 {
        struct mail_namespace *ns;
-       struct mailbox *box;
        string_t *str;
-       const char *orig_mailbox = mailbox;
 
        str = t_str_new(128);
        if (imap_utf8_to_utf7(mailbox, str) < 0)
@@ -88,10 +86,19 @@ static int mailbox_find_and_open(struct mail_user *user, const char *mailbox,
        if (ns == NULL)
                i_fatal("Can't find namespace for mailbox %s", mailbox);
 
-       box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT |
-                           MAILBOX_FLAG_IGNORE_ACLS);
+       return mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT |
+                            MAILBOX_FLAG_IGNORE_ACLS);
+}
+
+static int
+doveadm_mailbox_find_and_open(struct mail_user *user, const char *mailbox,
+                             struct mailbox **box_r)
+{
+       struct mailbox *box;
+
+       box = doveadm_mailbox_find(user, mailbox);
        if (mailbox_open(box) < 0) {
-               i_error("Opening mailbox %s failed: %s", orig_mailbox,
+               i_error("Opening mailbox %s failed: %s", mailbox,
                        mail_storage_get_last_error(mailbox_get_storage(box),
                                                    NULL));
                mailbox_free(&box);
@@ -104,12 +111,13 @@ static int mailbox_find_and_open(struct mail_user *user, const char *mailbox,
 int doveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox,
                                  struct mailbox **box_r)
 {
-       if (mailbox_find_and_open(user, mailbox, box_r) < 0)
+       if (doveadm_mailbox_find_and_open(user, mailbox, box_r) < 0)
                return -1;
        if (mailbox_sync(*box_r, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
                i_error("Syncing mailbox %s failed: %s", mailbox,
                        mail_storage_get_last_error(mailbox_get_storage(*box_r),
                                                    NULL));
+               mailbox_free(box_r);
                return -1;
        }
        return 0;
@@ -143,7 +151,7 @@ static void cmd_force_resync_run(struct doveadm_mail_cmd_context *_ctx,
        struct mail_storage *storage;
        struct mailbox *box;
 
-       if (mailbox_find_and_open(user, ctx->mailbox, &box) < 0) {
+       if (doveadm_mailbox_find_and_open(user, ctx->mailbox, &box) < 0) {
                _ctx->failed = TRUE;
                return;
        }
index df113f41af1bbab2d966594489dc6046a2738735..4a8d4a1a1c057398836677c571890c0d302341c0 100644 (file)
@@ -89,6 +89,8 @@ int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
                             const char **error_r);
 void doveadm_mail_server_flush(void);
 
+struct mailbox *
+doveadm_mailbox_find(struct mail_user *user, const char *mailbox);
 int doveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox,
                                  struct mailbox **box_r);
 struct mail_search_args *
index b01f47a4ffd5825618f23a793e3d56fd94ca888a..a434156e48dce3f84926099028d6327ee66097b4 100644 (file)
@@ -514,12 +514,14 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
                MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT;
        const enum mailbox_status_items status_items =
                STATUS_UIDNEXT | STATUS_UIDVALIDITY |
-               STATUS_HIGHESTMODSEQ | STATUS_CACHE_FIELDS;
+               STATUS_HIGHESTMODSEQ;
+       const enum mailbox_metadata_items metadata_items =
+               MAILBOX_METADATA_CACHE_FIELDS | MAILBOX_METADATA_GUID;
        const struct mailbox_info *info;
        const char *storage_name;
        struct mailbox *box;
        struct mailbox_status status;
-       uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
        struct local_dsync_mailbox_change *change;
        struct local_dsync_dir_change *dir_change, change_lookup;
        struct local_dsync_mailbox *old_lbox;
@@ -557,9 +559,8 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
        }
 
        box = mailbox_alloc(info->ns->list, storage_name, flags);
-       if (mailbox_sync(box, 0) < 0 ||
-           mailbox_get_status(box, status_items, &status) < 0 ||
-           mailbox_get_guid(box, mailbox_guid) < 0) {
+       if (mailbox_get_status(box, status_items, &status) < 0 ||
+           mailbox_get_metadata(box, metadata_items, &metadata) < 0) {
                struct mail_storage *storage = mailbox_get_storage(box);
 
                i_error("Failed to sync mailbox %s: %s", info->name,
@@ -569,13 +570,13 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
                return -1;
        }
 
-       change = hash_table_lookup(worker->mailbox_changes_hash, mailbox_guid);
+       change = hash_table_lookup(worker->mailbox_changes_hash, metadata.guid);
        if (change != NULL) {
                /* it shouldn't be marked as deleted, but drop it to be sure */
                change->deleted_mailbox = FALSE;
        }
 
-       memcpy(dsync_box_r->mailbox_guid.guid, mailbox_guid,
+       memcpy(dsync_box_r->mailbox_guid.guid, metadata.guid,
               sizeof(dsync_box_r->mailbox_guid.guid));
        dsync_box_r->uid_validity = status.uidvalidity;
        dsync_box_r->uid_next = status.uidnext;
@@ -583,7 +584,7 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
        dsync_box_r->highest_modseq = status.highest_modseq;
 
        p_clear(iter->ret_pool);
-       fields = array_get(status.cache_fields, &field_count);
+       fields = array_get(metadata.cache_fields, &field_count);
        p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, field_count);
        for (i = 0; i < field_count; i++) {
                const char *field_name = p_strdup(iter->ret_pool, fields[i]);
@@ -788,7 +789,7 @@ static int local_mailbox_open(struct local_dsync_worker *worker,
        enum mailbox_flags flags = MAILBOX_FLAG_KEEP_RECENT;
        struct local_dsync_mailbox *lbox;
        struct mailbox *box;
-       uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
 
        lbox = hash_table_lookup(worker->mailbox_hash, guid);
        if (lbox == NULL) {
@@ -799,7 +800,7 @@ static int local_mailbox_open(struct local_dsync_worker *worker,
 
        box = mailbox_alloc(lbox->ns->list, lbox->storage_name, flags);
        if (mailbox_sync(box, 0) < 0 ||
-           mailbox_get_guid(box, mailbox_guid) < 0) {
+           mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
                struct mail_storage *storage = mailbox_get_storage(box);
 
                i_error("Failed to sync mailbox %s: %s", lbox->storage_name,
@@ -808,10 +809,10 @@ static int local_mailbox_open(struct local_dsync_worker *worker,
                return -1;
        }
 
-       if (memcmp(mailbox_guid, guid->guid, sizeof(guid->guid)) != 0) {
+       if (memcmp(metadata.guid, guid->guid, sizeof(guid->guid)) != 0) {
                i_error("Mailbox %s changed its GUID (%s -> %s)",
                        lbox->storage_name, dsync_guid_to_str(guid),
-                       mail_guid_128_to_string(mailbox_guid));
+                       mail_guid_128_to_string(metadata.guid));
                mailbox_free(&box);
                return -1;
        }
@@ -936,8 +937,7 @@ iter_local_mailbox_next_expunge(struct local_dsync_worker_msg_iter *iter,
        array_clear(&iter->expunges);
        iter->expunges_set = TRUE;
 
-       if (mailbox_get_status(box, STATUS_UIDNEXT, &status) < 0)
-               i_unreached();
+       mailbox_get_open_status(box, STATUS_UIDNEXT, &status);
        if (prev_uid + 1 >= status.uidnext) {
                /* no expunged messages at the end of mailbox */
                return FALSE;
index 778a6e96ce4cc4285dfa4ab8ab6830955aca7f31..dbe57bed50ac021d5a1a40b0c20eef3d594994ff 100644 (file)
@@ -21,13 +21,13 @@ bool cmd_enable(struct client_command_context *cmd)
                }
                str = t_str_ucase(str);
                if (strcmp(str, "CONDSTORE") == 0) {
-                       client_enable(cmd->client, MAILBOX_FEATURE_CONDSTORE);
-                       str_append(reply, " CONDSTORE");
-               }
-               else if (strcmp(str, "QRESYNC") == 0) {
-                       client_enable(cmd->client, MAILBOX_FEATURE_QRESYNC |
-                                     MAILBOX_FEATURE_CONDSTORE);
-                       str_append(reply, " QRESYNC");
+                       if (client_enable(cmd->client,
+                                         MAILBOX_FEATURE_CONDSTORE) == 0)
+                               str_append(reply, " CONDSTORE");
+               else if (strcmp(str, "QRESYNC") == 0) {
+                       if (client_enable(cmd->client, MAILBOX_FEATURE_QRESYNC |
+                                         MAILBOX_FEATURE_CONDSTORE) == 0)
+                               str_append(reply, " QRESYNC");
                }
        }
        if (str_len(reply) > 9)
index e588647a52d6798da0cf97aade30e403ff48d4e1..6294b219384fef9e6d62c4876cbd35278b3f6d60 100644 (file)
@@ -276,7 +276,7 @@ select_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
        struct client *client = ctx->cmd->client;
        struct mailbox_status status;
        enum mailbox_flags flags = 0;
-       int ret;
+       int ret = 0;
 
        if (readonly)
                flags |= MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT;
@@ -289,20 +289,17 @@ select_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
        }
 
        if (client->enabled_features != 0)
-               mailbox_enable(ctx->box, client->enabled_features);
-       if (mailbox_sync(ctx->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
-               client_send_storage_error(ctx->cmd,
-                                         mailbox_get_storage(ctx->box));
-               return -1;
-       }
-       if (mailbox_get_status(ctx->box, STATUS_MESSAGES | STATUS_RECENT |
-                              STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY |
-                              STATUS_UIDNEXT | STATUS_KEYWORDS |
-                              STATUS_HIGHESTMODSEQ, &status) < 0) {
+               ret = mailbox_enable(ctx->box, client->enabled_features);
+       if (ret < 0 ||
+           mailbox_sync(ctx->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
                client_send_storage_error(ctx->cmd,
                                          mailbox_get_storage(ctx->box));
                return -1;
        }
+       mailbox_get_open_status(ctx->box, STATUS_MESSAGES | STATUS_RECENT |
+                               STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY |
+                               STATUS_UIDNEXT | STATUS_KEYWORDS |
+                               STATUS_HIGHESTMODSEQ, &status);
 
        client->mailbox = ctx->box;
        client->select_counter++;
@@ -413,7 +410,7 @@ bool cmd_select_full(struct client_command_context *cmd, bool readonly)
        if (ctx->condstore) {
                /* Enable while no mailbox is opened to avoid sending
                   HIGHESTMODSEQ for previously opened mailbox */
-               client_enable(client, MAILBOX_FEATURE_CONDSTORE);
+               (void)client_enable(client, MAILBOX_FEATURE_CONDSTORE);
        }
 
        ret = select_open(ctx, storage_name, readonly);
index ff53ac400ac5733733a61b1e010943f4a96f9c22..1bab792bda6dabce8c2efd98a17da97528afbd43 100644 (file)
@@ -62,8 +62,8 @@ store_parse_modifiers(struct imap_store_context *ctx,
                                                          "Invalid modseq");
                                return FALSE;
                        }
-                       client_enable(ctx->cmd->client,
-                                     MAILBOX_FEATURE_CONDSTORE);
+                       (void)client_enable(ctx->cmd->client,
+                                           MAILBOX_FEATURE_CONDSTORE);
                } else {
                        client_send_command_error(ctx->cmd,
                                                  "Unknown STORE modifier");
index 954b5026756c60dda507f20f6b244efa0c1c8d5d..5b32ad23673dc3cfefee3bcb7fbc096ec9080706 100644 (file)
@@ -911,28 +911,35 @@ bool client_handle_search_save_ambiguity(struct client_command_context *cmd)
        return TRUE;
 }
 
-void client_enable(struct client *client, enum mailbox_feature features)
+int client_enable(struct client *client, enum mailbox_feature features)
 {
        struct mailbox_status status;
+       int ret;
 
        if ((client->enabled_features & features) == features)
-               return;
+               return 0;
 
        client->enabled_features |= features;
        if (client->mailbox == NULL)
-               return;
+               return 0;
 
-       mailbox_enable(client->mailbox, features);
-       if ((features & MAILBOX_FEATURE_CONDSTORE) != 0) {
+       ret = mailbox_enable(client->mailbox, features);
+       if ((features & MAILBOX_FEATURE_CONDSTORE) != 0 && ret == 0) {
                /* CONDSTORE being enabled while mailbox is selected.
                   Notify client of the latest HIGHESTMODSEQ. */
-               if (mailbox_get_status(client->mailbox,
-                                      STATUS_HIGHESTMODSEQ, &status) < 0)
-                       i_unreached();
-               client_send_line(client, t_strdup_printf(
-                       "* OK [HIGHESTMODSEQ %llu] Highest",
-                       (unsigned long long)status.highest_modseq));
+               ret = mailbox_get_status(client->mailbox,
+                                        STATUS_HIGHESTMODSEQ, &status);
+               if (ret == 0) {
+                       client_send_line(client, t_strdup_printf(
+                               "* OK [HIGHESTMODSEQ %llu] Highest",
+                               (unsigned long long)status.highest_modseq));
+               }
+       }
+       if (ret < 0) {
+               client_send_untagged_storage_error(client,
+                       mailbox_get_storage(client->mailbox));
        }
+       return ret;
 }
 
 struct imap_search_update *
index 57fc7470556f92a9a3894ce199dc7b500c0c970d..e6b44cc65d995089cf2d79978db3f3d7f75baf3f 100644 (file)
@@ -192,7 +192,7 @@ bool client_read_string_args(struct client_command_context *cmd,
    have to wait for an existing SEARCH SAVE to finish. */
 bool client_handle_search_save_ambiguity(struct client_command_context *cmd);
 
-void client_enable(struct client *client, enum mailbox_feature features);
+int client_enable(struct client *client, enum mailbox_feature features);
 
 struct imap_search_update *
 client_search_update_lookup(struct client *client, const char *tag,
index 658ab66517575681380f23a71175852e2dbe5b3c..fd148e937e1247698c447af633f95838f2e56c0d 100644 (file)
@@ -102,8 +102,13 @@ int client_open_save_dest_box(struct client_command_context *cmd,
                mailbox_free(&box);
                return -1;
        }
-       if (cmd->client->enabled_features != 0)
-               mailbox_enable(box, cmd->client->enabled_features);
+       if (cmd->client->enabled_features != 0) {
+               if (mailbox_enable(box, cmd->client->enabled_features) < 0) {
+                       client_send_storage_error(cmd, mailbox_get_storage(box));
+                       mailbox_free(&box);
+                       return -1;
+               }
+       }
        *destbox_r = box;
        return 0;
 }
index f20cd49a945b7f2ea798789a25c29a1591bcfa2e..ded6969c5a0a4900e925bd7a6baf1f5015d8d6fa 100644 (file)
@@ -159,7 +159,7 @@ expunges_drop_known(struct imap_fetch_context *ctx, struct mail *mail,
        i_assert(array_count(ctx->qresync_sample_uidset) == count);
        i_assert(count > 0);
 
-       mailbox_get_status(ctx->box, STATUS_MESSAGES, &status);
+       mailbox_get_open_status(ctx->box, STATUS_MESSAGES, &status);
 
        /* FIXME: we could do removals from the middle as well */
        for (i = 0; i < count && seqs[i] <= status.messages; i++) {
@@ -245,7 +245,7 @@ static int get_expunges_fallback(struct imap_fetch_context *ctx,
                                          uid_filter[i].seq2);
        }
 
-       mailbox_get_status(ctx->box, STATUS_UIDNEXT, &status);
+       mailbox_get_open_status(ctx->box, STATUS_UIDNEXT, &status);
        seq_range_array_remove_range(expunged_uids, status.uidnext,
                                     (uint32_t)-1);
 
@@ -751,7 +751,7 @@ static bool
 fetch_modseq_init(struct imap_fetch_context *ctx, const char *name,
                  const struct imap_arg **args ATTR_UNUSED)
 {
-       client_enable(ctx->client, MAILBOX_FEATURE_CONDSTORE);
+       (void)client_enable(ctx->client, MAILBOX_FEATURE_CONDSTORE);
        imap_fetch_add_handler(ctx, TRUE, FALSE, name, NULL,
                               fetch_modseq, NULL);
        return TRUE;
index 6c6b842fe50288d640dd9730fa0e7a99a9996e10..5f96e19f39c053a122ba18dbb9d32b8e2e7b83a0 100644 (file)
@@ -527,7 +527,7 @@ bool imap_search_start(struct imap_search_context *ctx,
 
        if (ctx->have_modseqs) {
                ctx->return_options |= SEARCH_RETURN_MODSEQ;
-               client_enable(cmd->client, MAILBOX_FEATURE_CONDSTORE);
+               (void)client_enable(cmd->client, MAILBOX_FEATURE_CONDSTORE);
        }
 
        ctx->box = cmd->client->mailbox;
index b0c63bdb63ac9e0f0c4db0d79e06082c2062455c..6f30372e7014eada120b7bb0b249cc7104b6975e 100644 (file)
@@ -11,7 +11,8 @@ int imap_status_parse_items(struct client_command_context *cmd,
                            struct imap_status_items *items_r)
 {
        const char *item;
-       enum mailbox_status_items items;
+       enum mailbox_status_items status = 0;
+       enum mailbox_metadata_items metadata = 0;
 
        if (IMAP_ARG_IS_EOL(args)) {
                client_send_command_error(cmd, "Empty status list.");
@@ -19,7 +20,6 @@ int imap_status_parse_items(struct client_command_context *cmd,
        }
 
        memset(items_r, 0, sizeof(*items_r));
-       items = 0;
        for (; !IMAP_ARG_IS_EOL(args); args++) {
                if (!imap_arg_get_atom(args, &item)) {
                        /* list may contain only atoms */
@@ -30,21 +30,21 @@ int imap_status_parse_items(struct client_command_context *cmd,
 
                item = t_str_ucase(item);
                if (strcmp(item, "MESSAGES") == 0)
-                       items |= STATUS_MESSAGES;
+                       status |= STATUS_MESSAGES;
                else if (strcmp(item, "RECENT") == 0)
-                       items |= STATUS_RECENT;
+                       status |= STATUS_RECENT;
                else if (strcmp(item, "UIDNEXT") == 0)
-                       items |= STATUS_UIDNEXT;
+                       status |= STATUS_UIDNEXT;
                else if (strcmp(item, "UIDVALIDITY") == 0)
-                       items |= STATUS_UIDVALIDITY;
+                       status |= STATUS_UIDVALIDITY;
                else if (strcmp(item, "UNSEEN") == 0)
-                       items |= STATUS_UNSEEN;
+                       status |= STATUS_UNSEEN;
                else if (strcmp(item, "HIGHESTMODSEQ") == 0)
-                       items |= STATUS_HIGHESTMODSEQ;
+                       status |= STATUS_HIGHESTMODSEQ;
                else if (strcmp(item, "X-SIZE") == 0)
-                       items |= STATUS_VIRTUAL_SIZE;
+                       metadata |= MAILBOX_METADATA_VIRTUAL_SIZE;
                else if (strcmp(item, "X-GUID") == 0)
-                       items_r->guid = TRUE;
+                       metadata |= MAILBOX_METADATA_GUID;
                else {
                        client_send_tagline(cmd, t_strconcat(
                                "BAD Invalid status item ", item, NULL));
@@ -52,7 +52,8 @@ int imap_status_parse_items(struct client_command_context *cmd,
                }
        }
 
-       items_r->mailbox_items = items;
+       items_r->status = status;
+       items_r->metadata = metadata;
        return 0;
 }
 
@@ -75,16 +76,20 @@ int imap_status_get(struct client_command_context *cmd,
                box = mailbox_alloc(ns->list, mailbox,
                                    MAILBOX_FLAG_READONLY |
                                    MAILBOX_FLAG_KEEP_RECENT);
-               if (client->enabled_features != 0)
-                       mailbox_enable(box, client->enabled_features);
+               if (client->enabled_features != 0) {
+                       if (mailbox_enable(box, client->enabled_features) < 0)
+                               ret = -1;
+               }
        }
 
-       if ((items->mailbox_items & STATUS_HIGHESTMODSEQ) != 0)
-               client_enable(client, MAILBOX_FEATURE_CONDSTORE);
+       if ((items->status & STATUS_HIGHESTMODSEQ) != 0)
+               (void)client_enable(client, MAILBOX_FEATURE_CONDSTORE);
 
-       ret = mailbox_get_status(box, items->mailbox_items, &result_r->status);
-       if (items->guid && ret == 0)
-               ret = mailbox_get_guid(box, result_r->mailbox_guid);
+       ret = mailbox_get_status(box, items->status, &result_r->status);
+       if (items->metadata != 0 && ret == 0) {
+               ret = mailbox_get_metadata(box, items->metadata,
+                                          &result_r->metadata);
+       }
 
        if (ret < 0) {
                struct mail_storage *storage = mailbox_get_storage(box);
@@ -111,27 +116,27 @@ void imap_status_send(struct client *client, const char *mailbox,
        str_append(str, " (");
 
        prefix_len = str_len(str);
-       if ((items->mailbox_items & STATUS_MESSAGES) != 0)
+       if ((items->status & STATUS_MESSAGES) != 0)
                str_printfa(str, "MESSAGES %u ", status->messages);
-       if ((items->mailbox_items & STATUS_RECENT) != 0)
+       if ((items->status & STATUS_RECENT) != 0)
                str_printfa(str, "RECENT %u ", status->recent);
-       if ((items->mailbox_items & STATUS_UIDNEXT) != 0)
+       if ((items->status & STATUS_UIDNEXT) != 0)
                str_printfa(str, "UIDNEXT %u ", status->uidnext);
-       if ((items->mailbox_items & STATUS_UIDVALIDITY) != 0)
+       if ((items->status & STATUS_UIDVALIDITY) != 0)
                str_printfa(str, "UIDVALIDITY %u ", status->uidvalidity);
-       if ((items->mailbox_items & STATUS_UNSEEN) != 0)
+       if ((items->status & STATUS_UNSEEN) != 0)
                str_printfa(str, "UNSEEN %u ", status->unseen);
-       if ((items->mailbox_items & STATUS_HIGHESTMODSEQ) != 0) {
+       if ((items->status & STATUS_HIGHESTMODSEQ) != 0) {
                str_printfa(str, "HIGHESTMODSEQ %llu ",
                            (unsigned long long)status->highest_modseq);
        }
-       if ((items->mailbox_items & STATUS_VIRTUAL_SIZE) != 0) {
+       if ((items->metadata & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) {
                str_printfa(str, "X-SIZE %llu ",
-                           (unsigned long long)status->virtual_size);
+                           (unsigned long long)result->metadata.virtual_size);
        }
-       if (items->guid) {
+       if ((items->metadata & MAILBOX_METADATA_GUID) != 0) {
                str_printfa(str, "X-GUID %s ",
-                           mail_guid_128_to_string(result->mailbox_guid));
+                           mail_guid_128_to_string(result->metadata.guid));
        }
 
        if (str_len(str) != prefix_len)
index 23a98b95af339736b9a31bb56432422ed1431af3..3e038a79c47996feeb1e5ff09b76416c7e534ec4 100644 (file)
@@ -2,14 +2,13 @@
 #define IMAP_STATUS_H
 
 struct imap_status_items {
-       enum mailbox_status_items mailbox_items;
-
-       unsigned int guid:1;
+       enum mailbox_status_items status;
+       enum mailbox_metadata_items metadata;
 };
 
 struct imap_status_result {
        struct mailbox_status status;
-       uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
 };
 
 int imap_status_parse_items(struct client_command_context *cmd,
index 17a90916332b06dd11a5e78ae8fa627c34ad30f5..1c93ee4cc0840bcf133427ca2fad0f08f18a1968 100644 (file)
@@ -210,9 +210,6 @@ imap_sync_send_highestmodseq(struct imap_sync_context *ctx,
 int imap_sync_deinit(struct imap_sync_context *ctx,
                     struct client_command_context *sync_cmd)
 {
-       const enum mailbox_status_items status_items =
-               STATUS_UIDVALIDITY | STATUS_MESSAGES | STATUS_RECENT |
-               STATUS_HIGHESTMODSEQ;
        struct client *client = ctx->client;
        struct mailbox_status status;
        struct mailbox_sync_status sync_status;
@@ -223,13 +220,15 @@ int imap_sync_deinit(struct imap_sync_context *ctx,
                array_free(&ctx->expunges);
 
        if (mailbox_sync_deinit(&ctx->sync_ctx, &sync_status) < 0 ||
-           mailbox_get_status(ctx->box, status_items, &status) < 0 ||
            ctx->failed) {
                mailbox_transaction_rollback(&ctx->t);
                array_free(&ctx->tmp_keywords);
                i_free(ctx);
                return -1;
        }
+       mailbox_get_open_status(ctx->box, STATUS_UIDVALIDITY |
+                               STATUS_MESSAGES | STATUS_RECENT |
+                               STATUS_HIGHESTMODSEQ, &status);
 
        ret = mailbox_transaction_commit(&ctx->t);
 
index 577b9b45344f30ce619d9ebd9b685fca1374408c..1fc990da44fe5dc9b9dd634b0c3e88fcd7142f15 100644 (file)
@@ -300,9 +300,9 @@ static void mdbox_set_file_corrupted(struct dbox_file *file)
 }
 
 static int
-mdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
+mdbox_mailbox_get_guid(struct mdbox_mailbox *mbox,
+                      uint8_t guid[MAIL_GUID_128_SIZE])
 {
-       struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
        struct mdbox_index_header hdr;
 
        if (mdbox_read_header(mbox, &hdr) < 0)
@@ -310,7 +310,7 @@ mdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
 
        if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
                /* regenerate it */
-               if (mdbox_write_index_header(box, NULL, NULL) < 0 ||
+               if (mdbox_write_index_header(&mbox->box, NULL, NULL) < 0 ||
                    mdbox_read_header(mbox, &hdr) < 0)
                        return -1;
        }
@@ -318,6 +318,20 @@ mdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
        return 0;
 }
 
+static int
+mdbox_mailbox_get_metadata(struct mailbox *box,
+                          enum mailbox_metadata_items items,
+                          struct mailbox_metadata *metadata_r)
+{
+       struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
+
+       if ((items & MAILBOX_METADATA_GUID) != 0) {
+               if (mdbox_mailbox_get_guid(mbox, metadata_r->guid) < 0)
+                       return -1;
+       }
+       return index_mailbox_get_metadata(box, items, metadata_r);
+}
+
 static int
 mdbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
 {
@@ -403,7 +417,7 @@ struct mailbox mdbox_mailbox = {
                mdbox_mailbox_delete,
                index_storage_mailbox_rename,
                index_storage_get_status,
-               mdbox_mailbox_get_guid,
+               mdbox_mailbox_get_metadata,
                NULL,
                NULL,
                mdbox_storage_sync_init,
index aaf0fdff7bd4d950839ab309caba555555ea56b3..1389522c3bfd57750d22cf006d7ade86b6135aee 100644 (file)
@@ -303,12 +303,17 @@ static int sdbox_mailbox_delete(struct mailbox *box)
 }
 
 static int
-sdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
+sdbox_mailbox_get_metadata(struct mailbox *box,
+                          enum mailbox_metadata_items items,
+                          struct mailbox_metadata *metadata_r)
 {
        struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
 
-       memcpy(guid, mbox->mailbox_guid, MAIL_GUID_128_SIZE);
-       return 0;
+       if ((items & MAILBOX_METADATA_GUID) != 0) {
+               memcpy(metadata_r->guid, mbox->mailbox_guid,
+                      MAIL_GUID_128_SIZE);
+       }
+       return index_mailbox_get_metadata(box, items, metadata_r);
 }
 
 static int
@@ -370,7 +375,7 @@ struct mailbox sdbox_mailbox = {
                sdbox_mailbox_delete,
                index_storage_mailbox_rename,
                index_storage_get_status,
-               sdbox_mailbox_get_guid,
+               sdbox_mailbox_get_metadata,
                NULL,
                NULL,
                sdbox_storage_sync_init,
index 33b11735c32d6a0fbc0cad11e842889e8408fc69..f823b2fccfc94e88fc9fb82ff51634961d71589b 100644 (file)
@@ -88,7 +88,7 @@ static void search_parse_msgset_args(unsigned int messages_count,
 static void search_init_arg(struct mail_search_arg *arg,
                            struct index_search_context *ctx)
 {
-       uint8_t guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
        bool match;
 
        switch (arg->type) {
@@ -105,12 +105,13 @@ static void search_init_arg(struct mail_search_arg *arg,
                ctx->have_index_args = TRUE;
                break;
        case SEARCH_MAILBOX_GUID:
-               if (mailbox_get_guid(ctx->box, guid) < 0) {
+               if (mailbox_get_metadata(ctx->box, MAILBOX_METADATA_GUID,
+                                        &metadata) < 0) {
                        /* result will be unknown */
                        break;
                }
 
-               match = strcmp(mail_guid_128_to_string(guid),
+               match = strcmp(mail_guid_128_to_string(metadata.guid),
                               arg->value.str) == 0;
                if (match != arg->not)
                        arg->match_always = TRUE;
@@ -1079,7 +1080,7 @@ index_storage_search_init(struct mailbox_transaction_context *t,
        if (gettimeofday(&ctx->last_nonblock_timeval, NULL) < 0)
                i_fatal("gettimeofday() failed: %m");
 
-       mailbox_get_status(t->box, STATUS_MESSAGES, &status);
+       mailbox_get_open_status(t->box, STATUS_MESSAGES, &status);
        ctx->mail_ctx.progress_max = status.messages;
 
        i_array_init(&ctx->mail_ctx.results, 5);
index ac219a5f5e1059cd023456278e977bccee3c9579..1e5aabd99e1bf2b283a5b37a82d45022566e4917 100644 (file)
@@ -7,9 +7,54 @@
 #include "index-storage.h"
 #include "mail-index-modseq.h"
 
+int index_storage_get_status(struct mailbox *box,
+                            enum mailbox_status_items items,
+                            struct mailbox_status *status_r)
+{
+       const struct mail_index_header *hdr;
+
+       memset(status_r, 0, sizeof(struct mailbox_status));
+
+       if (!box->opened) {
+               if (mailbox_open(box) < 0)
+                       return -1;
+               if (mailbox_sync(box, 0) < 0)
+                       return -1;
+       }
+
+       /* we can get most of the status items without any trouble */
+       hdr = mail_index_get_header(box->view);
+       status_r->messages = hdr->messages_count;
+       if ((items & STATUS_RECENT) != 0) {
+               status_r->recent = index_mailbox_get_recent_count(box);
+               i_assert(status_r->recent <= status_r->messages);
+       }
+       status_r->unseen = hdr->messages_count - hdr->seen_messages_count;
+       status_r->uidvalidity = hdr->uid_validity;
+       status_r->uidnext = hdr->next_uid;
+       status_r->nonpermanent_modseqs = mail_index_is_in_memory(box->index);
+       if ((items & STATUS_HIGHESTMODSEQ) != 0) {
+               status_r->highest_modseq =
+                       mail_index_modseq_get_highest(box->view);
+               if (status_r->highest_modseq == 0) {
+                       /* modseqs not enabled yet, but we can't return 0 */
+                       status_r->highest_modseq = 1;
+               }
+       }
+
+       if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) {
+               mail_index_lookup_first(box->view, 0, MAIL_SEEN,
+                                       &status_r->first_unseen_seq);
+       }
+
+       if ((items & STATUS_KEYWORDS) != 0)
+               status_r->keywords = mail_index_get_keywords(box->index);
+       return 0;
+}
+
 static void
-index_storage_get_status_cache_fields(struct mailbox *box,
-                                     struct mailbox_status *status_r)
+get_metadata_cache_fields(struct mailbox *box,
+                         struct mailbox_metadata *metadata_r)
 {
        const struct mail_cache_field *fields;
        enum mail_cache_decision_type dec;
@@ -26,12 +71,12 @@ index_storage_get_status_cache_fields(struct mailbox *box,
                if (dec != MAIL_CACHE_DECISION_NO)
                        array_append(cache_fields, &fields[i].name, 1);
        }
-       status_r->cache_fields = cache_fields;
+       metadata_r->cache_fields = cache_fields;
 }
 
 static int
-index_storage_virtual_size_add_new(struct mailbox *box,
-                                  struct index_vsize_header *vsize_hdr)
+virtual_size_add_new(struct mailbox *box,
+                    struct index_vsize_header *vsize_hdr)
 {
        struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
        const struct mail_index_header *hdr;
@@ -98,15 +143,17 @@ index_storage_virtual_size_add_new(struct mailbox *box,
 }
 
 static int
-index_storage_get_status_virtual_size(struct mailbox *box,
-                                     struct mailbox_status *status_r)
+get_metadata_virtual_size(struct mailbox *box,
+                         struct mailbox_metadata *metadata_r)
 {
        struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
        struct index_vsize_header vsize_hdr;
+       struct mailbox_status status;
        const void *data;
        size_t size;
        int ret;
 
+       mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_UIDNEXT, &status);
        mail_index_get_header_ext(box->view, ibox->vsize_hdr_ext_id,
                                  &data, &size);
        if (size == sizeof(vsize_hdr))
@@ -120,71 +167,32 @@ index_storage_get_status_virtual_size(struct mailbox *box,
                memset(&vsize_hdr, 0, sizeof(vsize_hdr));
        }
 
-       if (vsize_hdr.highest_uid + 1 == status_r->uidnext &&
-           vsize_hdr.message_count == status_r->messages) {
+       if (vsize_hdr.highest_uid + 1 == status.uidnext &&
+           vsize_hdr.message_count == status.messages) {
                /* up to date */
-               status_r->virtual_size = vsize_hdr.vsize;
+               metadata_r->virtual_size = vsize_hdr.vsize;
                return 0;
        }
-       if (vsize_hdr.highest_uid >= status_r->uidnext) {
+       if (vsize_hdr.highest_uid >= status.uidnext) {
                mail_storage_set_critical(box->storage,
                        "vsize-hdr has invalid highest-uid (%u >= %u)",
-                       vsize_hdr.highest_uid, status_r->uidnext);
+                       vsize_hdr.highest_uid, status.uidnext);
                memset(&vsize_hdr, 0, sizeof(vsize_hdr));
        }
-       ret = index_storage_virtual_size_add_new(box, &vsize_hdr);
-       status_r->virtual_size = vsize_hdr.vsize;
+       ret = virtual_size_add_new(box, &vsize_hdr);
+       metadata_r->virtual_size = vsize_hdr.vsize;
        return ret;
 }
 
-int index_storage_get_status(struct mailbox *box,
-                            enum mailbox_status_items items,
-                            struct mailbox_status *status_r)
+int index_mailbox_get_metadata(struct mailbox *box,
+                              enum mailbox_metadata_items items,
+                              struct mailbox_metadata *metadata_r)
 {
-       const struct mail_index_header *hdr;
-       int ret = 0;
-
-       memset(status_r, 0, sizeof(struct mailbox_status));
-
-       if (!box->opened) {
-               if (mailbox_open(box) < 0)
-                       return -1;
-               if (mailbox_sync(box, 0) < 0)
+       if ((items & MAILBOX_METADATA_CACHE_FIELDS) != 0)
+               get_metadata_cache_fields(box, metadata_r);
+       if ((items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) {
+               if (get_metadata_virtual_size(box, metadata_r) < 0)
                        return -1;
        }
-
-       /* we can get most of the status items without any trouble */
-       hdr = mail_index_get_header(box->view);
-       status_r->messages = hdr->messages_count;
-       if ((items & STATUS_RECENT) != 0) {
-               status_r->recent = index_mailbox_get_recent_count(box);
-               i_assert(status_r->recent <= status_r->messages);
-       }
-       status_r->unseen = hdr->messages_count - hdr->seen_messages_count;
-       status_r->uidvalidity = hdr->uid_validity;
-       status_r->uidnext = hdr->next_uid;
-       status_r->nonpermanent_modseqs = mail_index_is_in_memory(box->index);
-       if ((items & STATUS_HIGHESTMODSEQ) != 0) {
-               status_r->highest_modseq =
-                       mail_index_modseq_get_highest(box->view);
-               if (status_r->highest_modseq == 0) {
-                       /* modseqs not enabled yet, but we can't return 0 */
-                       status_r->highest_modseq = 1;
-               }
-       }
-
-       if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) {
-               mail_index_lookup_first(box->view, 0, MAIL_SEEN,
-                                       &status_r->first_unseen_seq);
-       }
-
-       if ((items & STATUS_KEYWORDS) != 0)
-               status_r->keywords = mail_index_get_keywords(box->index);
-       if ((items & STATUS_CACHE_FIELDS) != 0)
-               index_storage_get_status_cache_fields(box, status_r);
-       if ((items & STATUS_VIRTUAL_SIZE) != 0) {
-               if (index_storage_get_status_virtual_size(box, status_r) < 0)
-                       ret = -1;
-       }
-       return ret;
+       return 0;
 }
index 609a29baebecd5dbbdd412d9cac58d626a515cf7..8c8907ec74a0594a8ea151535d27b44d6b38a908 100644 (file)
@@ -423,7 +423,7 @@ int index_storage_mailbox_delete_dir(struct mailbox *box, bool mailbox_deleted)
 
 int index_storage_mailbox_delete(struct mailbox *box)
 {
-       uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
+       struct mailbox_metadata metadata;
 
        if (!box->opened) {
                /* \noselect mailbox, try deleting only the directory */
@@ -433,7 +433,7 @@ int index_storage_mailbox_delete(struct mailbox *box)
        if (mailbox_mark_index_deleted(box, TRUE) < 0)
                return -1;
 
-       if (mailbox_get_guid(box, mailbox_guid) < 0)
+       if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0)
                return -1;
 
        /* Make sure the indexes are closed before trying to delete the
@@ -449,7 +449,7 @@ int index_storage_mailbox_delete(struct mailbox *box)
        } 
 
        mailbox_list_add_change(box->list, MAILBOX_LOG_RECORD_DELETE_MAILBOX,
-                               mailbox_guid);
+                               metadata.guid);
        return index_storage_mailbox_delete_dir(box, TRUE);
 }
 
@@ -532,15 +532,17 @@ void index_copy_cache_fields(struct mail_save_context *ctx,
                             struct mail *src_mail, uint32_t dest_seq)
 {
        T_BEGIN {
-               struct mailbox_status src_status;
+               struct mailbox_metadata src_metadata;
                const char *const *namep;
                buffer_t *buf;
 
-               index_storage_get_status(src_mail->box, STATUS_CACHE_FIELDS,
-                                        &src_status);
+               if (mailbox_get_metadata(src_mail->box,
+                                        MAILBOX_METADATA_CACHE_FIELDS,
+                                        &src_metadata) < 0)
+                       i_unreached();
 
                buf = buffer_create_dynamic(pool_datastack_create(), 1024);
-               array_foreach(src_status.cache_fields, namep) {
+               array_foreach(src_metadata.cache_fields, namep) {
                        mail_copy_cache_field(ctx, src_mail, dest_seq,
                                              *namep, buf);
                }
index d64311b5537af15cad884d652926bae4b95e150c..09927ffedffc1468e324417bfb3caec40671ebd0 100644 (file)
@@ -108,6 +108,9 @@ enum mailbox_sync_type index_sync_type_convert(enum mail_index_sync_type type);
 int index_storage_get_status(struct mailbox *box,
                             enum mailbox_status_items items,
                             struct mailbox_status *status_r);
+int index_mailbox_get_metadata(struct mailbox *box,
+                              enum mailbox_metadata_items items,
+                              struct mailbox_metadata *metadata_r);
 
 struct mail_search_context *
 index_storage_search_init(struct mailbox_transaction_context *t,
index 181d45a1dc73c25690f8ec2513e73b98adb89ee4..29648723ab68020144f213b1907855af54196aca 100644 (file)
@@ -473,11 +473,18 @@ maildir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
 }
 
 static int
-maildir_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
+maildir_mailbox_get_metadata(struct mailbox *box,
+                            enum mailbox_metadata_items items,
+                            struct mailbox_metadata *metadata_r)
 {
        struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
 
-       return maildir_uidlist_get_mailbox_guid(mbox->uidlist, guid);
+       if ((items & MAILBOX_METADATA_GUID) != 0) {
+               if (maildir_uidlist_get_mailbox_guid(mbox->uidlist,
+                                                    metadata_r->guid) < 0)
+                       return -1;
+       }
+       return index_mailbox_get_metadata(box, items, metadata_r);
 }
 
 static void maildir_mailbox_close(struct mailbox *box)
@@ -644,7 +651,7 @@ struct mailbox maildir_mailbox = {
                index_storage_mailbox_delete,
                index_storage_mailbox_rename,
                index_storage_get_status,
-               maildir_mailbox_get_guid,
+               maildir_mailbox_get_metadata,
                maildir_list_index_has_changed,
                maildir_list_index_update_sync,
                maildir_storage_sync_init,
index ef371d5347cbcfca382365964a1a137edd080639..ff709111384b576556ceff376961c06e6cb321ef 100644 (file)
@@ -593,12 +593,11 @@ static void mbox_mailbox_close(struct mailbox *box)
 }
 
 static int
-mbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
+mbox_mailbox_get_guid(struct mbox_mailbox *mbox,
+                     uint8_t guid[MAIL_GUID_128_SIZE])
 {
-       struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
-
-       if (mail_index_is_in_memory(box->index)) {
-               mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
+       if (mail_index_is_in_memory(mbox->box.index)) {
+               mail_storage_set_error(mbox->box.storage, MAIL_ERROR_NOTPOSSIBLE,
                        "Mailbox GUIDs are not permanent without index files");
                return -1;
        }
@@ -610,6 +609,20 @@ mbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
        return 0;
 }
 
+static int
+mbox_mailbox_get_metadata(struct mailbox *box,
+                         enum mailbox_metadata_items items,
+                         struct mailbox_metadata *metadata_r)
+{
+       struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
+
+       if ((items & MAILBOX_METADATA_GUID) != 0) {
+               if (mbox_mailbox_get_guid(mbox, metadata_r->guid) < 0)
+                       return -1;
+       }
+       return index_mailbox_get_metadata(box, items, metadata_r);
+}
+
 static void mbox_notify_changes(struct mailbox *box)
 {
        struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
@@ -748,7 +761,7 @@ struct mailbox mbox_mailbox = {
                index_storage_mailbox_delete,
                index_storage_mailbox_rename,
                index_storage_get_status,
-               mbox_mailbox_get_guid,
+               mbox_mailbox_get_metadata,
                NULL,
                NULL,
                mbox_storage_sync_init,
index 15d7a94c997f61dc8301d2d25c3b2db179eea696..a58db9da8d768a7d5daa99e401ea98bc082fcca5 100644 (file)
@@ -340,7 +340,7 @@ static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
 
        view = mail_index_view_open(ilist->mail_index);
        if (mail_index_lookup_seq(view, uid, &seq)) {
-               mailbox_get_status(box, CACHED_STATUS_ITEMS, &status);
+               mailbox_get_open_status(box, CACHED_STATUS_ITEMS, &status);
                (void)index_list_update(ilist, box, view, seq, &status);
        }
        mail_index_view_close(&view);
index 38488c46bb1937d04cff6d8a194c08fd70ba29cf..85f87e1363701d5ee530520dd9b6f80264aa78e5 100644 (file)
@@ -116,7 +116,9 @@ struct mailbox_vfuncs {
 
        int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
                          struct mailbox_status *status_r);
-       int (*get_guid)(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE]);
+       int (*get_metadata)(struct mailbox *box,
+                           enum mailbox_metadata_items items,
+                           struct mailbox_metadata *metadata_r);
 
        /* Lookup sync extension record and figure out if it mailbox has
           changed since. Returns 1 = yes, 0 = no, -1 = error. */
index f8f192f2fc3d9b5a3ee6bbe87554c9ce3dfcfa62..8c811d09d0a57c766a52110ba30a500f5fb67c87 100644 (file)
@@ -911,21 +911,27 @@ int mailbox_get_status(struct mailbox *box,
        return box->v.get_status(box, items, status_r);
 }
 
-int mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
+void mailbox_get_open_status(struct mailbox *box,
+                            enum mailbox_status_items items,
+                            struct mailbox_status *status_r)
+{
+       i_assert(box->opened);
+       if (box->v.get_status(box, items, status_r) < 0)
+               i_unreached();
+}
+
+int mailbox_get_metadata(struct mailbox *box, enum mailbox_metadata_items items,
+                        struct mailbox_metadata *metadata_r)
 {
-       if (box->v.get_guid == NULL) {
-               mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
-                                      "Storage doesn't support mailbox GUIDs");
-               return -1;
-       }
        if (!box->opened) {
                if (mailbox_open(box) < 0)
                        return -1;
        }
-       if (box->v.get_guid(box, guid) < 0)
+       if (box->v.get_metadata(box, items, metadata_r) < 0)
                return -1;
 
-       i_assert(!mail_guid_128_is_empty(guid));
+       i_assert((items & MAILBOX_METADATA_GUID) == 0 ||
+                !mail_guid_128_is_empty(metadata_r->guid));
        return 0;
 }
 
index f5bcb70e27e44c770da9fc42dce7d67d0e3c380a..9e8410190dc3cfc1da5d2b9a773c9856ef94721c 100644 (file)
@@ -64,9 +64,13 @@ enum mailbox_status_items {
        STATUS_UNSEEN           = 0x10,
        STATUS_FIRST_UNSEEN_SEQ = 0x20,
        STATUS_KEYWORDS         = 0x40,
-       STATUS_HIGHESTMODSEQ    = 0x80,
-       STATUS_CACHE_FIELDS     = 0x100,
-       STATUS_VIRTUAL_SIZE     = 0x200
+       STATUS_HIGHESTMODSEQ    = 0x80
+};
+
+enum mailbox_metadata_items {
+       MAILBOX_METADATA_GUID           = 0x01,
+       MAILBOX_METADATA_VIRTUAL_SIZE   = 0x02,
+       MAILBOX_METADATA_CACHE_FIELDS   = 0x04
 };
 
 enum mailbox_search_result_flags {
@@ -185,17 +189,21 @@ struct mailbox_status {
 
        uint32_t first_unseen_seq;
        uint64_t highest_modseq;
-       /* sum of virtual size of all messages in mailbox */
-       uint64_t virtual_size;
 
        const ARRAY_TYPE(keywords) *keywords;
-       /* Fields that have "temp" or "yes" caching decision. */
-       const ARRAY_TYPE(const_string) *cache_fields;
 
        /* Modseqs aren't permanent (index is in memory) */
        unsigned int nonpermanent_modseqs:1;
 };
 
+struct mailbox_metadata {
+       uint8_t guid[MAIL_GUID_128_SIZE];
+       /* sum of virtual size of all messages in mailbox */
+       uint64_t virtual_size;
+       /* Fields that have "temp" or "yes" caching decision. */
+       const ARRAY_TYPE(const_string) *cache_fields;
+};
+
 struct mailbox_update {
        /* All non-zero fields are changed. */
        uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
@@ -393,11 +401,16 @@ bool mailbox_backends_equal(const struct mailbox *box1,
    do forced CLOSE. */
 bool mailbox_is_inconsistent(struct mailbox *box);
 
-/* Gets the mailbox status information. */
+/* Gets the mailbox status information, opening the mailbox if necessary. */
 int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items,
                       struct mailbox_status *status_r);
-/* Get mailbox GUID, creating it if necessary. */
-int mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE]);
+/* Gets the mailbox status, requires that mailbox is already opened. */
+void mailbox_get_open_status(struct mailbox *box,
+                            enum mailbox_status_items items,
+                            struct mailbox_status *status_r);
+/* Gets mailbox metadata */
+int mailbox_get_metadata(struct mailbox *box, enum mailbox_metadata_items items,
+                        struct mailbox_metadata *metadata_r);
 /* Returns a mask of flags that are private to user in this mailbox
    (as opposed to flags shared between users). */
 enum mail_flags mailbox_get_private_flags_mask(struct mailbox *box);
index 29fc412203a9b898db9f47f69efa94cb8e15fa02..d975839a75c7cdbe156c3e6f75d82fe9dcd220b4 100644 (file)
@@ -298,7 +298,7 @@ static int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend,
 
        box_name = fts_box_get_root(box, &ns);
 
-       mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
        str_printfa(str, "uidv:%u+box:", status.uidvalidity);
        solr_quote_http(str, box_name);
        solr_add_ns_query_http(str, backend, ns);
@@ -340,7 +340,7 @@ static int fts_backend_solr_get_last_uid(struct fts_backend *backend,
 
        box_name = fts_box_get_root(box, &ns);
 
-       mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
        str_printfa(str, "uidv:%u+box:", status.uidvalidity);
        solr_quote_http(str, box_name);
        solr_add_ns_query_http(str, backend, ns);
@@ -539,7 +539,7 @@ fts_backend_solr_build_init(struct fts_backend *backend, uint32_t *last_uid_r,
        ctx->ctx.backend = backend;
        ctx->cmd = str_new(default_pool, SOLR_CMDBUF_SIZE);
 
-       mailbox_get_status(backend->box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(backend->box, STATUS_UIDVALIDITY, &status);
        ctx->uid_validity = status.uidvalidity;
 
        *ctx_r = &ctx->ctx;
@@ -737,7 +737,7 @@ fts_backend_solr_expunge(struct fts_backend *backend, struct mail *mail)
 {
        struct mailbox_status status;
 
-       mailbox_get_status(mail->box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(mail->box, STATUS_UIDVALIDITY, &status);
 
        T_BEGIN {
                string_t *cmd;
@@ -807,7 +807,7 @@ static int fts_backend_solr_lookup(struct fts_backend_lookup_context *ctx,
        bool virtual;
 
        virtual = strcmp(box->storage->name, "virtual") == 0;
-       mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
 
        str = t_str_new(256);
        if (!virtual) {
index b41b54715e30687a3b6dc78b5f7679065249f39a..3da073b2d11edbe87052ee6647df25f186cab647 100644 (file)
@@ -69,7 +69,7 @@ static struct fts_backend *fts_backend_squat_init(struct mailbox *box)
                return NULL;
        }
 
-       mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
        if (storage->set->mmap_disable)
                flags |= SQUAT_INDEX_FLAG_MMAP_DISABLE;
        if (storage->set->mail_nfs_index)
index 1fc50b1c52abe5670c1ce448008ef8a6cb1894a1..dc1a51f0410f47e69cb6a0b72ce0fee52754a6f5 100644 (file)
@@ -396,8 +396,8 @@ static int fts_build_init_virtual_next(struct fts_search_context *fctx)
                ret = strcmp(vname, last_uids[uidi].mailbox);
                if (ret == 0) {
                        /* match. check also that uidvalidity matches. */
-                       mailbox_get_status(boxes[boxi].box, STATUS_UIDVALIDITY,
-                                          &status);
+                       mailbox_get_open_status(boxes[boxi].box,
+                                               STATUS_UIDVALIDITY, &status);
                        if (status.uidvalidity != last_uids[uidi].uidvalidity) {
                                uidi++;
                                continue;
@@ -501,8 +501,8 @@ static int fts_build_init(struct fts_search_context *fctx)
        struct mailbox_status status;
        int ret;
 
-       mailbox_get_status(fctx->t->box, STATUS_MESSAGES | STATUS_UIDNEXT,
-                          &status);
+       mailbox_get_open_status(fctx->t->box, STATUS_MESSAGES | STATUS_UIDNEXT,
+                               &status);
        if (status.messages == fctx->fbox->last_messages_count &&
            status.uidnext == fctx->fbox->last_uidnext) {
                /* no new messages since last check */
@@ -540,8 +540,8 @@ static int fts_build_deinit(struct fts_storage_build_context **_ctx)
                ret = -1;
 
        if (ret == 0) {
-               mailbox_get_status(box, STATUS_MESSAGES | STATUS_UIDNEXT,
-                                  &status);
+               mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_UIDNEXT,
+                                       &status);
                fbox->last_messages_count = status.messages;
                fbox->last_uidnext = status.uidnext;
        }
@@ -778,7 +778,8 @@ static bool search_nonindexed(struct mail_search_context *ctx)
        struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
        struct mailbox_status status;
 
-       mailbox_get_status(ctx->transaction->box, STATUS_MESSAGES, &status);
+       mailbox_get_open_status(ctx->transaction->box,
+                               STATUS_MESSAGES, &status);
 
        fctx->seqs_set = FALSE;
        ctx->seq = fctx->first_nonindexed_seq - 1;
index e6321142d191da68253166282ed2abbf7ddf20e8..1b7da6e6f36b0747026e4c9d7f5650a0630a0806 100644 (file)
@@ -50,7 +50,7 @@ virtual_copy_keywords(struct mailbox *src_box,
                return NULL;
 
        t_array_init(&kw_strings, src_keywords->count + 1);
-       mailbox_get_status(src_box, STATUS_KEYWORDS, &status);
+       mailbox_get_open_status(src_box, STATUS_KEYWORDS, &status);
 
        for (i = 0; i < src_keywords->count; i++) {
                kwp = array_idx(status.keywords, src_keywords->idx[i]);
index 60654b352df0456745284deb34d80726ad6bb044..f0cdf42874a8ada2ee708515ab914ee91782ee4f 100644 (file)
@@ -335,12 +335,16 @@ virtual_mailbox_update(struct mailbox *box,
 }
 
 static int
-virtual_mailbox_get_guid(struct mailbox *box,
-                        uint8_t guid[MAIL_GUID_128_SIZE] ATTR_UNUSED)
+virtual_mailbox_get_metadata(struct mailbox *box,
+                            enum mailbox_metadata_items items,
+                            struct mailbox_metadata *metadata_r)
 {
-       mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
-                              "Virtual mailboxes have no GUIDs");
-       return -1;
+       if ((items & MAILBOX_METADATA_GUID) != 0) {
+               mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
+                                      "Virtual mailboxes have no GUIDs");
+               return -1;
+       }
+       return index_mailbox_get_metadata(box, items, metadata_r);
 }
 
 static void
@@ -437,7 +441,7 @@ virtual_get_virtual_uid(struct mailbox *box, const char *backend_mailbox,
        if (bbox == NULL)
                return FALSE;
 
-       mailbox_get_status(bbox->box, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(bbox->box, STATUS_UIDVALIDITY, &status);
        if (status.uidvalidity != backend_uidvalidity)
                return FALSE;
 
@@ -517,7 +521,7 @@ struct mailbox virtual_mailbox = {
                index_storage_mailbox_delete,
                index_storage_mailbox_rename,
                index_storage_get_status,
-               virtual_mailbox_get_guid,
+               virtual_mailbox_get_metadata,
                NULL,
                NULL,
                virtual_storage_sync_init,
index ccd0d340a6674f5a10b624cba7a816cb3459fa6e..fdaf70ab901a8a28582732efde40d8fb86fc61ff 100644 (file)
@@ -986,8 +986,8 @@ static void virtual_sync_backend_ext_header(struct virtual_sync_context *ctx,
        unsigned int mailbox_offset;
        uint64_t wanted_ondisk_highest_modseq;
 
-       mailbox_get_status(bbox->box, STATUS_UIDVALIDITY |
-                          STATUS_HIGHESTMODSEQ, &status);
+       mailbox_get_open_status(bbox->box, STATUS_UIDVALIDITY |
+                               STATUS_HIGHESTMODSEQ, &status);
        wanted_ondisk_highest_modseq =
                array_count(&bbox->sync_pending_removes) > 0 ? 0 :
                status.highest_modseq;
@@ -1053,7 +1053,7 @@ static int virtual_sync_backend_box(struct virtual_sync_context *ctx,
                if (mailbox_sync(bbox->box, sync_flags) < 0)
                        return -1;
 
-               mailbox_get_status(bbox->box, STATUS_UIDVALIDITY, &status);
+               mailbox_get_open_status(bbox->box, STATUS_UIDVALIDITY, &status);
                virtual_backend_box_sync_mail_set(bbox);
                if (status.uidvalidity != bbox->sync_uid_validity) {
                        /* UID validity changed since last sync (or this is
index 693f86173f9344d7e15738b522bf770ae94cfbef..11b703fbf3bdb254e370c726e78190e29555eb02 100644 (file)
@@ -116,7 +116,7 @@ static int read_mailbox(struct client *client, uint32_t *failed_uid_r)
 
        *failed_uid_r = 0;
 
-       mailbox_get_status(client->mailbox, STATUS_UIDVALIDITY, &status);
+       mailbox_get_open_status(client->mailbox, STATUS_UIDVALIDITY, &status);
        client->uid_validity = status.uidvalidity;
        client->messages_count = status.messages;