Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/index/index-sync.c @ 327:276b7a53c264 HEAD
Modify log fixes. STORE and SEARCH didn't handle properly message sequence
numbers when some in the middle were externally deleted.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 29 Sep 2002 19:19:53 +0300 |
parents | ba058497efa9 |
children | 0dc59fd3faed |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "index-storage.h" #include "mail-index-util.h" #include "mail-modifylog.h" #include "mail-custom-flags.h" /* may leave the index locked */ int index_storage_sync_if_possible(IndexMailbox *ibox) { if (!ibox->index->sync(ibox->index)) { if (!ibox->index->is_diskspace_error(ibox->index)) { (void)ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK); return mail_storage_set_index_error(ibox); } /* not enough disk space to sync. can't do much about it though, giving error message would just make it impossible to delete messages. */ index_reset_error(ibox->index); } return TRUE; } static int index_storage_sync_log(Mailbox *box, MailIndex *index, MailExpungeFunc expunge_func, MailFlagUpdateFunc flag_func, void *context) { ModifyLogRecord *log; MailIndexRecord *rec; MailFlags flags; const char **custom_flags; unsigned int count; /* show the log */ log = mail_modifylog_get_nonsynced(index->modifylog, &count); if (log == NULL) return FALSE; custom_flags = mail_custom_flags_list_get(index->custom_flags); for (; count > 0; count--, log++) { switch (log->type) { case RECORD_TYPE_EXPUNGE: if (expunge_func != NULL) { expunge_func(box, log->seq, log->uid, context); } break; case RECORD_TYPE_FLAGS_CHANGED: if (flag_func == NULL) break; rec = index->lookup_uid_range(index, log->uid, log->uid); if (rec != NULL) { flags = rec->msg_flags; if (rec->uid >= index->first_recent_uid) flags |= MAIL_RECENT; flag_func(box, log->seq, log->uid, flags, custom_flags, context); } break; } } mail_custom_flags_list_unref(index->custom_flags); /* mark synced */ return mail_modifylog_mark_synced(index->modifylog); } int index_storage_sync(Mailbox *box, int expunge, unsigned int *messages, unsigned int *recent, MailExpungeFunc expunge_func, MailFlagUpdateFunc flag_func, void *context) { IndexMailbox *ibox = (IndexMailbox *) box; unsigned int count; int failed; if (expunge && box->readonly) { mail_storage_set_error(box->storage, "Mailbox is read-only"); return FALSE; } *messages = *recent = 0; if (!index_storage_sync_if_possible(ibox)) return FALSE; if (!ibox->index->set_lock(ibox->index, expunge ? MAIL_LOCK_EXCLUSIVE : MAIL_LOCK_SHARED)) return mail_storage_set_index_error(ibox); failed = FALSE; if (expunge_func != NULL || flag_func != NULL) { failed = !index_storage_sync_log(box, ibox->index, expunge_func, flag_func, context); } if (!failed && expunge) { /* expunge messages */ failed = !ibox->expunge_locked(ibox, expunge_func, context); } /* get the messages count even if there was some failures. also it must be done after expunging messages */ count = ibox->index->get_header(ibox->index)->messages_count; count += mail_modifylog_get_expunge_count(ibox->index->modifylog); if (count != ibox->synced_messages_count) { if (count > ibox->synced_messages_count) { /* new messages in mailbox */ *messages = count; *recent = index_storage_get_recent_count(ibox->index); } ibox->synced_messages_count = count; } if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK) || failed) return mail_storage_set_index_error(ibox); return TRUE; }