imap-sync.c revision 5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* if multiple commands are in progress, we may need to wait for them
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen to finish before syncing mailbox. */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen unsigned int counter;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen ARRAY_TYPE(seq_range) search_adds, search_removes;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic void uids_to_seqs(struct mailbox *box, ARRAY_TYPE(seq_range) *uids)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int i, count;
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen for (i = 0; i < count; i++) {
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen mailbox_get_seq_range(box, range[i].seq1, range[i].seq2,
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen /* since we have to notify about expunged messages,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen we expect that all the referenced UIDs exist */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen i_assert(seq2 - seq1 == range[i].seq2 - range[i].seq1);
ccb77e2f63626ec46e5745ef4f38baa8e8e504fcTimo Sirainen /* replace uids with seqs */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenimap_sync_send_search_update(struct imap_sync_context *ctx,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen mailbox_search_result_sync(update->result, &ctx->search_removes,
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen imap_quote_append_string(cmd, update->tag, FALSE);
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen /* convert to sequences */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen uids_to_seqs(ctx->client->mailbox, &ctx->search_removes);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen uids_to_seqs(ctx->client->mailbox, &ctx->search_adds);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen imap_write_seq_range(cmd, &ctx->search_removes);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen o_stream_send(ctx->client->output, str_data(cmd), str_len(cmd));
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic void imap_sync_send_search_updates(struct imap_sync_context *ctx)
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen unsigned int i, count;
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen if (!array_is_created(&ctx->client->search_updates))
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen if (!array_is_created(&ctx->search_removes)) {
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen updates = array_get(&ctx->client->search_updates, &count);
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen imap_sync_send_search_update(ctx, &updates[i]);
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainenimap_sync_init(struct client *client, struct mailbox *box,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_ctx = mailbox_sync_init(box, flags);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen i_array_init(&ctx->tmp_keywords, client->keywords.announce_count + 8);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if ((client->enabled_features & MAILBOX_FEATURE_QRESYNC) != 0)
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen /* send search updates the first time after sync is initialized.
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen it now contains expunged messages that must be sent before
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen EXPUNGE replies. */
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainenint imap_sync_deinit(struct imap_sync_context *ctx)
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen STATUS_MESSAGES | STATUS_RECENT, &status) < 0 ||
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen if (status.uidvalidity != ctx->client->uidvalidity) {
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen /* most clients would get confused by this. disconnect them. */
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen "Mailbox UIDVALIDITY changed");
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen ctx->client->messages_count = status.messages;
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen t_strdup_printf("* %u EXISTS", status.messages));
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (status.recent != ctx->client->recent_count &&
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen t_strdup_printf("* %u RECENT", status.recent));
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* send search updates the second time after syncing in done.
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen now it contains added/removed messages. */
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainenstatic int imap_sync_send_flags(struct imap_sync_context *ctx, string_t *str)
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen const char *const *keywords;
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen keywords = client_get_keyword_names(ctx->client, &ctx->tmp_keywords,
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen (unsigned long long)mail_get_modseq(ctx->mail));
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen return client_send_line(ctx->client, str_c(str));
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic int imap_sync_send_modseq(struct imap_sync_context *ctx, string_t *str)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID)
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen (unsigned long long)mail_get_modseq(ctx->mail));
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen return client_send_line(ctx->client, str_c(str));
18634dae6e304bac982bb1e0ff1b6b88fc448dbcTimo Sirainenstatic void imap_sync_vanished(struct imap_sync_context *ctx)
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen unsigned int i, count;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen /* Convert expunge sequences to UIDs and send them in VANISHED line. */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen for (i = 0; i < count; i++) {
if (start_uid != 0) {
if (!comma)
prev_uid);
if (!comma)
case MAILBOX_SYNC_TYPE_FLAGS:
if (ret <= 0)
if (ret <= 0)
case MAILBOX_SYNC_TYPE_MODSEQ:
MAILBOX_FEATURE_CONDSTORE) == 0)
if (ret <= 0)
if (ret <= 0) {
return ret;
return TRUE;
int ret;
return FALSE;
if (ret < 0)
*flags_r = 0;
*imap_flags_r = 0;
fast_count++;
count++;
MAILBOX_SYNC_FLAG_FIX_INCONSISTENT)) == 0);
bool no_newmail;
if (no_newmail) {
return FALSE;
return TRUE;
return TRUE;
return TRUE;
return FALSE;
return ret;
return FALSE;