Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-index/mbox/mbox-sync.c @ 1858:f59f0c50f018 HEAD
fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 29 Oct 2003 17:45:41 +0200 |
parents | c9571aa175f8 |
children |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "mbox-index.h" #include "mbox-lock.h" #include "mail-index-util.h" #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> static int mbox_lock_and_sync_full(struct mail_index *index, enum mail_lock_type data_lock_type) { enum mail_lock_type lock_type; /* syncing needs exclusive index lock and shared mbox lock, but if we'd want exclusive mbox lock we need to set it here already */ if (index->lock_type == MAIL_LOCK_SHARED) (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK); if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; if (index->mbox_lock_type == MAIL_LOCK_UNLOCK) { lock_type = data_lock_type == MAIL_LOCK_EXCLUSIVE ? MAIL_LOCK_EXCLUSIVE : MAIL_LOCK_SHARED; if (!mbox_lock(index, lock_type)) return FALSE; } return mbox_sync_full(index); } int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__, enum mail_lock_type data_lock_type, int *changes) { struct stat st; int count, fd; if (index->mailbox_readonly && data_lock_type == MAIL_LOCK_EXCLUSIVE) { index_set_error(index, "sync: %s is read-only, " "can't get exclusive lock", index->mailbox_path); return FALSE; } if (changes != NULL) *changes = FALSE; if (index->mbox_sync_counter == index->mbox_lock_counter) { /* we've already synced in this locking session */ return TRUE; } i_assert(index->lock_type != MAIL_LOCK_SHARED); count = 0; while (stat(index->mailbox_path, &st) < 0) { if (errno != ENOENT || ++count == 3) return mbox_set_syscall_error(index, "stat()"); /* mbox was deleted by someone - happens with some MUAs when all mail is expunged. easiest way to deal with this is to recreate the file. */ fd = open(index->mailbox_path, O_RDWR | O_CREAT | O_EXCL, 0660); if (fd != -1) (void)close(fd); else if (errno != EEXIST) return mbox_set_syscall_error(index, "open()"); } if (index->mbox_fd != -1 && (index->mbox_ino != st.st_ino || !CMP_DEV_T(index->mbox_dev, st.st_dev))) { /* mbox file was overwritten, close it if it was open */ index->mbox_dev = st.st_dev; index->mbox_ino = st.st_ino; index->sync_size = (uoff_t)-1; index->sync_stamp = (time_t)-1; mbox_file_close_fd(index); } if (index->sync_stamp != st.st_mtime || index->sync_size != (uoff_t)st.st_size) { mbox_file_close_stream(index); if (changes != NULL) *changes = TRUE; if (!mbox_lock_and_sync_full(index, data_lock_type)) return FALSE; if ((index->set_flags & MAIL_INDEX_HDR_FLAG_REBUILD) != 0) { /* uidvalidity probably changed, rebuild */ if (!index->rebuild(index)) return FALSE; } if (fstat(index->mbox_fd, &st) < 0) return mbox_set_syscall_error(index, "fstat()"); index->sync_stamp = st.st_mtime; index->sync_size = st.st_size; } /* we need some index lock to be able to lock mbox */ if (index->lock_type == MAIL_LOCK_UNLOCK) { if (!index->set_lock(index, MAIL_LOCK_SHARED)) return FALSE; } if (data_lock_type == MAIL_LOCK_UNLOCK) { if (!mbox_unlock(index)) return FALSE; } else { if (!mbox_lock(index, data_lock_type)) return FALSE; } index->mbox_sync_counter = index->mbox_lock_counter; return TRUE; }