index-sync.c revision ab9a91eb05a54f7675e0bf861aca53f417e1980d
/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "seq-range-array.h"
#include "ioloop.h"
#include "array.h"
#include "index-sync-private.h"
struct index_storage_list_index_record {
};
enum cache_mask {
CACHE_HDR = 0x01,
CACHE_BODY = 0x02,
CACHE_RECEIVED_DATE = 0x04,
CACHE_SAVE_DATE = 0x08,
CACHE_VIRTUAL_SIZE = 0x10,
CACHE_PHYSICAL_SIZE = 0x20,
CACHE_POP3_UIDL = 0x40,
CACHE_GUID = 0x80
};
{
enum mail_index_sync_flags sync_flags = 0;
return sync_flags;
}
enum mailbox_sync_flags flags)
{
if ((flags & MAILBOX_SYNC_FLAG_FAST) != 0 &&
return FALSE;
return TRUE;
}
{
return;
"Recent flags state corrupted for mailbox %s",
ibox->recent_flags_count = 0;
}
}
struct mail_index_view *view,
{
}
}
{
}
{
/* can't trust the currently cached recent flags anymore */
ibox->recent_flags_count = 0;
ibox->recent_flags_prev_uid = 0;
}
{
const struct mail_index_header *hdr;
unsigned int i, count, recent_count;
return 0;
for (i = count; i > 0; ) {
i--;
break;
/* completely invisible to this view */
} else {
/* partially invisible */
break;
}
}
return recent_count;
}
static void
{
return;
}
}
{
struct mail_index_view_sync_rec sync_rec;
break;
}
break;
}
}
/* remove expunged messages from flag updates */
}
/* remove flag updates from hidden updates */
&ctx->flag_updates);
}
struct mailbox_sync_context *
bool failed)
{
struct index_mailbox_sync_context *ctx;
enum mail_index_view_sync_flags sync_flags = 0;
if (failed) {
}
if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
if ((flags & MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) != 0) {
ctx->messages_count = 0;
} else {
}
if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
}
}
static bool
struct mailbox_sync_rec *sync_rec_r)
{
if (ctx->expunge_pos == 0)
return FALSE;
/* expunges is a sorted array of sequences. it's easiest for
us to print them from end to beginning. */
ctx->expunge_pos--;
return TRUE;
}
struct mailbox_sync_rec *sync_rec_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
unsigned int count;
return FALSE;
ctx->flag_update_idx++;
return TRUE;
}
/* hidden flag changes' MODSEQs still need to be returned */
ctx->hidden_update_idx++;
return TRUE;
}
}
}
static void
{
struct index_mailbox_context *ibox =
const struct mail_index_header *hdr;
return;
/* expunges array contained expunges for the messages that were already
visible in this view, but append+expunge would be invisible.
recent_flags may however contain the append UID, so we'll have to
remove it separately */
if (ctx->messages_count == 0)
uid = 0;
else {
return;
}
continue;
}
uid + 1,
}
#ifdef DEBUG
if (!mail_index_view_is_inconsistent(view)) {
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
}
}
#endif
}
static enum cache_mask
{
const char *const *cache_fields;
unsigned int i, count;
enum cache_mask cache = 0;
for (i = 0; i < count; i++) {
cache |= CACHE_BODY;
cache |= CACHE_SAVE_DATE;
cache |= CACHE_POP3_UIDL;
cache |= CACHE_GUID;
else if (debug) {
i_debug("Ignoring unknown cache field: %s",
cache_fields[i]);
}
}
return cache;
}
{
struct mailbox_status status;
struct mailbox_transaction_context *trans;
const char *str;
if (cache == 0) {
i_debug("%s: Nothing in mailbox cache, skipping",
}
return 0;
}
/* find the first message we need to index */
if (mail_is_cached(mail))
break;
}
seq++;
} else {
i_debug("%s: Caching mails seq=%u..%u cache=0x%x",
}
}
if ((cache & CACHE_RECEIVED_DATE) != 0)
if ((cache & CACHE_SAVE_DATE) != 0)
if ((cache & CACHE_VIRTUAL_SIZE) != 0)
if ((cache & CACHE_PHYSICAL_SIZE) != 0)
if ((cache & CACHE_POP3_UIDL) != 0) {
&str);
}
if ((cache & CACHE_GUID) != 0)
}
if (mailbox_transaction_commit(&trans) < 0) {
return -1;
}
return 0;
}
{
struct mailbox_metadata metadata;
enum cache_mask cache;
&metadata) < 0) {
return -1;
}
}
{
const struct mail_index_header *hdr;
if (seq1 != 0) {
}
}
}
struct mailbox_sync_status *status_r)
{
struct index_mailbox_sync_context *ctx =
(struct index_mailbox_sync_context *)_ctx;
struct mailbox_sync_rec sync_rec;
bool delayed_expunges = FALSE;
/* finish handling expunges, so we don't break when updating
recent flags */
/* convert sequences to uids before syncing view */
&delayed_expunges) < 0) {
ret = -1;
}
}
/* mailbox syncing didn't necessarily update our recent state */
}
ret = -1;
}
return ret;
}
{
if (!array_is_created(k1))
if (!array_is_created(k2))
return array_count(k1) == 0;
/* The arrays may not be sorted, but they usually are. Optimize for
the assumption that they are */
return FALSE;
for (i = 0; i < count1; i++) {
/* not found / unsorted array. check. */
for (j = 0; j < count1; j++) {
break;
}
if (j == count1)
return FALSE;
}
}
return TRUE;
}
{
enum mailbox_sync_type ret = 0;
if ((type & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0)
if ((type & (MAIL_INDEX_SYNC_TYPE_FLAGS |
return ret;
}
static unsigned int
struct mail_index_view *view)
{
"index sync", 0,
sizeof(struct index_storage_list_index_record),
sizeof(uint32_t));
}
return storage->list_sync_ext_id;
}
struct mail_index_view *list_view,
{
const struct index_storage_list_index_record *rec;
const void *data;
bool expunged;
return 1;
/* doesn't exist / not synced */
return 1;
}
"stat(%s) failed: %m", path);
return -1;
}
return 1;
return 0;
}
struct mail_index_transaction *trans,
{
struct mail_index_view *list_view;
const struct index_storage_list_index_record *old_rec;
const void *data;
bool expunged;
return;
/* get the current record */
if (expunged)
return;
"stat(%s) failed: %m", path);
return;
}
}
}