maildir-sync.c revision 31ddc75584c5cde53d2e78a737587f2e7fdcb0d2
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen/*
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 1. read files in maildir
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 2. see if they're all found in uidlist read in memory
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 3. if not, check if uidlist's mtime has changed and read it if so
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 4. if still not, lock uidlist, sync it once more and generate UIDs for new
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen files
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 5. apply changes in transaction log
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen 6. apply changes in maildir to index
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen*/
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen/* Copyright (C) 2004 Timo Sirainen */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "lib.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "ioloop.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "buffer.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "hash.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "str.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "maildir-storage.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "maildir-uidlist.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include <stdio.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include <unistd.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include <dirent.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include <sys/stat.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define MAILDIR_SYNC_SECS 1
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define MAILDIR_FILENAME_FLAG_FOUND 128
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct maildir_sync_context {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct index_mailbox *ibox;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *new_dir, *cur_dir;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct maildir_uidlist_sync_ctx *uidlist_sync_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen};
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_expunge(struct index_mailbox *ibox, const char *path,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen void *context __attr_unused__)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (unlink(path) == 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (errno == ENOENT)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_critical(ibox->box.storage,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "unlink(%s) failed: %m", path);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_sync_flags(struct index_mailbox *ibox, const char *path,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen void *context)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_sync_rec *syncrec = context;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *newpath;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen enum mail_flags flags;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen uint8_t flags8;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen custom_flags_mask_t custom_flags;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen (void)maildir_filename_get_flags(path, &flags, custom_flags);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen flags8 = flags;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_index_sync_flags_apply(syncrec, &flags8, custom_flags);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen newpath = maildir_filename_set_flags(path, flags8, custom_flags);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (rename(path, newpath) == 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (errno == ENOENT)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_critical(ibox->box.storage,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "rename(%s, %s) failed: %m", path, newpath);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_sync_record(struct index_mailbox *ibox,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_view *view,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_sync_rec *syncrec)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen uint32_t seq, uid;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen switch (syncrec->type) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case MAIL_INDEX_SYNC_TYPE_APPEND:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (seq = syncrec->seq1; seq <= syncrec->seq2; seq++) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (mail_index_lookup_uid(view, seq, &uid) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (maildir_file_do(ibox, uid, maildir_expunge,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen NULL) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case MAIL_INDEX_SYNC_TYPE_FLAGS:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (seq = syncrec->seq1; seq <= syncrec->seq2; seq++) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (mail_index_lookup_uid(view, seq, &uid) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (maildir_file_do(ibox, uid, maildir_sync_flags,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen syncrec) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenint maildir_sync_last_commit(struct index_mailbox *ibox)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_view *view;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_sync_ctx *sync_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_index_sync_rec sync_rec;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen int ret;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ibox->commit_log_file_seq == 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ret = mail_index_sync_begin(ibox->index, &sync_ctx, &view,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ibox->commit_log_file_seq,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ibox->commit_log_file_offset);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ret > 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen while ((ret = mail_index_sync_next(sync_ctx, &sync_rec)) > 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (maildir_sync_record(ibox, view, &sync_rec) < 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ret = -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (mail_index_sync_end(sync_ctx) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ret = -1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ret == 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ibox->commit_log_file_seq = 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ibox->commit_log_file_offset = 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen } else {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen // FIXME: this is bad - we have to fix this in some way
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_index_error(ibox);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return ret;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic struct maildir_sync_context *
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmaildir_sync_context_new(struct index_mailbox *ibox)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct maildir_sync_context *ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx = t_new(struct maildir_sync_context, 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx->ibox = ibox;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx->new_dir = t_strconcat(ibox->path, "/new", NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx->cur_dir = t_strconcat(ibox->path, "/cur", NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void maildir_sync_deinit(struct maildir_sync_context *ctx)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ctx->uidlist_sync_ctx != NULL)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen (void)maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_fix_duplicate(struct index_mailbox *ibox, const char *dir,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *old_fname)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char *new_fname, *old_path, *new_path;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen int ret = 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen t_push();
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen old_path = t_strconcat(dir, "/", old_fname, NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen new_fname = maildir_generate_tmp_filename(&ioloop_timeval);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen new_path = t_strconcat(ibox->path, "/new/", new_fname, NULL);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (rename(old_path, new_path) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_warning("Fixed duplicate in %s: %s -> %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->path, old_fname, new_fname);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (errno != ENOENT) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(ibox->box.storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "rename(%s, %s) failed: %m", old_path, new_path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen t_pop();
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int maildir_scan_dir(struct maildir_sync_context *ctx, int new_dir)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_storage *storage = ctx->ibox->box.storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *dir;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DIR *dirp;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen string_t *src, *dest;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct dirent *dp;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int move_new, this_new, ret = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b7b81543899e306c71e6152516d8698416162bcbTimo Sirainen src = t_str_new(1024);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest = t_str_new(1024);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dir = new_dir ? ctx->new_dir : ctx->cur_dir;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dirp = opendir(dir);
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen if (dirp == NULL) {
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen mail_storage_set_critical(storage,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen "opendir(%s) failed: %m", dir);
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen return -1;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen move_new = new_dir;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen while ((dp = readdir(dirp)) != NULL) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (dp->d_name[0] == '.')
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen continue;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen this_new = new_dir;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (move_new) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_truncate(src, 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen str_truncate(dest, 0);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen str_printfa(src, "%s/%s", ctx->new_dir, dp->d_name);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(dest, "%s/%s", ctx->cur_dir, dp->d_name);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (rename(str_c(src), str_c(dest)) == 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ENOTFOUND(errno)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* moved - we'll look at it later in cur/ dir */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen this_new = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen continue;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (ENOSPACE(errno)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not enough disk space, leave here */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen move_new = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "rename(%s, %s) failed: %m",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_c(src), str_c(dest));
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen dp->d_name, this_new);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret <= 0) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ret < 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen break;
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* possibly duplicate - try fixing it */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_fix_duplicate(ctx->ibox,
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen dir, dp->d_name) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (closedir(dirp) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "closedir(%s) failed: %m", dir);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return ret < 0 ? -1 : 0;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen}
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainenstatic int maildir_sync_quick_check(struct maildir_sync_context *ctx,
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen int *new_changed_r, int *cur_changed_r)
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen{
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen struct index_mailbox *ibox = ctx->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct stat st;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t new_mtime, cur_mtime;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *new_changed_r = *cur_changed_r = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stat(ctx->new_dir, &st) < 0) {
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen mail_storage_set_critical(ibox->box.storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "stat(%s) failed: %m", ctx->new_dir);
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen return -1;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen new_mtime = st.st_mtime;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stat(ctx->cur_dir, &st) < 0) {
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen mail_storage_set_critical(ibox->box.storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "stat(%s) failed: %m", ctx->cur_dir);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen cur_mtime = st.st_mtime;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (new_mtime != ibox->last_new_mtime ||
659fe5d24825b160cae512538088020d97a60239Timo Sirainen new_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS) {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen *new_changed_r = TRUE;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen ibox->last_new_mtime = new_mtime;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (cur_mtime != ibox->last_cur_mtime ||
659fe5d24825b160cae512538088020d97a60239Timo Sirainen (cur_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS &&
659fe5d24825b160cae512538088020d97a60239Timo Sirainen ioloop_time - ibox->last_sync > MAILDIR_SYNC_SECS)) {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen /* cur/ changed, or delayed cur/ check */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *cur_changed_r = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->last_cur_mtime = cur_mtime;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->last_sync = ioloop_time;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainenstatic int maildir_sync_index(struct maildir_sync_context *ctx)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen{
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct index_mailbox *ibox = ctx->ibox;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_index_sync_ctx *sync_ctx;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_index_sync_rec sync_rec;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct maildir_uidlist_iter_ctx *iter;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_index_transaction *trans;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct mail_index_view *view;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const struct mail_index_header *hdr;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen const struct mail_index_record *rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq, uid, uflags;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen const char *filename;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen enum mail_flags flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen custom_flags_mask_t custom_flags;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen int ret;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (mail_index_sync_begin(ibox->index, &sync_ctx, &view,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen (uint32_t)-1, (uoff_t)-1) <= 0) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen // FIXME: ?
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return -1;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ret = mail_index_get_header(view, &hdr);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen i_assert(ret == 0); /* view is locked, can't happen */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen trans = mail_index_transaction_begin(view, FALSE);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen seq = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen iter = maildir_uidlist_iter_init(ibox->uidlist);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_filename_get_flags(filename, &flags, custom_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen __again:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq > hdr->messages_count) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_append(trans, uid, &seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_update_flags(trans, seq, MODIFY_REPLACE,
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen flags, custom_flags);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen continue;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup(view, seq, &rec) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_index_error(ibox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen if (rec->uid < uid) {
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen /* expunged */
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen mail_index_expunge(trans, seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen goto __again;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (rec->uid > uid) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* new UID in the middle of the mailbox -
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen shouldn't happen */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen mail_storage_set_critical(ibox->box.storage,
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen "Maildir sync: UID inserted in the middle "
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen "of mailbox (%u > %u)", rec->uid, uid);
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen (void)mail_index_reset(ibox->index);
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen ret = -1;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_filename_get_flags(filename, &flags, custom_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (rec->flags & MAIL_RECENT)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen flags |= MAIL_RECENT;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if ((uint8_t)flags != (rec->flags & MAIL_FLAGS_MASK) ||
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen memcmp(custom_flags, rec->custom_flags,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen INDEX_CUSTOM_FLAGS_BYTE_COUNT) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_update_flags(trans, seq, MODIFY_REPLACE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flags, custom_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_uidlist_iter_deinit(iter);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_transaction_rollback(trans);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_transaction_commit(trans, &seq, &offset) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_index_error(ibox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->commit_log_file_seq = seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->commit_log_file_offset = offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* now, sync the index */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while ((ret = mail_index_sync_next(sync_ctx, &sync_rec)) > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_sync_record(ibox, view, &sync_rec) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_sync_end(sync_ctx) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->commit_log_file_seq = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->commit_log_file_offset = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen // FIXME: this is bad - we have to fix this in some way
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_index_error(ibox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int maildir_sync_context(struct maildir_sync_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int *changes_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret, new_changed, cur_changed;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_sync_quick_check(ctx, &new_changed, &cur_changed) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->uidlist_sync_ctx = maildir_uidlist_sync_init(ctx->ibox->uidlist);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_scan_dir(ctx, TRUE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_scan_dir(ctx, FALSE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->uidlist_sync_ctx = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = maildir_sync_index(ctx);
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen return ret;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int maildir_sync_context_readonly(struct maildir_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->uidlist_sync_ctx = maildir_uidlist_sync_init(ctx->ibox->uidlist);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_scan_dir(ctx, TRUE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_scan_dir(ctx, FALSE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c282435b57b6f9696fc12d99ea70468b7bdfe24cTimo Sirainen ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx);
c282435b57b6f9696fc12d99ea70468b7bdfe24cTimo Sirainen ctx->uidlist_sync_ctx = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenint maildir_storage_sync_readonly(struct index_mailbox *ibox)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen struct maildir_sync_context *ctx;
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen int ret;
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ctx = maildir_sync_context_new(ibox);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ret = maildir_sync_context_readonly(ctx);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen maildir_sync_deinit(ctx);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen return ret;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenint maildir_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)box;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen struct maildir_sync_context *ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int changes, ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ibox->sync_last_check = ioloop_time;
ead79af955bccc360de08c150918474c1809748eTimo Sirainen
ead79af955bccc360de08c150918474c1809748eTimo Sirainen ctx = maildir_sync_context_new(ibox);
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen ret = maildir_sync_context(ctx, &changes);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen maildir_sync_deinit(ctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen if (ret < 0)
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen return -1;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen }
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen return index_storage_sync(box, flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen