mail-index-view-sync.c revision 07afd4db18860589803c46a3ee0559bda1c9e1b4
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainenmail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* Note that all the sequences are actually still UIDs at this point */
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen /* @UNSAFE */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen array_append(expunges, src, src_size / sizeof(*src));
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* src[] must be sorted. */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen (src+1 != src_end && src->seq2 >= src[1].seq1))
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen for (; i < dest_count; i++) {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* we can/must merge with next record */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen /* continue previous record */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen } else if (i == first) {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* use next record */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainenview_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen const struct mail_index_header *hdr = &view->index->map->hdr;
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* we'll just directly to the end */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* the view begins from the first non-synced transaction */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen ret = mail_transaction_log_view_set(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* FIXME: use the new index to get needed
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen "Transaction log got desynced for index %s",
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* we can't do this. sync only up to reset. */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* we have only this reset log */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen mail_transaction_log_view_clear(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainenview_sync_get_expunges(struct mail_index_view *view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (view_sync_set_log_view_range(view, TRUE, FALSE, &reset) < 0)
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* get a list of expunge transactions. there may be some that we have
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen already synced, but it doesn't matter because they'll get dropped
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen out when converting to sequences */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* this is simply a request for expunge */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (mail_transaction_log_sort_expunges(expunges_r, data,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen "Corrupted expunge record");
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* convert UIDs to sequences */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen src = dest = array_get_modifiable(expunges_r, &count);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (!mail_index_lookup_seq_range(view, src->seq1, src->seq2,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainenstatic bool have_existing_expunges(struct mail_index_view *view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (mail_index_lookup_seq_range(view, range->seq1, range->seq2,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainenstatic bool view_sync_have_expunges(struct mail_index_view *view)
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* this is simply a request for expunge */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen /* we have an expunge. see if it still exists. */
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen if (have_existing_expunges(view, data, hdr->size)) {
unsigned int expunge_count = 0;
if (quick_sync) {
} else if (sync_expunges) {
&reset) < 0) {
#ifdef DEBUG
unsigned int i, count;
return FALSE;
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
int ret;
bool synced_to_map;
if (ret <= 0) {
if (ret < 0)
store +flags.silent command) */
#define FLAG_UPDATE_IS_INTERNAL(u) \
~MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
case MAIL_TRANSACTION_APPEND: {
case MAIL_TRANSACTION_EXPUNGE: {
case MAIL_TRANSACTION_FLAG_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_RESET: {
return FALSE;
return TRUE;
int ret;
if (ret <= 0) {
if (ret < 0)
return FALSE;
return TRUE;
unsigned int i, count;
for (i = 0; i < count; i++) {
#ifdef DEBUG
return ret;
unsigned int length)