maildir-sync.c revision 31ddc75584c5cde53d2e78a737587f2e7fdcb0d2
/*
1. read files in maildir
2. see if they're all found in uidlist read in memory
3. if not, check if uidlist's mtime has changed and read it if so
4. if still not, lock uidlist, sync it once more and generate UIDs for new
files
5. apply changes in transaction log
6. apply changes in maildir to index
*/
/* Copyright (C) 2004 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "buffer.h"
#include "hash.h"
#include "str.h"
#include "maildir-storage.h"
#include "maildir-uidlist.h"
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#define MAILDIR_SYNC_SECS 1
#define MAILDIR_FILENAME_FLAG_FOUND 128
struct maildir_sync_context {
struct index_mailbox *ibox;
struct maildir_uidlist_sync_ctx *uidlist_sync_ctx;
};
void *context __attr_unused__)
{
return 1;
return 0;
"unlink(%s) failed: %m", path);
return -1;
}
void *context)
{
const char *newpath;
enum mail_flags flags;
return 1;
return 0;
return -1;
}
struct mail_index_view *view,
struct mail_index_sync_rec *syncrec)
{
break;
return -1;
NULL) < 0)
return -1;
}
break;
return -1;
syncrec) < 0)
return -1;
}
break;
}
return 0;
}
{
struct mail_index_view *view;
struct mail_index_sync_ctx *sync_ctx;
struct mail_index_sync_rec sync_rec;
int ret;
if (ibox->commit_log_file_seq == 0)
return 0;
if (ret > 0) {
ret = -1;
break;
}
}
if (mail_index_sync_end(sync_ctx) < 0)
ret = -1;
}
if (ret == 0) {
ibox->commit_log_file_seq = 0;
ibox->commit_log_file_offset = 0;
} else {
// FIXME: this is bad - we have to fix this in some way
}
return ret;
}
static struct maildir_sync_context *
{
struct maildir_sync_context *ctx;
return ctx;
}
{
}
const char *old_fname)
{
int ret = 0;
t_push();
i_warning("Fixed duplicate in %s: %s -> %s",
ret = -1;
}
t_pop();
return ret;
}
{
const char *dir;
"opendir(%s) failed: %m", dir);
return -1;
}
continue;
if (move_new) {
str_truncate(src, 0);
str_truncate(dest, 0);
/* moved - we'll look at it later in cur/ dir */
continue;
/* not enough disk space, leave here */
} else {
"rename(%s, %s) failed: %m",
}
}
if (ret <= 0) {
if (ret < 0)
break;
/* possibly duplicate - try fixing it */
ret = -1;
break;
}
}
}
"closedir(%s) failed: %m", dir);
}
return ret < 0 ? -1 : 0;
}
int *new_changed_r, int *cur_changed_r)
{
return -1;
}
return -1;
}
*new_changed_r = TRUE;
}
/* cur/ changed, or delayed cur/ check */
*cur_changed_r = TRUE;
}
return 0;
}
{
struct mail_index_sync_ctx *sync_ctx;
struct mail_index_sync_rec sync_rec;
struct maildir_uidlist_iter_ctx *iter;
struct mail_index_transaction *trans;
struct mail_index_view *view;
const struct mail_index_header *hdr;
const struct mail_index_record *rec;
const char *filename;
enum mail_flags flags;
int ret;
// FIXME: ?
return -1;
}
seq = 0;
seq++;
continue;
}
ret = -1;
break;
}
/* expunged */
goto __again;
}
/* new UID in the middle of the mailbox -
shouldn't happen */
"Maildir sync: UID inserted in the middle "
ret = -1;
break;
}
flags |= MAIL_RECENT;
INDEX_CUSTOM_FLAGS_BYTE_COUNT) != 0) {
}
}
if (ret < 0)
else {
else {
}
}
/* now, sync the index */
ret = -1;
break;
}
}
if (mail_index_sync_end(sync_ctx) < 0)
ret = -1;
if (ret == 0) {
ibox->commit_log_file_seq = 0;
ibox->commit_log_file_offset = 0;
} else {
// FIXME: this is bad - we have to fix this in some way
}
return ret;
}
int *changes_r)
{
return -1;
return -1;
return -1;
if (ret == 0)
return ret;
}
{
int ret;
return -1;
return -1;
return ret;
}
{
struct maildir_sync_context *ctx;
int ret;
return ret;
}
{
struct maildir_sync_context *ctx;
if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 ||
if (ret < 0)
return -1;
}
}