From: Timo Sirainen Date: Thu, 29 May 2003 22:48:02 +0000 (+0300) Subject: Fixes for syncing mails that are kept in new/ dir. X-Git-Tag: 1.1.alpha1~4587 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c29c4813481f479b5544489b5451c8761e21ef13;p=thirdparty%2Fdovecot%2Fcore.git Fixes for syncing mails that are kept in new/ dir. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-index-open.c b/src/lib-index/mail-index-open.c index 3fc62f4296..9709e6b667 100644 --- a/src/lib-index/mail-index-open.c +++ b/src/lib-index/mail-index-open.c @@ -27,6 +27,9 @@ static int mail_index_open_init(struct mail_index *index, hdr = index->header; + index->maildir_have_new = + (hdr->flags & MAIL_INDEX_FLAG_MAILDIR_NEW) != 0; + /* update \Recent message counters */ if ((flags & MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT) != 0 && hdr->last_nonrecent_uid != hdr->next_uid-1) { diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 48371de52c..0915c228f6 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -29,14 +29,15 @@ enum mail_index_header_flag { /* Rebuild flag is set while index is being rebuilt or when some error is noticed in the index file. If this flag is set, the index shouldn't be used before rebuilding it. */ - MAIL_INDEX_FLAG_REBUILD = 0x01, - MAIL_INDEX_FLAG_FSCK = 0x02, - MAIL_INDEX_FLAG_CACHE_FIELDS = 0x04, - MAIL_INDEX_FLAG_COMPRESS = 0x08, - MAIL_INDEX_FLAG_COMPRESS_DATA = 0x10, - MAIL_INDEX_FLAG_REBUILD_TREE = 0x20, - MAIL_INDEX_FLAG_DIRTY_MESSAGES = 0x40, - MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS = 0x80 + MAIL_INDEX_FLAG_REBUILD = 0x0001, + MAIL_INDEX_FLAG_FSCK = 0x0002, + MAIL_INDEX_FLAG_CACHE_FIELDS = 0x0004, + MAIL_INDEX_FLAG_COMPRESS = 0x0008, + MAIL_INDEX_FLAG_COMPRESS_DATA = 0x0010, + MAIL_INDEX_FLAG_REBUILD_TREE = 0x0020, + MAIL_INDEX_FLAG_DIRTY_MESSAGES = 0x0040, + MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS = 0x0080, + MAIL_INDEX_FLAG_MAILDIR_NEW = 0x0100 }; enum mail_data_field { diff --git a/src/lib-index/maildir/maildir-sync.c b/src/lib-index/maildir/maildir-sync.c index 7df3ed3d5e..f460aef298 100644 --- a/src/lib-index/maildir/maildir-sync.c +++ b/src/lib-index/maildir/maildir-sync.c @@ -436,7 +436,7 @@ static void uidlist_hash_get_filenames(void *key, void *value, void *context) struct maildir_hash_rec *hash_rec = value; if (ACTION(hash_rec) == MAILDIR_FILE_ACTION_NEW) - buffer_append(buf, (const void *) &key, sizeof(key)); + buffer_append(buf, (const void *) &key, sizeof(const char *)); } static int maildir_full_sync_finish(struct maildir_sync_context *ctx) @@ -637,8 +637,8 @@ static int maildir_full_sync_finish(struct maildir_sync_context *ctx) buf = buffer_create_static_hard(ctx->pool, ctx->new_count * sizeof(const char *)); hash_foreach(ctx->files, uidlist_hash_get_filenames, buf); - i_assert(buffer_get_used_size(buf) / sizeof(const char *) <= - ctx->new_count); + i_assert(buffer_get_used_size(buf) == + ctx->new_count * sizeof(const char *)); new_files = buffer_get_modifyable_data(buf, NULL); qsort(new_files, ctx->new_count, sizeof(const char *), @@ -669,7 +669,8 @@ static int maildir_full_sync_finish(struct maildir_sync_context *ctx) return TRUE; } -static int maildir_full_sync_init(struct maildir_sync_context *ctx) +static int maildir_full_sync_init(struct maildir_sync_context *ctx, + int only_new) { struct mail_index *index = ctx->index; struct mail_index_record *rec; @@ -697,6 +698,7 @@ static int maildir_full_sync_init(struct maildir_sync_context *ctx) ctx->files = hash_create(default_pool, ctx->pool, index->header->messages_count * 2, maildir_hash, maildir_cmp); + ctx->new_count = 0; have_new = FALSE; @@ -709,20 +711,23 @@ static int maildir_full_sync_init(struct maildir_sync_context *ctx) if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) have_new = TRUE; - hash_rec = p_new(ctx->pool, struct maildir_hash_rec, 1); - hash_rec->rec = rec; - hash_rec->action = MAILDIR_FILE_ACTION_EXPUNGE; + if (!only_new || + (rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) { + hash_rec = p_new(ctx->pool, struct maildir_hash_rec, 1); + hash_rec->rec = rec; + hash_rec->action = MAILDIR_FILE_ACTION_EXPUNGE; - if (hash_lookup(ctx->files, fname) != NULL) { - index_set_corrupted(index, "Duplicated message %s", - fname); - return FALSE; - } + if (hash_lookup(ctx->files, fname) != NULL) { + index_set_corrupted(index, + "Duplicated message %s", fname); + return FALSE; + } - /* WARNING: index must not be modified as long as these - hash keys exist. Modifying might change the mmap base - address. */ - hash_insert(ctx->files, (void *) fname, hash_rec); + /* WARNING: index must not be modified as long as + these hash keys exist. Modifying might change the + mmap base address. */ + hash_insert(ctx->files, (void *) fname, hash_rec); + } rec = index->next(index, rec); } @@ -892,6 +897,7 @@ static int maildir_full_sync_dirs(struct maildir_sync_context *ctx) if (!maildir_full_sync_dir(ctx, ctx->new_dir, TRUE, ctx->new_dirp, ctx->new_dent)) return FALSE; + ctx->new_dent = NULL; } dirp = opendir(ctx->cur_dir); @@ -911,6 +917,25 @@ static int maildir_full_sync_dirs(struct maildir_sync_context *ctx) return !failed; } +static int maildir_sync_new_dir_full(struct maildir_sync_context *ctx) +{ + if (!ctx->index->set_lock(ctx->index, MAIL_LOCK_EXCLUSIVE)) + return FALSE; + + if (!maildir_full_sync_init(ctx, TRUE)) + return FALSE; + + if (!maildir_full_sync_dir(ctx, ctx->new_dir, TRUE, + ctx->new_dirp, ctx->new_dent)) + return FALSE; + ctx->new_dent = NULL; + + if (!maildir_full_sync_finish(ctx)) + return FALSE; + + return TRUE; +} + static int maildir_sync_new_dir(struct maildir_sync_context *ctx, int move_to_cur, int append_index) { @@ -919,6 +944,14 @@ static int maildir_sync_new_dir(struct maildir_sync_context *ctx, const char *final_dir; if (append_index) { + if (ctx->index->maildir_have_new) { + /* some of the mails in new/ are already indexed. + we'll have to do a full sync. + FIXME: or not really, just full sync for mails + in new/ */ + return maildir_sync_new_dir_full(ctx); + } + if (!ctx->index->set_lock(ctx->index, MAIL_LOCK_EXCLUSIVE)) return FALSE; @@ -988,8 +1021,6 @@ static int maildir_sync_new_dir(struct maildir_sync_context *ctx, } if (append_index) { - /* FIXME: it may be already indexed if it couldn't - be moved to cur! */ if (!move_to_cur) ctx->index->maildir_have_new = TRUE; @@ -1026,7 +1057,7 @@ static int maildir_sync_cur_dir(struct maildir_sync_context *ctx) if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; - if (!maildir_full_sync_init(ctx) || + if (!maildir_full_sync_init(ctx, FALSE) || !maildir_full_sync_dirs(ctx) || !maildir_full_sync_finish(ctx)) return FALSE; @@ -1099,6 +1130,13 @@ static int maildir_index_sync_context(struct maildir_sync_context *ctx, return FALSE; } + if (index->lock_type == MAIL_LOCK_EXCLUSIVE) { + if (index->maildir_have_new) + index->header->flags |= MAIL_INDEX_FLAG_MAILDIR_NEW; + else + index->header->flags &= ~MAIL_INDEX_FLAG_MAILDIR_NEW; + } + if (cur_mtime < ioloop_time - MAILDIR_SYNC_SECS) index->maildir_cur_dirty = 0; else @@ -1190,7 +1228,7 @@ static int maildir_index_sync_context_readonly(struct maildir_sync_context *ctx) directly. but don't rely on it. */ (void)index->try_lock(index, MAIL_LOCK_EXCLUSIVE); - if (!maildir_full_sync_init(ctx) || + if (!maildir_full_sync_init(ctx, FALSE) || !maildir_full_sync_dirs(ctx) || !maildir_full_sync_finish_readonly(ctx)) return FALSE;