imap-sync.c revision 10cfe8a2bdc5ccfc05380689c71c27209327538f
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
5c2d695acf9f95ae0dcdda89c4d2391ceda4d672Timo Sirainenimap_sync_init(struct client *client, struct mailbox *box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->sync_ctx = mailbox_sync_init(box, flags);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0);
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 Sirainenint imap_sync_deinit(struct imap_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen STATUS_MESSAGES | STATUS_RECENT, &status) < 0 ||
66c0f96d704f09c88dd03b0ee13a3e9711ffe593Timo Sirainen if (status.uidvalidity != ctx->client->uidvalidity) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* most clients would get confused by this. disconnect them. */
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen "Mailbox UIDVALIDITY changed");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ctx->client->messages_count = status.messages;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen t_strdup_printf("* %u EXISTS", status.messages));
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if (status.recent != ctx->client->recent_count && !ctx->no_newmail) {
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen t_strdup_printf("* %u RECENT", status.recent));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenint imap_sync_more(struct imap_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *const *keywords;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* get next one */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mailbox_sync_next(ctx->sync_ctx, &ctx->sync_rec)) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* finished */
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) {
899ebb8ba3fbebaafd3e431943283719ce2b106dTimo Sirainen for (; ctx->seq <= ctx->sync_rec.seq2; ctx->seq++) {
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = client_send_line(ctx->client, str_c(str));
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ret = client_send_line(ctx->client, str_c(str));
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* update only after we're finished, so that
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen the seq2 > messages_count check above
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen doesn't break */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* failure / buffer full */
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainenint imap_sync_nonselected(struct mailbox *box, enum mailbox_sync_flags flags)
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainenstatic bool cmd_sync_continue(struct client_command_context *cmd)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen if ((ret = imap_sync_more(ctx->sync_ctx)) == 0)
111a7dda02defa4d612468cfc3c40da5240645afTimo Sirainen client_send_untagged_storage_error(cmd->client,
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 i_assert(client->output_lock == cmd || client->output_lock == NULL);
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen mailbox_transaction_get_count(client->mailbox) > 0) {
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen no_newmail = (client_workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 &&
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen /* expunges might break the client just as badly as new mail
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen notifications. */
834f2b9f60d93e4c7dfc6992e692f5b7213a1b11Timo Sirainen ctx = p_new(cmd->pool, struct cmd_sync_context, 1);