mail-index-view-sync.c revision b6612c334604eeb27e1ca2bd804ac66dcbc2eaad
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* After syncing view, map is replaced with sync_new_map. */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* temporary variables while handling lost transaction logs: */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ARRAY_TYPE(keyword_indexes) lost_old_kw, lost_new_kw;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* result of lost transaction logs: */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenmail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Note that all the sequences are actually still UIDs at this point */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* @UNSAFE */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest = array_get_modifiable(expunges, &dest_count);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen array_append(expunges, src, src_size / sizeof(*src));
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* src[] must be sorted. */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen (src+1 != src_end && src->seq2 >= src[1].seq1))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (; i < dest_count; i++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* we can/must merge with next record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* continue previous record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen } else if (i == first) {
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* use next record */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen dest = array_get_modifiable(expunges, &dest_count);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenview_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen const struct mail_index_header *hdr = &view->index->map->hdr;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* the view begins from the first non-synced transaction */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ret = mail_transaction_log_view_set(view->log_view,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* log was reset, but we don't want to sync expunges.
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen we can't do this, so sync only up to the reset. */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen /* we have only this reset log */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen mail_transaction_log_view_clear(view->log_view,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstatic unsigned int
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenview_sync_expunges2seqs(struct mail_index_view_sync_ctx *ctx)
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen /* convert UIDs to sequences */
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen src = dest = array_get_modifiable(&ctx->expunges, &count);
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen if (!mail_index_lookup_seq_range(view, src->seq1, src->seq2,
659fe5d24825b160cae512538088020d97a60239Timo Sirainenview_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* get a list of expunge transactions. there may be some that we have
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen already synced, but it doesn't matter because they'll get dropped
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen out when converting to sequences */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen mail_transaction_log_view_mark(view->log_view);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen /* this is simply a request for expunge */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (mail_transaction_log_sort_expunges(&ctx->expunges, data,
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Corrupted expunge record");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_rewind(view->log_view);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen *expunge_count_r = view_sync_expunges2seqs(ctx);
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainenstatic bool have_existing_expunges(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup_seq_range(view, range->seq1, range->seq2,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool view_sync_have_expunges(struct mail_index_view *view)
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_transaction_log_view_mark(view->log_view);
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* this is simply a request for expunge */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* we have an expunge. see if it still exists. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (have_existing_expunges(view, data, hdr->size)) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen mail_transaction_log_view_rewind(view->log_view);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* handle failures as having expunges (which is safer).
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen we'll probably fail later. */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainenstatic int uint_cmp(const void *p1, const void *p2)
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainenstatic bool view_sync_lost_keywords_equal(struct mail_index_view_sync_ctx *ctx)
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen old_idx = array_get_modifiable(&ctx->lost_old_kw, &old_count);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen new_idx = array_get_modifiable(&ctx->lost_new_kw, &new_count);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen qsort(old_idx, old_count, sizeof(*old_idx), uint_cmp);
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen qsort(new_idx, new_count, sizeof(*new_idx), uint_cmp);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen return memcmp(old_idx, new_idx, old_count * sizeof(old_idx)) == 0;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic int view_sync_update_keywords(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned int *kw_idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *kw_names;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, count;
24c6aaf3c540d078021bb4a326982ae4e3d7eaf8Timo Sirainen kw_idx = array_get(&ctx->lost_new_kw, &count);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen kw_names = array_idx(&ctx->view->index->keywords, 0);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen thdr.type = MAIL_TRANSACTION_KEYWORD_UPDATE | MAIL_TRANSACTION_EXTERNAL;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen /* add new flags one by one */
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen for (i = 0; i < count; i++) {
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen kw_up.name_size = strlen(kw_names[kw_idx[i]]);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen buffer_append(ctx->lost_kw_buf, &kw_up, sizeof(kw_up));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(ctx->lost_kw_buf, kw_names[kw_idx[i]],
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen buffer_append(ctx->lost_kw_buf, &uid, sizeof(uid));
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen buffer_append(ctx->lost_kw_buf, &uid, sizeof(uid));
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx, &thdr,
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainenstatic int view_sync_apply_lost_changes(struct mail_index_view_sync_ctx *ctx,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen struct mail_index_map *old_map = ctx->view->map;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen struct mail_index_map *new_map = ctx->view->index->map;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen const struct mail_index_record *old_rec, *new_rec;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen old_rec = MAIL_INDEX_MAP_IDX(old_map, old_seq - 1);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen new_rec = MAIL_INDEX_MAP_IDX(new_map, new_seq - 1);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen struct mail_transaction_flag_update flag_update;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* check this before syncing the record, since it updates
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if ((old_rec->flags & MAIL_INDEX_FLAGS_MASK) !=
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen flag_update.uid1 = flag_update.uid2 = new_rec->uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flag_update.remove_flags = ~new_rec->flags & 0xff;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx, &thdr,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen mail_index_map_lookup_keywords(old_map, old_seq, &ctx->lost_old_kw);
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen mail_index_map_lookup_keywords(new_map, new_seq, &ctx->lost_new_kw);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct mail_transaction_keyword_reset kw_reset;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* remove all old flags by resetting them */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx, &thdr,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen /* flags or keywords changed */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* if modseq has changed include this message in changed flags
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen list, even if we didn't see any changes above. */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen ext = array_idx(&new_map->extensions, ctx->lost_new_ext_idx);
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen modseqp = CONST_PTR_OFFSET(new_rec, ext->record_offset);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* without modseqs lost_flags isn't updated perfectly correctly, because
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen by the time we're comparing old flags it may have changed from what
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen we last sent to the client (because the map is shared). This could
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen be avoided by always keeping a private copy of the map in the view,
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen but that's a waste of memory for as rare of a problem as this. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen seq_range_array_add(&ctx->lost_flags, 0, new_rec->uid);
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainenview_sync_get_log_lost_changes(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_map *new_map = view->index->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned int old_count = old_map->hdr.messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned int new_count = new_map->hdr.messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_record *old_rec, *new_rec;
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen unsigned int i, j;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* we don't update the map in the same order as it's typically done.
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen map->rec_map may already have some messages appended that we don't
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen want. get an atomic map to make sure these get removed. */
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen (void)mail_index_sync_get_atomic_map(&ctx->sync_map_ctx);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen if (!mail_index_map_get_ext_idx(new_map, view->index->modseq_ext_id,
659fe5d24825b160cae512538088020d97a60239Timo Sirainen ctx->lost_kw_buf = buffer_create_dynamic(pool_datastack_create(), 128);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen /* handle expunges and sync flags */
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen /* message found - check if flags have changed */
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen if (view_sync_apply_lost_changes(ctx, i + 1, j + 1) < 0)
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen /* message expunged */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen seq_range_array_add(&ctx->expunges, 0, old_rec->uid);
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen /* new message appeared out of nowhere */
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen "%s view is inconsistent: "
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen "uid=%u inserted in the middle of mailbox",
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen /* if there are old messages left, they're all expunged */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (; i < old_count; i++) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen seq_range_array_add(&ctx->expunges, 0, old_rec->uid);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* if there are new messages left, they're all new messages */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen thdr.type = MAIL_TRANSACTION_APPEND | MAIL_TRANSACTION_EXTERNAL;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen for (; j < new_count; j++) {
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx,
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen mail_index_map_lookup_keywords(new_map, j + 1,
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen *expunge_count_r = view_sync_expunges2seqs(ctx);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* we have no idea how far we've synced - make sure these aren't used */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if ((ctx->flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) != 0) {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen view->log_file_head_seq = new_map->hdr.log_file_seq;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen view->log_file_head_offset = new_map->hdr.log_file_head_offset;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainenstatic int mail_index_view_sync_init_fix(struct mail_index_view_sync_ctx *ctx)
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* replace the view's map */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* update log positions */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen view->log_file_head_seq = seq = view->map->hdr.log_file_seq;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen if (mail_transaction_log_view_set(view->log_view, seq, offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_view_sync_begin(struct mail_index_view *view,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen unsigned int expunge_count = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Syncing the view invalidates all previous looked up records.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Unreference the mappings this view keeps because of them. */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_expunges = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* just get this view synced - don't return anything */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_index_set_error(view->index, "%s view is inconsistent",
cc6ed00c61fda24799c905e403b94a2a8c39ae5cTimo Sirainen ret = view_sync_set_log_view_range(view, sync_expunges, &reset);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_get_log_lost_changes(ctx, &expunge_count) < 0) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen "%s view syncing failed to apply changes",
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen /* get list of all expunges first */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view_sync_get_expunges(ctx, &expunge_count) < 0) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen have_expunges = view_sync_have_expunges(view);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->map->hdr.messages_count - expunge_count;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (reset && view->map->hdr.messages_count > 0) {
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen "%s reset, view is now inconsistent",
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* no expunges, we can just replace the map */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen "Index %s lost messages without expunging "
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen /* expunges seen. create a private map which we update.
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if we're syncing expunges the map will finally be replaced
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen with the head map to remove the expunged messages. */
#ifdef DEBUG
return ctx;
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)
} T_END;
if (ret < 0)
case MAIL_TRANSACTION_FLAG_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
case MAIL_TRANSACTION_KEYWORD_RESET: {
return FALSE;
return TRUE;
unsigned int count;
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++) {
bool *delayed_expunges_r)
#ifdef DEBUG
return ret;
unsigned int length)