imap-sync.c revision 10cfe8a2bdc5ccfc05380689c71c27209327538f
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "common.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "str.h"
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen#include "mail-storage.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "imap-util.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "imap-sync.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "commands.h"
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct cmd_sync_context {
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen const char *tagline;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct imap_sync_context *sync_ctx;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct imap_sync_context {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct client *client;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox *box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum imap_sync_flags imap_flags;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_transaction_context *t;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_sync_context *sync_ctx;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail *mail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_sync_rec sync_rec;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen uint32_t seq;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen unsigned int messages_count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int failed:1;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen unsigned int no_newmail:1;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct imap_sync_context *
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainenimap_sync_init(struct client *client, struct mailbox *box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags)
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen{
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen struct imap_sync_context *ctx;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_status status;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_assert(client->mailbox == box);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen ctx = i_new(struct imap_sync_context, 1);
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen ctx->client = client;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen ctx->box = box;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen ctx->imap_flags = imap_flags;
6b265a8a9d1ce3b3a8033445e99c9035d62ffbc7Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->sync_ctx = mailbox_sync_init(box, flags);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->t = mailbox_transaction_begin(box, 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen ctx->messages_count = client->messages_count;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* if keyword list changed, send the new list before flag changes */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_get_status(ctx->box, STATUS_KEYWORDS, &status);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen if (client_save_keywords(&client->keywords, status.keywords))
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen client_send_mailbox_flags(client, box, status.keywords);
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen return ctx;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen}
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainenint imap_sync_deinit(struct imap_sync_context *ctx)
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen{
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen struct mailbox_status status;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen int ret;
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_free(&ctx->mail);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen STATUS_MESSAGES | STATUS_RECENT, &status) < 0 ||
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->failed) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mailbox_transaction_rollback(&ctx->t);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_free(ctx);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return -1;
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mailbox_transaction_commit(&ctx->t, 0);
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen t_push();
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen if (status.uidvalidity != ctx->client->uidvalidity) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* most clients would get confused by this. disconnect them. */
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen client_disconnect_with_error(ctx->client,
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen "Mailbox UIDVALIDITY changed");
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!ctx->no_newmail) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (status.messages < ctx->messages_count)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_panic("Message count decreased");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->client->messages_count = status.messages;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (status.messages != ctx->messages_count) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen client_send_line(ctx->client,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen t_strdup_printf("* %u EXISTS", status.messages));
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (status.recent != ctx->client->recent_count && !ctx->no_newmail) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->client->recent_count = status.recent;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen client_send_line(ctx->client,
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen t_strdup_printf("* %u RECENT", status.recent));
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen }
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen t_pop();
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen i_free(ctx);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return ret;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenint imap_sync_more(struct imap_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum mail_flags flags;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *const *keywords;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen string_t *str;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen int ret = 1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen t_push();
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen str = t_str_new(256);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
67770c0874918e3b73bbd1ff75b5ec91790d51dcTimo Sirainen for (;;) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (ctx->seq == 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* get next one */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mailbox_sync_next(ctx->sync_ctx, &ctx->sync_rec)) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* finished */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = 1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen if (ctx->sync_rec.seq2 > ctx->messages_count) {
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen /* don't send change notifications of messages we
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen haven't even announced to client yet */
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen if (ctx->sync_rec.seq1 > ctx->messages_count) {
bcdb6c0bd2e7dbb34b306d3d8c2383a7d7654612Timo Sirainen ctx->seq = 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen continue;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->sync_rec.seq2 = ctx->messages_count;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen switch (ctx->sync_rec.type) {
fb5b342aab25d6dc96df14774eb5215dc5481546Timo Sirainen case MAILBOX_SYNC_TYPE_FLAGS:
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen case MAILBOX_SYNC_TYPE_KEYWORDS:
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen if (ctx->seq == 0)
1330f999b8076b2f8eed2572c667f7482a555c1bTimo Sirainen ctx->seq = ctx->sync_rec.seq1;
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen ret = 1;
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen for (; ctx->seq <= ctx->sync_rec.seq2; ctx->seq++) {
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen if (ret <= 0)
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen break;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mail_set_seq(ctx->mail, ctx->seq);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen flags = mail_get_flags(ctx->mail);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen keywords = mail_get_keywords(ctx->mail);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen str_truncate(str, 0);
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen str_printfa(str, "* %u FETCH (", ctx->seq);
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID) {
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen str_printfa(str, "UID %u ",
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen ctx->mail->uid);
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen }
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen str_append(str, "FLAGS (");
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen imap_write_flags(str, flags, keywords);
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen str_append(str, "))");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = client_send_line(ctx->client, str_c(str));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen case MAILBOX_SYNC_TYPE_EXPUNGE:
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (ctx->seq == 0)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ctx->seq = ctx->sync_rec.seq2;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ret = 1;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) {
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen if (ret <= 0)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen break;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen str_truncate(str, 0);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen str_printfa(str, "* %u EXPUNGE", ctx->seq);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ret = client_send_line(ctx->client, str_c(str));
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (ctx->seq < ctx->sync_rec.seq1) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* update only after we're finished, so that
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen the seq2 > messages_count check above
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen doesn't break */
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen ctx->messages_count -=
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ctx->sync_rec.seq2 -
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen ctx->sync_rec.seq1 + 1;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen }
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen break;
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen }
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen if (ret <= 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* failure / buffer full */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen break;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen ctx->seq = 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen t_pop();
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return ret;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenint imap_sync_nonselected(struct mailbox *box, enum mailbox_sync_flags flags)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen{
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mailbox_sync_context *ctx;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen struct mailbox_sync_rec sync_rec;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen ctx = mailbox_sync_init(box, flags);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen while (mailbox_sync_next(ctx, &sync_rec))
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return mailbox_sync_deinit(&ctx, 0, NULL);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic bool cmd_sync_continue(struct client_command_context *cmd)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct cmd_sync_context *ctx = cmd->context;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen int ret;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (cmd->cancel)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen ret = 0;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen else {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if ((ret = imap_sync_more(ctx->sync_ctx)) == 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen return FALSE;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (ret < 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen ctx->sync_ctx->failed = TRUE;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen cmd->client->syncing = FALSE;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (imap_sync_deinit(ctx->sync_ctx) < 0) {
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen client_send_untagged_storage_error(cmd->client,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen mailbox_get_storage(cmd->client->mailbox));
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen }
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (!cmd->cancel)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen client_send_tagline(cmd, ctx->tagline);
7f3b826a89bcb7a72759912e99f574b28309fe1bTimo Sirainen return TRUE;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen}
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenbool cmd_sync(struct client_command_context *cmd, enum mailbox_sync_flags flags,
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen enum imap_sync_flags imap_flags, const char *tagline)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen{
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct client *client = cmd->client;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen struct cmd_sync_context *ctx;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen bool no_newmail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen i_assert(client->output_lock == cmd || client->output_lock == NULL);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (client->mailbox == NULL ||
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen mailbox_transaction_get_count(client->mailbox) > 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen client_send_tagline(cmd, tagline);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen return TRUE;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen no_newmail = (client_workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 &&
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen (flags & MAILBOX_SYNC_FLAG_FAST) != 0;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen if (no_newmail) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen /* expunges might break the client just as badly as new mail
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen notifications. */
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen flags |= MAILBOX_SYNC_FLAG_NO_EXPUNGES;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen }
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ctx = p_new(cmd->pool, struct cmd_sync_context, 1);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ctx->tagline = p_strdup(cmd->pool, tagline);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ctx->sync_ctx = imap_sync_init(client, client->mailbox,
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen imap_flags, flags);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ctx->sync_ctx->no_newmail = no_newmail;
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen cmd->func = cmd_sync_continue;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen cmd->context = ctx;
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen cmd->output_pending = TRUE;
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen if (client->input_lock == cmd)
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen client->input_lock = NULL;
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen client->output_lock = NULL;
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen client->syncing = TRUE;
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen return cmd_sync_continue(cmd);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen