mail-index-view-sync.c revision 16f816d3f3c32ae3351834253f52ddd0212bcbf3
/* Copyright (C) 2003-2004 Timo Sirainen */
#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"
#include "mail-transaction-log.h"
#include "mail-transaction-util.h"
struct mail_index_view_sync_ctx {
struct mail_index_view *view;
struct mail_index_sync_map_ctx sync_map_ctx;
const struct mail_transaction_header *hdr;
const void *data;
unsigned int skipped_some:1;
unsigned int last_read:1;
unsigned int sync_map_update:1;
};
struct mail_index_view_log_sync_pos {
};
static void
const struct mail_transaction_expunge *src,
{
const struct mail_transaction_expunge *src_end;
struct mail_transaction_expunge *dest;
struct mail_transaction_expunge new_exp;
unsigned int first, i, dest_count;
/* @UNSAFE */
if (dest_count == 0) {
return;
}
/* src[] must be sorted. */
for (; i < dest_count; i++) {
break;
}
first = i;
i++;
}
/* continue previous record */
} else if (i == first) {
i++; first++;
} else {
/* use next record */
first++;
}
if (i > first) {
i = first;
}
}
}
static int
{
const struct mail_transaction_header *hdr;
const void *data;
unsigned int count;
int ret;
MAIL_TRANSACTION_EXPUNGE) < 0)
return -1;
struct mail_transaction_expunge, 64);
}
if (ret < 0) {
return -1;
}
/* convert to sequences */
count--;
else
dest++;
}
return 0;
}
#define MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK \
struct mail_index_view_sync_ctx **ctx_r)
{
const struct mail_index_header *hdr;
struct mail_index_view_sync_ctx *ctx;
struct mail_index_map *map;
/* We must sync flags as long as view is mmap()ed, as the flags may
have already changed under us. */
/* Currently we're not handling correctly expunges + no-appends case */
(sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0);
return -1;
if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
/* get list of all expunges first */
return -1;
}
/* only flags, appends and expunges can be left to be synced later */
if (array_is_created(&expunges))
return -1;
}
if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0 &&
(sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0) {
/* keep the old mapping without expunges until we're
fully synced */
} else {
/* we need a private copy of the map if we don't want to
sync expunges. we need to sync mapping only if we're not
using the latest one. */
}
if (ctx->sync_map_update) {
}
/* start from our old view's header. */
}
}
return 0;
}
{
return 0;
return 1;
}
return 0;
}
{
&skipped);
if (ret <= 0) {
if (ret < 0)
return -1;
return 1;
}
if (skipped)
/* skip flag changes that we committed ourself or have already synced */
return 0;
/* expunges have to be synced afterwards so that caller can still get
information of the messages. otherwise caller most likely wants to
see only updated information. */
if (ctx->sync_map_update &&
return -1;
}
return 0;
return 1;
}
#define FLAG_UPDATE_IS_INTERNAL(u) \
((((u)->add_flags | (u)->remove_flags) & \
~(MAIL_INDEX_MAIL_FLAG_DIRTY | MAIL_RECENT)) == 0)
static int
struct mail_index_sync_rec *rec)
{
case MAIL_TRANSACTION_APPEND: {
break;
}
case MAIL_TRANSACTION_EXPUNGE: {
const struct mail_transaction_expunge *exp =
break;
}
case MAIL_TRANSACTION_FLAG_UPDATE: {
const struct mail_transaction_flag_update *update =
for (;;) {
if (!FLAG_UPDATE_IS_INTERNAL(update))
break;
return 0;
}
break;
}
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
if (ctx->data_offset == 0) {
}
/* FIXME: this isn't exactly correct.. but no-one cares? */
break;
}
case MAIL_TRANSACTION_KEYWORD_RESET: {
const struct mail_transaction_keyword_reset *reset =
break;
}
default:
i_unreached();
}
return 1;
}
struct mail_index_sync_rec *sync_rec)
{
int ret;
do {
ctx->data_offset = 0;
do {
&offset);
if (ret < 0)
return -1;
return 0;
if (!ctx->skipped_some) {
}
} while (ret == 0);
if (ctx->skipped_some) {
seq,
offset);
}
}
return 1;
}
const uint32_t *
unsigned int *count_r)
{
const struct mail_transaction_expunge *data;
}
{
if (ctx->sync_map_update)
/* we didn't sync everything */
}
}
}
{
struct mail_index_view_log_sync_pos pos;
}