static int mbox_file_open_latest(struct mbox_lock_context *ctx, int lock_type) { struct mbox_mailbox *mbox = ctx->mbox; struct stat st; if (ctx->checked_file || lock_type == F_UNLCK) return 0; if (mbox->mbox_fd != -1) { /* we could flush NFS file handle cache here if we wanted to be sure that the file is latest, but mbox files get rarely deleted and the flushing might cause errors (e.g. EBUSY for trying to flush a /var/mail mountpoint) */ if (nfs_safe_stat(mailbox_get_path(&mbox->box), &st) < 0) { if (errno == ENOENT) mailbox_set_deleted(&mbox->box); else mbox_set_syscall_error(mbox, "stat()"); return -1; } if (st.st_ino != mbox->mbox_ino || !CMP_DEV_T(st.st_dev, mbox->mbox_dev)) mbox_file_close(mbox); } if (mbox->mbox_fd == -1) { if (mbox_file_open(mbox) < 0) return -1; } ctx->checked_file = TRUE; return 0; }
static void mbox_mailbox_close(struct mailbox *box) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; const struct mail_index_header *hdr; enum mbox_sync_flags sync_flags = 0; if (mbox->mbox_stream != NULL && istream_raw_mbox_is_corrupted(mbox->mbox_stream)) { /* clear the corruption by forcing a full resync */ sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC; } if (box->view != NULL) { hdr = mail_index_get_header(box->view); if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 && !mbox_is_backend_readonly(mbox)) { /* we've done changes to mbox which haven't been written yet. do it now. */ sync_flags |= MBOX_SYNC_REWRITE; } } if (sync_flags != 0 && !mbox->invalid_mbox_file) (void)mbox_sync(mbox, sync_flags); if (mbox->mbox_global_lock_id != 0) mbox_unlock(mbox, mbox->mbox_global_lock_id); if (mbox->keep_lock_to != NULL) timeout_remove(&mbox->keep_lock_to); mbox_file_close(mbox); if (mbox->mbox_file_stream != NULL) i_stream_destroy(&mbox->mbox_file_stream); index_storage_mailbox_close(box); }