index-sync.c revision a5cc9935581d9503b5f77097390d903b8add6c44
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "seq-range-array.h"
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen#include "array.h"
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#include "buffer.h"
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#include "index-storage.h"
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainenstruct index_mailbox_sync_context {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct mailbox_sync_context ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct index_mailbox *ibox;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct mail_index_view_sync_ctx *sync_ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen uint32_t messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen const ARRAY_TYPE(seq_range) *expunges;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen unsigned int expunge_pos;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen uint32_t last_seq1, last_seq2;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen bool failed;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen};
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainenvoid index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen unsigned char *p;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen size_t dest_idx;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen i_assert(seq != 0);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (ibox->recent_flags_start_seq == 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags = buffer_create_dynamic(default_pool, 128);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags_start_seq = seq;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen } else if (seq < ibox->recent_flags_start_seq) {
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen dest_idx = ibox->recent_flags_start_seq - seq;
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen buffer_copy(ibox->recent_flags, dest_idx,
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen ibox->recent_flags, 0, (size_t)-1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen memset(buffer_get_modifiable_data(ibox->recent_flags, NULL),
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen 0, dest_idx);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags_start_seq = seq;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen p = buffer_get_space_unsafe(ibox->recent_flags,
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen seq - ibox->recent_flags_start_seq, 1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (*p == 0) {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen ibox->recent_flags_count++;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen *p = 1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen}
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenbool index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t seq)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const unsigned char *data;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen size_t size;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint32_t idx;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (seq < ibox->recent_flags_start_seq ||
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags_start_seq == 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return FALSE;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen idx = seq - ibox->recent_flags_start_seq;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen data = buffer_get_data(ibox->recent_flags, &size);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return idx < size ? data[idx] : FALSE;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen}
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void index_mailbox_expunge_recent(struct index_mailbox *ibox,
4c07b08af30e1065f7022980b60474f229d8cadfTimo Sirainen uint32_t seq1, uint32_t seq2)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const unsigned char *data;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen size_t size;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint32_t i, idx, count, move;
baf1148108b7d9739626b47cc57298c36929586aTimo Sirainen
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen if (ibox->recent_flags_start_seq == 0) {
4c07b08af30e1065f7022980b60474f229d8cadfTimo Sirainen /* no recent flags */
baf1148108b7d9739626b47cc57298c36929586aTimo Sirainen return;
baf1148108b7d9739626b47cc57298c36929586aTimo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
4c07b08af30e1065f7022980b60474f229d8cadfTimo Sirainen if (seq2 < ibox->recent_flags_start_seq) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* expunging messages before recent flags, just modify
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen the recent start position */
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen ibox->recent_flags_start_seq -= seq2 - seq1 + 1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (seq1 < ibox->recent_flags_start_seq) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen move = ibox->recent_flags_start_seq - seq1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen seq1 = ibox->recent_flags_start_seq;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen } else {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen move = 0;
6389aeec8c26b585e583c364b48ad12adf741898Timo Sirainen }
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen idx = seq1 - ibox->recent_flags_start_seq;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen count = seq2 - seq1 + 1;
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen data = buffer_get_data(ibox->recent_flags, &size);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (idx < size) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (idx + count > size)
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen count = size - idx;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen for (i = 0; i < count; i++) {
9c4e6f29ad07fbd27cb9ac510fa69f8c60709f1fTimo Sirainen if (data[idx+i])
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags_count--;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen buffer_copy(ibox->recent_flags, idx,
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen ibox->recent_flags, idx + count, (size_t)-1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen buffer_write_zero(ibox->recent_flags, size - count, count);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen buffer_set_used_size(ibox->recent_flags, size - count);
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen }
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ibox->recent_flags_start_seq -= move;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen}
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainenstatic int index_mailbox_update_recent(struct index_mailbox *ibox,
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen uint32_t seq1, uint32_t seq2)
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen{
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen const struct mail_index_record *rec;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen for (; seq1 <= seq2; seq1++) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (mail_index_lookup(ibox->view, seq1, &rec) < 0) {
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen mail_storage_set_index_error(ibox);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return -1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if ((rec->flags & MAIL_RECENT) != 0 ||
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->is_recent(ibox, rec->uid))
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen index_mailbox_set_recent(ibox, seq1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return 0;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mailbox_sync_context *
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenindex_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen bool failed)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)box;
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen struct index_mailbox_sync_context *ctx;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen enum mail_index_sync_type sync_mask;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx = i_new(struct index_mailbox_sync_context, 1);
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx->ctx.box = box;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx->ibox = ibox;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (failed) {
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx->failed = TRUE;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen return &ctx->ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->messages_count = mail_index_view_get_messages_count(ibox->view);
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync_mask = MAIL_INDEX_SYNC_MASK_ALL;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync_mask &= ~MAIL_INDEX_SYNC_TYPE_EXPUNGE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_NEWMAIL) != 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync_mask &= ~MAIL_INDEX_SYNC_TYPE_APPEND;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (mail_index_view_sync_begin(ibox->view, sync_mask,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen &ctx->sync_ctx) < 0) {
4c07b08af30e1065f7022980b60474f229d8cadfTimo Sirainen mail_storage_set_index_error(ibox);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->failed = TRUE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return &ctx->ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (!ibox->recent_flags_synced) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->recent_flags_synced = TRUE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen index_mailbox_update_recent(ibox, 1, ctx->messages_count);
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen mail_index_view_sync_get_expunges(ctx->sync_ctx,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen &ctx->expunges);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->expunge_pos = array_count(ctx->expunges);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return &ctx->ctx;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic bool sync_rec_check_skips(struct index_mailbox_sync_context *ctx,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct mailbox_sync_rec *sync_rec)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen uint32_t seq, new_seq1, new_seq2;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (sync_rec->seq1 >= ctx->last_seq1 &&
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec->seq1 <= ctx->last_seq2)
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen new_seq1 = ctx->last_seq2 + 1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen else
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen new_seq1 = sync_rec->seq1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (sync_rec->seq2 >= ctx->last_seq1 &&
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec->seq2 <= ctx->last_seq2)
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen new_seq2 = ctx->last_seq1 - 1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen else
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen new_seq2 = sync_rec->seq2;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (new_seq1 > new_seq2)
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen return FALSE;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx->last_seq1 = sync_rec->seq1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen ctx->last_seq2 = sync_rec->seq2;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec->seq1 = new_seq1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec->seq2 = new_seq2;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen /* FIXME: we're only skipping messages from the beginning and from
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen the end. we should skip also the middle ones. This takes care of
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen the most common repeats though. */
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (ctx->expunges != NULL) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* skip expunged messages from the beginning and the end */
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen for (seq = sync_rec->seq1; seq <= sync_rec->seq2; seq++) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (!seq_range_exists(ctx->expunges, seq))
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen break;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (seq > sync_rec->seq2) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* everything skipped */
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen return FALSE;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen }
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen sync_rec->seq1 = seq;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen for (seq = sync_rec->seq2; seq >= sync_rec->seq1; seq--) {
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen if (!seq_range_exists(ctx->expunges, seq))
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen break;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen }
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen sync_rec->seq2 = seq;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen }
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen return TRUE;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen}
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainenint index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct mailbox_sync_rec *sync_rec_r)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
07fe84e1db9fe5a79e815f000bd94ae61f5831dbTimo Sirainen struct index_mailbox_sync_context *ctx =
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen (struct index_mailbox_sync_context *)_ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct mail_index_view_sync_rec sync;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen int ret;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (ctx->failed)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return -1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen while ((ret = mail_index_view_sync_next(ctx->sync_ctx, &sync)) > 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen switch (sync.type) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen case MAIL_INDEX_SYNC_TYPE_APPEND:
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* not interested */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen break;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen /* later */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen break;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen case MAIL_INDEX_SYNC_TYPE_FLAGS:
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* FIXME: hide the flag updates for expunged messages */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (mail_index_lookup_uid_range(ctx->ibox->view,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync.uid1, sync.uid2,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen &sync_rec_r->seq1,
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen &sync_rec_r->seq2) < 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->failed = TRUE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return -1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (sync_rec_r->seq1 == 0)
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen break;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (!sync_rec_check_skips(ctx, sync_rec_r))
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen break;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec_r->type =
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync.type == MAIL_INDEX_SYNC_TYPE_FLAGS ?
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen MAILBOX_SYNC_TYPE_FLAGS :
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen MAILBOX_SYNC_TYPE_KEYWORDS;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return 1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen if (ret == 0 && ctx->expunge_pos > 0) {
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen /* expunges is a sorted array of sequences. it's easiest for
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen us to print them from end to beginning. */
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen const struct seq_range *range;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen ctx->expunge_pos--;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen range = array_idx(ctx->expunges, ctx->expunge_pos);
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen sync_rec_r->seq1 = range->seq1;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen sync_rec_r->seq2 = range->seq2;
d21f14c01d5546f4bf1b2cbb28ac1f00c24d952aTimo Sirainen index_mailbox_expunge_recent(ctx->ibox, sync_rec_r->seq1,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync_rec_r->seq2);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (sync_rec_r->seq2 > ctx->messages_count)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen sync_rec_r->seq2 = ctx->messages_count;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->messages_count -= sync_rec_r->seq2 - sync_rec_r->seq1 + 1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen return 1;
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (ret < 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen mail_storage_set_index_error(ctx->ibox);
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen return ret;
2ae7cffa50608be0e1261e0a993333a8bdc0550dTimo Sirainen}
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenint index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen enum mailbox_status_items status_items,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct mailbox_status *status_r)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct index_mailbox_sync_context *ctx =
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen (struct index_mailbox_sync_context *)_ctx;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct index_mailbox *ibox = ctx->ibox;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen uint32_t messages_count;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen int ret = ctx->failed ? -1 : 0;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen if (ctx->sync_ctx != NULL)
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen mail_index_view_sync_end(&ctx->sync_ctx);
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen if (ret == 0) {
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen messages_count = mail_index_view_get_messages_count(ibox->view);
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen if (messages_count != ctx->messages_count) {
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen index_mailbox_update_recent(ibox,
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen ctx->messages_count+1,
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen messages_count);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ibox->synced_recent_count = ibox->recent_flags_count;
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen ret = status_items == 0 ? 0 :
1e62ad3955db977d527fa57d9584e504a8c26fd5Timo Sirainen index_storage_get_status_locked(ctx->ibox, status_items,
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen status_r);
2ba4e9bedb0fa778dfbccec5370018b4d0040d9cTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (ibox->box.transaction_count == 0)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen mail_index_view_unlock(ibox->view);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_free(ctx);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenbool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const ARRAY_TYPE(keyword_indexes) *k2)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const unsigned int *idx1, *idx2;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen unsigned int i, j, count1, count2;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (!array_is_created(k1))
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return !array_is_created(k2) || array_count(k2) == 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (!array_is_created(k2))
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return array_count(k1) == 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* The arrays may not be sorted, but they usually are. Optimize for
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen the assumption that they are */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen idx1 = array_get(k1, &count1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen idx2 = array_get(k2, &count2);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (count1 != count2)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return FALSE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen for (i = 0; i < count1; i++) {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen if (idx1[i] != idx2[i]) {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen /* not found / unsorted array. check. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen for (j = 0; j < count1; j++) {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen if (idx1[i] == idx2[j])
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen break;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (j == count1)
0b1f70057d59ed3fe7a163bd4fde0c75353910f3Timo Sirainen return FALSE;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return TRUE;
0b1f70057d59ed3fe7a163bd4fde0c75353910f3Timo Sirainen}
0b1f70057d59ed3fe7a163bd4fde0c75353910f3Timo Sirainen