int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx, struct mailbox_sync_status *status_r) { struct index_mailbox_sync_context *ctx = (struct index_mailbox_sync_context *)_ctx; struct mailbox_sync_rec sync_rec; bool delayed_expunges = FALSE; int ret = ctx->failed ? -1 : 0; /* finish handling expunges, so we don't break when updating recent flags */ while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ; /* convert sequences to uids before syncing view */ index_sync_search_results_uidify(ctx); if (ctx->sync_ctx != NULL) { if (mail_index_view_sync_commit(&ctx->sync_ctx, &delayed_expunges) < 0) { mailbox_set_index_error(_ctx->box); ret = -1; } } index_mailbox_expunge_unseen_recent(ctx); if ((_ctx->box->flags & MAILBOX_FLAG_DROP_RECENT) == 0 && _ctx->box->opened) { /* mailbox syncing didn't necessarily update our recent state */ index_sync_update_recent_count(_ctx->box); } if (status_r != NULL) status_r->sync_delayed_expunges = delayed_expunges; /* update search results after private index is updated */ index_sync_search_results_update(ctx); if (array_is_created(&ctx->flag_updates)) array_free(&ctx->flag_updates); if (array_is_created(&ctx->hidden_updates)) array_free(&ctx->hidden_updates); if (array_is_created(&ctx->all_flag_update_uids)) array_free(&ctx->all_flag_update_uids); /* update vsize header if wanted */ if (ret == 0) index_mailbox_vsize_update_appends(_ctx->box); i_free(ctx); return ret; }
void index_storage_get_open_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { const struct mail_index_header *hdr; /* 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) { if ((box->flags & MAILBOX_FLAG_DROP_RECENT) != 0) { /* recent flags are set and dropped by the previous sync while index was locked. if we updated the recent flags here we'd have a race condition. */ i_assert(box->synced); } else { /* make sure recent count is set, in case we haven't synced yet */ index_sync_update_recent_count(box); } status_r->recent = index_mailbox_get_recent_count(box); i_assert(status_r->recent <= status_r->messages); } if ((items & STATUS_UNSEEN) != 0) { if (box->view_pvt == NULL || (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { status_r->unseen = hdr->messages_count - hdr->seen_messages_count; } else { status_r->unseen = index_storage_count_pvt_unseen(box); } } status_r->uidvalidity = hdr->uid_validity; status_r->uidnext = hdr->next_uid; status_r->first_recent_uid = hdr->first_recent_uid; if ((items & STATUS_HIGHESTMODSEQ) != 0) { status_r->nonpermanent_modseqs = mail_index_is_in_memory(box->index); status_r->no_modseq_tracking = !mail_index_have_modseq_tracking(box->index); 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_HIGHESTPVTMODSEQ) != 0 && box->view_pvt != NULL) { status_r->highest_pvt_modseq = mail_index_modseq_get_highest(box->view_pvt); if (status_r->highest_pvt_modseq == 0) { /* modseqs not enabled yet, but we can't return 0 */ status_r->highest_pvt_modseq = 1; } } if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) { if (box->view_pvt == NULL || (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { mail_index_lookup_first(box->view, 0, MAIL_SEEN, &status_r->first_unseen_seq); } else { status_r->first_unseen_seq = index_storage_find_first_pvt_unseen_seq(box); } } if ((items & STATUS_LAST_CACHED_SEQ) != 0) get_last_cached_seq(box, &status_r->last_cached_seq); if ((items & STATUS_KEYWORDS) != 0) status_r->keywords = mail_index_get_keywords(box->index); if ((items & STATUS_PERMANENT_FLAGS) != 0) { if (!mailbox_is_readonly(box)) { status_r->permanent_flags = MAIL_FLAGS_NONRECENT; status_r->permanent_keywords = TRUE; status_r->allow_new_keywords = !box->disallow_new_keywords; } } }