mail-index-view-sync.c revision e06c0b65c16ccce69bbee009ead14d7d3d17a256
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#include "mail-transaction-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view_sync_ctx {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mail_index_view *view;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen enum mail_index_sync_type sync_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_t *expunges;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen const struct mail_transaction_header *hdr;
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen const void *data;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen size_t data_offset;
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen unsigned int skipped:1;
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen unsigned int last_read:1;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen unsigned int sync_map_update:1;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenview_sync_get_expunges(struct mail_index_view *view, buffer_t **expunges_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen const struct mail_transaction_header *hdr;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mail_transaction_expunge *src, *src_end, *dest;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const void *data;
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen size_t size;
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen int ret;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *expunges_r = buffer_create_dynamic(default_pool, 512, (size_t)-1);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* with mask 0 we don't get anything, we'll just read the expunges
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen while seeking to end */
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen if (mail_transaction_log_view_set(view->log_view,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_seq,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_offset,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->index->hdr->log_file_seq,
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen view->index->hdr->log_file_offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_TRANSACTION_EXPUNGE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen &hdr, &data, NULL)) > 0) {
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen mail_transaction_log_sort_expunges(*expunges_r,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen data, hdr->size);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen }
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (ret == 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* convert to sequences */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src = dest = buffer_get_modifyable_data(*expunges_r, &size);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src_end = src + size / sizeof(*src);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (; src != src_end; src++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen ret = mail_index_lookup_uid_range(view, src->uid1,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen src->uid2,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen &dest->uid1,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen &dest->uid2);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(ret == 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (dest->uid1 == 0)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen size -= sizeof(*dest);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen else
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen buffer_set_used_size(*expunges_r, size);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen } else {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen buffer_set_used_size(*expunges_r, 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen mail_transaction_log_view_unset(view->log_view);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return ret;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen}
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen enum mail_index_sync_type sync_mask,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen struct mail_index_view_sync_ctx **ctx_r)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen{
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const struct mail_index_header *hdr;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen struct mail_index_view_sync_ctx *ctx;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen struct mail_index_map *map;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen enum mail_transaction_type mask;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen buffer_t *expunges = NULL;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* We must sync flags as long as view is mmap()ed, as the flags may
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen have already changed under us. */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen i_assert((sync_mask & MAIL_INDEX_SYNC_TYPE_FLAGS) != 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(view->transactions == 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(!view->syncing);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (mail_index_view_lock_head(view, TRUE) < 0)
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen hdr = view->index->hdr;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* get list of all expunges first */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen mask = mail_transaction_type_mask_get(sync_mask);
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen view->log_file_seq,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen view->log_file_offset,
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen hdr->log_file_seq,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen hdr->log_file_offset, mask) < 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (expunges != NULL)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen buffer_free(expunges);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return -1;
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen }
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen ctx->view = view;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ctx->sync_mask = sync_mask;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ctx->expunges = expunges;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen view->new_map = view->index->map;
9a25d843320a418799494ebaef91112ade0c5fdcTimo Sirainen view->new_map->refcount++;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen /* keep the old mapping without expunges until we're
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen fully synced */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen } else {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* we need a private copy of the map if we don't want to
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen sync expunges */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (view->map != view->index->map)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ctx->sync_map_update = TRUE;
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen map = mail_index_map_to_memory(view->map);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_index_unmap(view->index, view->map);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen view->map = map;
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen view->syncing = TRUE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *ctx_r = ctx;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return 0;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstatic int view_is_transaction_synced(struct mail_index_view *view,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen uint32_t seq, uoff_t offset)
c680a6b35b459045e92814778908da5a93922107Timo Sirainen{
c680a6b35b459045e92814778908da5a93922107Timo Sirainen const unsigned char *data, *end;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen size_t size;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if (view->log_syncs == NULL)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen data = buffer_get_data(view->log_syncs, &size);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen end = data + size;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen for (; data < end; ) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (*((const uoff_t *)data) == offset &&
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *((const uint32_t *)(data + sizeof(uoff_t))) == seq)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return 1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen data += sizeof(uoff_t) + sizeof(uint32_t);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenstatic int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uint32_t *seq_r, uoff_t *offset_r)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mail_index_view *view = ctx->view;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen int ret, skipped;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr, &ctx->data,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen &skipped);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret <= 0) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret < 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ctx->last_read = TRUE;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen return 1;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (skipped)
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen ctx->skipped = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, seq_r, offset_r);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainen /* skip flag changes that we committed ourself or have already synced */
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (view_is_transaction_synced(view, *seq_r, *offset_r))
659fe5d24825b160cae512538088020d97a60239Timo Sirainen return 0;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen /* expunges have to be synced afterwards so that caller can still get
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen information of the messages. otherwise caller most likely wants to
b43bb773ee6534c1013b01a62fbd5703e3b0d17dTimo Sirainen see only updated information. */
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (ctx->sync_map_update &&
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen (ctx->hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0) {
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if (mail_transaction_map(ctx->hdr, ctx->data,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen &mail_index_map_sync_funcs, view) < 0)
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen return -1;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen }
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen return 1;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#define FLAG_UPDATE_IS_INTERNAL(u, empty) \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (((u)->add_flags | (u)->remove_flags) == MAIL_INDEX_MAIL_FLAG_DIRTY && \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen memcmp((u)->add_keywords, empty, INDEX_KEYWORDS_BYTE_COUNT) == 0 && \
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen memcmp((u)->add_keywords, empty, INDEX_KEYWORDS_BYTE_COUNT) == 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainenstatic int
b43bb773ee6534c1013b01a62fbd5703e3b0d17dTimo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_sync_rec *rec)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen static keywords_mask_t empty_keywords = { 0, };
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const void *data = ctx->data;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen case MAIL_TRANSACTION_APPEND: {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen rec->uid1 = rec->uid2 = 0;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen ctx->data_offset += hdr->size;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen break;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen }
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen case MAIL_TRANSACTION_EXPUNGE: {
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen const struct mail_transaction_expunge *exp =
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen ctx->data_offset += sizeof(*exp);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mail_index_sync_get_expunge(rec, exp);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen break;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen case MAIL_TRANSACTION_FLAG_UPDATE: {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen const struct mail_transaction_flag_update *update =
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen for (;;) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen ctx->data_offset += sizeof(*update);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update, empty_keywords))
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen break;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if (ctx->data_offset == ctx->hdr->size)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen return 0;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mail_index_sync_get_update(rec, update);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen break;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen default:
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen i_unreached();
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen return 1;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen}
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen struct mail_index_sync_rec *sync_rec)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen{
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen struct mail_index_view *view = ctx->view;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen uint32_t seq;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen uoff_t offset;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen int ret;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen do {
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ctx->data_offset = 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen do {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ret = mail_index_view_sync_next_trans(ctx, &seq,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen &offset);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ret < 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return -1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ctx->last_read)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return 0;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (!ctx->skipped) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->log_file_seq = seq;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->log_file_offset = offset +
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen sizeof(*ctx->hdr) +
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ctx->hdr->size;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen } while (ret == 0);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ctx->skipped) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_index_view_add_synced_transaction(view,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen seq,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen offset);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return 1;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenconst uint32_t *
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen size_t *count_r)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen const uint32_t *data;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen size_t size;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen data = buffer_get_data(ctx->expunges, &size);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen *count_r = size / (sizeof(uint32_t)*2);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen return data;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen struct mail_index_view *view = ctx->view;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen i_assert(view->syncing);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (view->log_syncs != NULL && !ctx->skipped)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen buffer_set_used_size(view->log_syncs, 0);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (!ctx->last_read && ctx->hdr != NULL &&
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen ctx->data_offset != ctx->hdr->size) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen /* we didn't sync everything */
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->inconsistent = TRUE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (view->new_map != NULL) {
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_index_unmap(view->index, view->map);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->map = view->new_map;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->new_map = NULL;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->map_protected = FALSE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if ((ctx->sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->messages_count = view->map->records_count;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen mail_transaction_log_view_unset(view->log_view);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (ctx->expunges != NULL)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen buffer_free(ctx->expunges);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen view->syncing = FALSE;
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen i_free(ctx);
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen}
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainenvoid mail_index_view_add_synced_transaction(struct mail_index_view *view,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uint32_t log_file_seq,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen uoff_t log_file_offset)
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen{
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen if (view->log_syncs == NULL) {
919875067c26fb261a15b3f7afdb67d7eeddb226Timo Sirainen view->log_syncs = buffer_create_dynamic(default_pool,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen 128, (size_t)-1);
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen }
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen buffer_append(view->log_syncs, &log_file_offset,
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen sizeof(log_file_offset));
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen buffer_append(view->log_syncs, &log_file_seq, sizeof(log_file_seq));
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen}
20c892309312df8f4f73cfcaf8acd2ededda8b05Timo Sirainen