index-sync.c revision 5b1d58512ce6eece96f15d58b74e0a9ddb5ad474
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "seq-range-array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-storage.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstruct index_mailbox_sync_context {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox_sync_context ctx;
75e8db37023fde9ac15550bf426be8719d94a821Timo Sirainen struct index_mailbox *ibox;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_index_view_sync_ctx *sync_ctx;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen uint32_t messages_count;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen ARRAY_TYPE(seq_range) flag_updates;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen const ARRAY_TYPE(seq_range) *expunges;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen unsigned int flag_update_pos, expunge_pos;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen bool failed;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen};
e627cdc5ef30d87959f9510832427e33a2f1d84aTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenbool index_mailbox_want_full_sync(struct index_mailbox *ibox,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen enum mailbox_sync_flags flags)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0 &&
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen ioloop_time < ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL)
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen return FALSE;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (ibox->notify_to != NULL)
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen timeout_reset(ibox->notify_to);
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen ibox->sync_last_check = ioloop_time;
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen return TRUE;
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen}
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid index_mailbox_set_recent_uid(struct index_mailbox *ibox, uint32_t uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (uid <= ibox->recent_flags_prev_uid) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_assert(seq_range_exists(&ibox->recent_flags, uid));
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ibox->recent_flags_prev_uid = uid;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_add(&ibox->recent_flags, 64, uid);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ibox->recent_flags_count++;
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen}
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainenvoid index_mailbox_set_recent_seq(struct index_mailbox *ibox,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_index_view *view,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen uint32_t seq1, uint32_t seq2)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen uint32_t uid;
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen for (; seq1 <= seq2; seq1++) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen mail_index_lookup_uid(view, seq1, &uid);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen index_mailbox_set_recent_uid(ibox, uid);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen }
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen}
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return array_is_created(&ibox->recent_flags) &&
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen seq_range_exists(&ibox->recent_flags, uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainenunsigned int index_mailbox_get_recent_count(struct index_mailbox *ibox)
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct seq_range *range;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, count, recent_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!array_is_created(&ibox->recent_flags))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr = mail_index_get_header(ibox->view);
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen recent_count = ibox->recent_flags_count;
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen range = array_get(&ibox->recent_flags, &count);
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen for (i = count; i > 0; ) {
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen i--;
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen if (range[i].seq2 < hdr->next_uid)
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen break;
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen if (range[i].seq1 >= hdr->next_uid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* completely invisible to this view */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen recent_count -= range[i].seq2 - range[i].seq1 + 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* partially invisible */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen recent_count -= range[i].seq2 - hdr->next_uid + 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return recent_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void index_mailbox_expunge_recent(struct index_mailbox *ibox,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t seq1, uint32_t seq2)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t uid;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (!array_is_created(&ibox->recent_flags))
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen for (; seq1 <= seq2; seq1++) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen mail_index_lookup_uid(ibox->view, seq1, &uid);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (seq_range_array_remove(&ibox->recent_flags, uid))
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen ibox->recent_flags_count--;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx)
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct mail_index_view_sync_rec sync;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t seq1, seq2;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen i_array_init(&ctx->flag_updates, 128);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen while (mail_index_view_sync_next(ctx->sync_ctx, &sync)) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen switch (sync.type) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case MAIL_INDEX_SYNC_TYPE_APPEND:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* not interested */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen /* later */
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case MAIL_INDEX_SYNC_TYPE_FLAGS:
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (mail_index_lookup_seq_range(ctx->ibox->view,
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen sync.uid1, sync.uid2,
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen &seq1, &seq2)) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen seq_range_array_add_range(&ctx->flag_updates,
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen seq1, seq2);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* remove expunged messages from flag updates */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (ctx->expunges != NULL) {
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen seq_range_array_remove_seq_range(&ctx->flag_updates,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ctx->expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mailbox_sync_context *
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenindex_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen bool failed)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)box;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen struct index_mailbox_sync_context *ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_index_view_sync_flags sync_flags = 0;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct index_mailbox_sync_context, 1);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen ctx->ctx.box = box;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->ibox = ibox;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (failed) {
24ec3e51a1bd7aaf09c92a7ff7498e225796d7e0Timo Sirainen ctx->failed = TRUE;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen return &ctx->ctx;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen }
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen ctx->messages_count = 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen } else {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen ctx->messages_count =
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen mail_index_view_get_messages_count(ibox->view);
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (mail_index_view_sync_begin(ibox->view, sync_flags,
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen &ctx->sync_ctx) < 0) {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen mail_storage_set_index_error(ibox);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen ctx->failed = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return &ctx->ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen mail_index_view_sync_get_expunges(ctx->sync_ctx,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen &ctx->expunges);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->expunge_pos = array_count(ctx->expunges);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen index_view_sync_recs_get(ctx);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return &ctx->ctx;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen}
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainenstatic int
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainenindex_mailbox_sync_next_expunge(struct index_mailbox_sync_context *ctx,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct mailbox_sync_rec *sync_rec_r)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const struct seq_range *range;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (ctx->expunge_pos == 0)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen return 0;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* expunges is a sorted array of sequences. it's easiest for
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen us to print them from end to beginning. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->expunge_pos--;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen range = array_idx(ctx->expunges, ctx->expunge_pos);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(range->seq2 <= ctx->messages_count);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mailbox_expunge_recent(ctx->ibox, range->seq1, range->seq2);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->messages_count -= range->seq2 - range->seq1 + 1;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen sync_rec_r->seq1 = range->seq1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen sync_rec_r->seq2 = range->seq2;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return 1;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenbool index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct mailbox_sync_rec *sync_rec_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen struct index_mailbox_sync_context *ctx =
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen (struct index_mailbox_sync_context *)_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct seq_range *flag_updates;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int count;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if (ctx->failed)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flag_updates = array_get(&ctx->flag_updates, &count);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (ctx->flag_update_pos < count) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_rec_r->seq1 = flag_updates[ctx->flag_update_pos].seq1;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen sync_rec_r->seq2 = flag_updates[ctx->flag_update_pos].seq2;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ctx->flag_update_pos++;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen return index_mailbox_sync_next_expunge(ctx, sync_rec_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainenstatic void
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainenindex_mailbox_expunge_unseen_recent(struct index_mailbox_sync_context *ctx)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mailbox *ibox = ctx->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq, start_uid, uid;
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!array_is_created(&ibox->recent_flags))
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* expunges array contained expunges for the messages that were already
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen visible in this view, but append+expunge would be invisible.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen recent_flags may however contain the append UID, so we'll have to
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen remove it separately */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr = mail_index_get_header(ibox->view);
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen if (ctx->messages_count == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uid = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (ctx->messages_count <= hdr->messages_count)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_uid(ibox->view, ctx->messages_count, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen i_assert(mail_index_view_is_inconsistent(ibox->view));
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen return;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (seq = ctx->messages_count + 1; seq <= hdr->messages_count; seq++) {
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen start_uid = uid;
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen mail_index_lookup_uid(ibox->view, seq, &uid);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (start_uid + 1 > uid - 1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen continue;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->recent_flags_count -=
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_remove_range(&ibox->recent_flags,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen start_uid + 1, uid - 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (uid + 1 < hdr->next_uid) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen ibox->recent_flags_count -=
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen seq_range_array_remove_range(&ibox->recent_flags,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uid + 1,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen hdr->next_uid - 1);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen#ifdef DEBUG
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const struct seq_range *range;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen unsigned int i, count;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen range = array_get(&ibox->recent_flags, &count);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen for (i = 0; i < count; i++) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen for (uid = range[i].seq1; uid <= range[i].seq2; uid++) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (uid >= hdr->next_uid)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen break;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen mail_index_lookup_seq(ibox->view, uid, &seq);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen i_assert(seq != 0);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen#endif
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen}
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainenint index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen enum mailbox_status_items status_items,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen struct mailbox_status *status_r)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen{
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen struct index_mailbox_sync_context *ctx =
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen (struct index_mailbox_sync_context *)_ctx;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen struct index_mailbox *ibox = ctx->ibox;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen struct mailbox_sync_rec sync_rec;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen const struct mail_index_header *hdr;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uint32_t seq1, seq2;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen int ret = ctx->failed ? -1 : 0;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* finish handling expunges, so we don't break when updating
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen recent flags */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (ctx->sync_ctx != NULL) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (mail_index_view_sync_commit(&ctx->sync_ctx) < 0) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen mail_storage_set_index_error(ibox);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen ret = -1;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen index_mailbox_expunge_unseen_recent(ctx);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (ibox->keep_recent) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* mailbox syncing didn't necessarily update our recent state */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen hdr = mail_index_get_header(ibox->view);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (hdr->first_recent_uid > ibox->recent_flags_prev_uid) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen mail_index_lookup_seq_range(ibox->view,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen hdr->first_recent_uid,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen hdr->next_uid,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen &seq1, &seq2);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (seq1 != 0) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen index_mailbox_set_recent_seq(ibox, ibox->view,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen seq1, seq2);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen }
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen }
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen }
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (ret == 0 && status_items != 0)
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen mailbox_get_status(_ctx->box, status_items, status_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (array_is_created(&ctx->flag_updates))
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen array_free(&ctx->flag_updates);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen i_free(ctx);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return ret;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen}
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenbool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const ARRAY_TYPE(keyword_indexes) *k2)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen{
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen const unsigned int *idx1, *idx2;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen unsigned int i, j, count1, count2;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (!array_is_created(k1))
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return !array_is_created(k2) || array_count(k2) == 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (!array_is_created(k2))
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return array_count(k1) == 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* The arrays may not be sorted, but they usually are. Optimize for
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen the assumption that they are */
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen idx1 = array_get(k1, &count1);
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen idx2 = array_get(k2, &count2);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (count1 != count2)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return FALSE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen for (i = 0; i < count1; i++) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (idx1[i] != idx2[i]) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* not found / unsorted array. check. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen for (j = 0; j < count1; j++) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (idx1[i] == idx2[j])
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen break;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (j == count1)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return FALSE;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return TRUE;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenenum mailbox_sync_type index_sync_type_convert(enum mail_index_sync_type type)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen enum mailbox_sync_type ret = 0;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if ((type & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ret |= MAILBOX_SYNC_TYPE_EXPUNGE;
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if ((type & (MAIL_INDEX_SYNC_TYPE_FLAGS |
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD |
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE |
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET)) != 0)
44c5e644cb413a6559bf2d4179cbe48f9a82f366Timo Sirainen ret |= MAILBOX_SYNC_TYPE_FLAGS;
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen return ret;
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen}
44c5e644cb413a6559bf2d4179cbe48f9a82f366Timo Sirainen