imap-sync.c revision 8039af9679af6fb56116b353fe44f7dd4c08f031
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "common.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "str.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "mail-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-util.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "imap-sync.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "commands.h"
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainenstruct cmd_sync_context {
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen const char *tagline;
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen struct imap_sync_context *sync_ctx;
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen};
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct imap_sync_context {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct client *client;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mailbox *box;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen enum imap_sync_flags imap_flags;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mailbox_transaction_context *t;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mailbox_sync_context *sync_ctx;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail *mail;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen struct mailbox_sync_rec sync_rec;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen ARRAY_TYPE(keywords) tmp_keywords;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen uint32_t seq;
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen unsigned int messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int failed:1;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen unsigned int no_newmail:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct imap_sync_context *
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainenimap_sync_init(struct client *client, struct mailbox *box,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct imap_sync_context *ctx;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_assert(client->mailbox == box);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx = i_new(struct imap_sync_context, 1);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->client = client;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->box = box;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->imap_flags = imap_flags;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_ctx = mailbox_sync_init(box, flags);
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen ctx->t = mailbox_transaction_begin(box, 0);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->messages_count = client->messages_count;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_array_init(&ctx->tmp_keywords, client->keywords.announce_count + 8);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_mailbox_flags(client, FALSE);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return ctx;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainenint imap_sync_deinit(struct imap_sync_context *ctx)
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen{
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen struct mailbox_status status;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen int ret;
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen mail_free(&ctx->mail);
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen STATUS_MESSAGES | STATUS_RECENT, &status) < 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->failed) {
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen mailbox_transaction_rollback(&ctx->t);
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen i_free(ctx);
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen return -1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mailbox_transaction_commit(&ctx->t);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (status.uidvalidity != ctx->client->uidvalidity) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen /* most clients would get confused by this. disconnect them. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen client_disconnect_with_error(ctx->client,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Mailbox UIDVALIDITY changed");
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!ctx->no_newmail) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (status.messages < ctx->messages_count)
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen i_panic("Message count decreased");
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen ctx->client->messages_count = status.messages;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (status.messages != ctx->messages_count) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen client_send_line(ctx->client,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen t_strdup_printf("* %u EXISTS", status.messages));
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (status.recent != ctx->client->recent_count &&
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen !ctx->no_newmail) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen ctx->client->recent_count = status.recent;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen client_send_line(ctx->client,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen t_strdup_printf("* %u RECENT", status.recent));
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen array_free(&ctx->tmp_keywords);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen i_free(ctx);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen return ret;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen}
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainenstatic int imap_sync_send_flags(struct imap_sync_context *ctx, string_t *str)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen{
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen enum mail_flags flags;
4b41116563110d00330896a568eff1078c382827Timo Sirainen const char *const *keywords;
4b41116563110d00330896a568eff1078c382827Timo Sirainen
4b41116563110d00330896a568eff1078c382827Timo Sirainen mail_set_seq(ctx->mail, ctx->seq);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen flags = mail_get_flags(ctx->mail);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen keywords = client_get_keyword_names(ctx->client, &ctx->tmp_keywords,
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen mail_get_keyword_indexes(ctx->mail));
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_truncate(str, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(str, "* %u FETCH (", ctx->seq);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen str_printfa(str, "UID %u ", ctx->mail->uid);
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen
ccec5f82349eae44087900c0e64ed1fd5a1a6fcaTimo Sirainen str_append(str, "FLAGS (");
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainen imap_write_flags(str, flags, keywords);
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainen str_append(str, "))");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return client_send_line(ctx->client, str_c(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainenint imap_sync_more(struct imap_sync_context *ctx)
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen{
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen string_t *str;
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen int ret = 1;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen str = t_str_new(256);
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen for (;;) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (ctx->seq == 0) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen /* get next one */
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (!mailbox_sync_next(ctx->sync_ctx, &ctx->sync_rec)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* finished */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ret = 1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen break;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (ctx->sync_rec.seq2 > ctx->messages_count) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* don't send change notifications of messages we
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen haven't even announced to client yet */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (ctx->sync_rec.seq1 > ctx->messages_count) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen ctx->seq = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen continue;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen ctx->sync_rec.seq2 = ctx->messages_count;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen switch (ctx->sync_rec.type) {
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen case MAILBOX_SYNC_TYPE_FLAGS:
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen case MAILBOX_SYNC_TYPE_KEYWORDS:
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen if (ctx->seq == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->seq = ctx->sync_rec.seq1;
4981827cb5e32cf767b7b0e3070137e6b36f42afTimo Sirainen
4981827cb5e32cf767b7b0e3070137e6b36f42afTimo Sirainen ret = 1;
4981827cb5e32cf767b7b0e3070137e6b36f42afTimo Sirainen for (; ctx->seq <= ctx->sync_rec.seq2; ctx->seq++) {
4981827cb5e32cf767b7b0e3070137e6b36f42afTimo Sirainen if (ret <= 0)
4981827cb5e32cf767b7b0e3070137e6b36f42afTimo Sirainen break;
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen ret = imap_sync_send_flags(ctx, str);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen }
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen break;
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen case MAILBOX_SYNC_TYPE_EXPUNGE:
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen if (ctx->seq == 0)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ctx->seq = ctx->sync_rec.seq2;
c13f3df87bc8ec1fb279fc0ffa6e8517f74dc07cTimo Sirainen ret = 1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret <= 0)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_truncate(str, 0);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen str_printfa(str, "* %u EXPUNGE", ctx->seq);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ret = client_send_line(ctx->client, str_c(str));
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (ctx->seq < ctx->sync_rec.seq1) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* update only after we're finished, so that
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen the seq2 > messages_count check above
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen doesn't break */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->messages_count -=
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_rec.seq2 -
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_rec.seq1 + 1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen break;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen if (ret <= 0) {
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen /* failure / buffer full */
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen break;
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen }
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen ctx->seq = 0;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return ret;
47001341950b8588c5f3a96b75864dab48e279aeTimo Sirainen}
47001341950b8588c5f3a96b75864dab48e279aeTimo Sirainen
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainenstatic bool cmd_sync_continue(struct client_command_context *cmd)
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen{
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen struct cmd_sync_context *ctx = cmd->context;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen int ret;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (cmd->cancel)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ret = 0;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen else {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if ((ret = imap_sync_more(ctx->sync_ctx)) == 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return FALSE;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen }
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen if (ret < 0)
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen ctx->sync_ctx->failed = TRUE;
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen cmd->client->syncing = FALSE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (imap_sync_deinit(ctx->sync_ctx) < 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen client_send_untagged_storage_error(cmd->client,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen mailbox_get_storage(cmd->client->mailbox));
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (!cmd->cancel)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen client_send_tagline(cmd, ctx->tagline);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return TRUE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainenbool cmd_sync(struct client_command_context *cmd, enum mailbox_sync_flags flags,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen enum imap_sync_flags imap_flags, const char *tagline)
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen{
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct client *client = cmd->client;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct cmd_sync_context *ctx;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen bool no_newmail;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen i_assert(client->output_lock == cmd || client->output_lock == NULL);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (client->mailbox == NULL ||
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mailbox_transaction_get_count(client->mailbox) > 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen client_send_tagline(cmd, tagline);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return TRUE;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen no_newmail = (client_workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 &&
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (imap_flags & IMAP_SYNC_FLAG_SAFE) == 0;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (no_newmail) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen /* expunges might break the client just as badly as new mail
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen notifications. */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen flags |= MAILBOX_SYNC_FLAG_NO_EXPUNGES;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx = p_new(cmd->pool, struct cmd_sync_context, 1);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->tagline = p_strdup(cmd->pool, tagline);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_ctx = imap_sync_init(client, client->mailbox,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen imap_flags, flags);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen ctx->sync_ctx->no_newmail = no_newmail;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen cmd->func = cmd_sync_continue;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen cmd->context = ctx;
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen cmd->output_pending = TRUE;
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen if (client->input_lock == cmd)
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen client->input_lock = NULL;
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen client->output_lock = NULL;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen client->syncing = TRUE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return cmd_sync_continue(cmd);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen