box = mailbox_find_and_open(user, mailbox);
storage = mailbox_get_storage(box);
if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC |
- MAILBOX_SYNC_FLAG_FIX_INCONSISTENT, 0, NULL) < 0) {
+ MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) {
i_fatal("Forcing a resync on mailbox %s failed: %s", mailbox,
mail_storage_get_last_error(storage, NULL));
}
}
box = mailbox_alloc(info->ns->list, storage_name, NULL, flags);
- if (mailbox_sync(box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(box, 0) < 0) {
struct mail_storage *storage = mailbox_get_storage(box);
i_error("Failed to sync mailbox %s: %s", info->name,
}
box = mailbox_alloc(lbox->ns->list, lbox->storage_name, NULL, flags);
- if (mailbox_sync(box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(box, 0) < 0) {
struct mail_storage *storage = mailbox_get_storage(box);
i_error("Failed to sync mailbox %s: %s", lbox->storage_name,
array_clear(&worker->saved_uids);
if (mailbox_transaction_commit(&trans) < 0 ||
- mailbox_sync(worker->selected_box,
- MAILBOX_SYNC_FLAG_FULL_WRITE, 0, NULL) < 0)
+ mailbox_sync(worker->selected_box, MAILBOX_SYNC_FLAG_FULL_WRITE) < 0)
dsync_worker_set_failure(&worker->worker);
mailbox_close(&worker->selected_box);
storage = mailbox_get_storage(mailbox);
if ((ret = imap_expunge(mailbox, NULL)) < 0)
client_send_untagged_storage_error(client, storage);
- if (mailbox_sync(mailbox, 0, 0, NULL) < 0)
+ if (mailbox_sync(mailbox, 0) < 0)
client_send_untagged_storage_error(client, storage);
mailbox_close(&mailbox);
if (client->enabled_features != 0)
mailbox_enable(ctx->box, client->enabled_features);
- if (mailbox_sync(ctx->box, MAILBOX_SYNC_FLAG_FULL_READ,
- STATUS_MESSAGES | STATUS_RECENT |
- STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY |
- STATUS_UIDNEXT | STATUS_KEYWORDS |
- STATUS_HIGHESTMODSEQ, &status) < 0) {
+ if (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_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++;
if (client->enabled_features != 0)
mailbox_enable(box, client->enabled_features);
- ret = mailbox_sync(box, 0, items, status_r);
- if (ret < 0) {
+ ret = mailbox_sync(box, 0);
+ if (ret == 0)
+ mailbox_get_status(box, items, status_r);
+ else {
struct mail_storage *storage = mailbox_get_storage(box);
+
*error_r = mail_storage_get_last_error(storage, &error);
*error_r = imap_get_error_string(cmd, *error_r, error);
}
static void
imap_sync_send_highestmodseq(struct imap_sync_context *ctx,
const struct mailbox_status *status,
+ const struct mailbox_sync_status *sync_status,
struct client_command_context *sync_cmd)
{
struct client *client = ctx->client;
uint64_t send_modseq = 0;
- if (status->sync_delayed_expunges &&
+ if (sync_status->sync_delayed_expunges &&
client->highest_fetch_modseq > client->sync_last_full_modseq) {
/* if client updates highest-modseq using returned MODSEQs
it loses expunges. try to avoid this by sending it a lower
pre-expunge HIGHESTMODSEQ reply. */
send_modseq = client->sync_last_full_modseq;
- } else if (!status->sync_delayed_expunges &&
+ } else if (!sync_status->sync_delayed_expunges &&
status->highest_modseq > client->sync_last_full_modseq &&
status->highest_modseq > client->highest_fetch_modseq) {
/* we've probably sent some VANISHED or EXISTS replies which
(unsigned long long)send_modseq));
}
- if (!status->sync_delayed_expunges) {
+ if (!sync_status->sync_delayed_expunges) {
/* no delayed expunges, remember this for future */
client->sync_last_full_modseq = status->highest_modseq;
}
{
struct client *client = ctx->client;
struct mailbox_status status;
+ struct mailbox_sync_status sync_status;
int ret;
mail_free(&ctx->mail);
if (array_is_created(&ctx->expunges))
array_free(&ctx->expunges);
- if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
- STATUS_MESSAGES | STATUS_RECENT |
- STATUS_HIGHESTMODSEQ, &status) < 0 ||
+ if (mailbox_sync_deinit(&ctx->sync_ctx, &sync_status) < 0 ||
ctx->failed) {
mailbox_transaction_rollback(&ctx->t);
array_free(&ctx->tmp_keywords);
i_free(ctx);
return -1;
}
+ mailbox_get_status(ctx->box, STATUS_UIDVALIDITY |
+ STATUS_MESSAGES | STATUS_RECENT |
+ STATUS_HIGHESTMODSEQ, &status);
ret = mailbox_transaction_commit(&ctx->t);
now it contains added/removed messages. */
imap_sync_send_search_updates(ctx);
- if ((client->enabled_features & MAILBOX_FEATURE_QRESYNC) != 0)
- imap_sync_send_highestmodseq(ctx, &status, sync_cmd);
+ if ((client->enabled_features & MAILBOX_FEATURE_QRESYNC) != 0) {
+ imap_sync_send_highestmodseq(ctx, &status, &sync_status,
+ sync_cmd);
+ }
if (array_is_created(&ctx->search_removes)) {
array_free(&ctx->search_removes);
i_fatal("Can't open delivery mail as raw: %s",
mail_storage_get_last_error(box->storage, &error));
}
- if (mailbox_sync(box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(box, 0) < 0) {
i_fatal("Can't sync delivery mail: %s",
mail_storage_get_last_error(box->storage, &error));
}
}
/* and try opening again */
- if (mailbox_open(box) < 0 ||
- mailbox_sync(box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(box, 0) < 0) {
*error_r = mail_storage_get_last_error(storage, &error);
mailbox_close(&box);
return NULL;
ctx->saved_mail = TRUE;
mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
- if (ctx->save_dest_mail && mailbox_sync(box, 0, 0, NULL) == 0) {
+ if (ctx->save_dest_mail && mailbox_sync(box, 0) == 0) {
range = array_idx(&changes.saved_uids, 0);
i_assert(range[0].seq1 == range[0].seq2);
bool index_mailbox_sync_next(struct mailbox_sync_context *ctx,
struct mailbox_sync_rec *sync_rec_r);
int index_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r);
+ struct mailbox_sync_status *status_r);
int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags);
enum mailbox_sync_type index_sync_type_convert(enum mail_index_sync_type type);
}
int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+ struct mailbox_sync_status *status_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
}
}
- if (ret == 0 && status_items != 0) {
- mailbox_get_status(_ctx->box, status_items, status_r);
+ if (status_r != NULL)
status_r->sync_delayed_expunges = delayed_expunges;
- }
index_sync_search_results_update(ctx);
}
static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+ struct mailbox_sync_status *status_r)
{
struct mailbox *box = ctx->box;
struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
struct index_mailbox_list *ilist;
struct mail_index_view *view;
- struct mailbox_status tmp_status, *status;
+ struct mailbox_status status;
uint32_t uid, seq;
if (!box->opened) {
/* nothing synced. just return the status. */
i_free(ctx);
-
- if (status_items != 0)
- index_list_get_status(box, status_items, status_r);
return 0;
}
if (ilist == NULL) {
/* indexing disabled */
- return ibox->module_ctx.super.
- sync_deinit(ctx, status_items, status_r);
+ return ibox->module_ctx.super.sync_deinit(ctx, status_r);
}
- /* if status_items == 0, the status_r may be NULL. we really want to
- know the status anyway, so save it elsewhere then */
- status = status_items == 0 ? &tmp_status : status_r;
- status_items |= CACHED_STATUS_ITEMS;
-
- if (ibox->module_ctx.super.sync_deinit(ctx, status_items, status) < 0)
+ if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
return -1;
ctx = NULL;
}
view = mail_index_view_open(ilist->mail_index);
- if (mail_index_lookup_seq(view, uid, &seq))
- (void)index_list_update(ilist, box, view, seq, status);
+ if (mail_index_lookup_seq(view, uid, &seq)) {
+ mailbox_get_status(box, CACHED_STATUS_ITEMS, &status);
+ (void)index_list_update(ilist, box, view, seq, &status);
+ }
mail_index_view_close(&view);
return 0;
}
bool (*sync_next)(struct mailbox_sync_context *ctx,
struct mailbox_sync_rec *sync_rec_r);
int (*sync_deinit)(struct mailbox_sync_context *ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r);
+ struct mailbox_sync_status *status_r);
/* Called once for each expunge. Called one or more times for
flag/keyword changes. Once the sync is finished, called with
}
int mailbox_sync_deinit(struct mailbox_sync_context **_ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+ struct mailbox_sync_status *status_r)
{
struct mailbox_sync_context *ctx = *_ctx;
*_ctx = NULL;
- return ctx->box->v.sync_deinit(ctx, status_items, status_r);
+
+ memset(status_r, 0, sizeof(*status_r));
+ return ctx->box->v.sync_deinit(ctx, status_r);
}
-int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags)
{
struct mailbox_sync_context *ctx;
+ struct mailbox_sync_status status;
if (array_count(&box->search_results) == 0) {
/* we don't care about mailbox's current state, so we might
}
ctx = mailbox_sync_init(box, flags);
- return mailbox_sync_deinit(&ctx, status_items, status_r);
+ return mailbox_sync_deinit(&ctx, &status);
}
#undef mailbox_notify_changes
/* Fields that have "temp" or "yes" caching decision. */
const ARRAY_TYPE(const_string) *cache_fields;
- /* There are expunges that haven't been synced yet */
- unsigned int sync_delayed_expunges:1;
/* Modseqs aren't permanent (index is in memory) */
unsigned int nonpermanent_modseqs:1;
};
uint32_t seq1, seq2;
enum mailbox_sync_type type;
};
+struct mailbox_sync_status {
+ /* There are expunges that haven't been synced yet */
+ unsigned int sync_delayed_expunges:1;
+};
struct mailbox_expunge_rec {
/* IMAP UID */
bool mailbox_sync_next(struct mailbox_sync_context *ctx,
struct mailbox_sync_rec *sync_rec_r);
int mailbox_sync_deinit(struct mailbox_sync_context **ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r);
+ struct mailbox_sync_status *status_r);
/* One-step mailbox synchronization. Use this if you don't care about
changes. */
-int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r);
+int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags);
/* Call given callback function when something changes in the mailbox. */
void mailbox_notify_changes(struct mailbox *box, unsigned int min_interval,
static int
test_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+ struct mailbox_sync_status *status_r)
{
- test_mailbox_get_status(ctx->box, status_items, status_r);
+ if (status_r != NULL)
+ memset(status_r, 0, sizeof(*status_r));
i_free(ctx);
return 0;
}
mailbox_alloc(client->raw_mail_user->namespaces->list,
"Dovecot Delivery Mail", input,
MAILBOX_FLAG_NO_INDEX_FILES);
- if (mailbox_open(box) < 0 ||
- mailbox_sync(box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(box, 0) < 0) {
i_error("Can't open delivery mail as raw: %s",
mail_storage_get_last_error(box->storage, &error));
mailbox_close(&box);
mailbox_transaction_rollback(&t);
}
- if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST, 0, NULL) < 0)
+ if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0)
ret = -1;
mailbox_close(&box);
lt->failed = TRUE;
return;
}
- if (mailbox_sync(lt->dest_box, 0, 0, NULL) < 0) {
+ if (mailbox_sync(lt->dest_box, 0) < 0) {
mail_storage_set_critical(_mail->box->storage,
"lazy_expunge: Couldn't sync expunge mailbox");
mailbox_close(<->dest_box);
enum mail_error error;
int ret;
- if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0)
+ if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
return -1;
src_trans = mailbox_transaction_begin(srcbox, 0);
ret = -1;
}
if (ret == 0) {
- if (mailbox_sync(srcbox, 0, 0, NULL) < 0)
+ if (mailbox_sync(srcbox, 0) < 0)
ret = -1;
}
return ret;
return 0;
}
- if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0) {
+ if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
mailbox_close(&box);
return -1;
}
}
static int quota_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
- enum mailbox_status_items status_items,
- struct mailbox_status *status_r)
+ struct mailbox_sync_status *status_r)
{
struct quota_mailbox *qbox = QUOTA_CONTEXT(ctx->box);
int ret;
- ret = qbox->module_ctx.super.sync_deinit(ctx, status_items, status_r);
+ ret = qbox->module_ctx.super.sync_deinit(ctx, status_r);
/* update quota only after syncing is finished. the quota commit may
recalculate the quota and cause all mailboxes to be synced,
including the one we're already syncing. */
struct mail_search_args *search_args;
int ret;
- if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0)
+ if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
return -1;
t = mailbox_transaction_begin(box, 0);
return 0;
}
- if (mailbox_sync(trash->box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0)
+ if (mailbox_sync(trash->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
return -1;
trash->trans = mailbox_transaction_begin(trash->box, 0);
struct mailbox_sync_context *sync_ctx;
const struct virtual_backend_uidmap *uidmap;
struct mailbox_sync_rec sync_rec;
+ struct mailbox_sync_status sync_status;
unsigned int idx1, idx2;
uint32_t vseq, vuid;
break;
}
}
- return mailbox_sync_deinit(&sync_ctx, 0, NULL);
+ return mailbox_sync_deinit(&sync_ctx, &sync_status);
}
static void virtual_sync_backend_ext_header(struct virtual_sync_context *ctx,
/* first sync in this process */
i_assert(ctx->expunge_removed);
- if (mailbox_sync(bbox->box, sync_flags, STATUS_UIDVALIDITY,
- &status) < 0)
+ if (mailbox_sync(bbox->box, sync_flags) < 0)
return -1;
+ mailbox_get_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
for (i = 0; i < 2; i++) {
expunged = FALSE;
- if (mailbox_sync(client->mailbox, MAILBOX_SYNC_FLAG_FULL_READ,
- STATUS_UIDVALIDITY, &status) < 0) {
+ if (mailbox_sync(client->mailbox,
+ MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
client_send_storage_error(client);
break;
}
+ mailbox_get_status(client->mailbox, STATUS_UIDVALIDITY, &status);
client->uid_validity = status.uidvalidity;
t = mailbox_transaction_begin(client->mailbox, 0);
}
if (mailbox_transaction_commit(&client->trans) < 0 ||
- mailbox_sync(client->mailbox, MAILBOX_SYNC_FLAG_FULL_WRITE,
- 0, NULL) < 0) {
+ mailbox_sync(client->mailbox, MAILBOX_SYNC_FLAG_FULL_WRITE) < 0) {
client_send_storage_error(client);
client_disconnect(client, "Storage error during logout.");
return 1;