maildir-sync.c revision b7b81543899e306c71e6152516d8698416162bcb
/*
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;
int partial;
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, 0) < 0)
ret = -1;
}
if (ret == 0) {
ibox->commit_log_file_seq = 0;
ibox->commit_log_file_offset = 0;
} else {
}
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;
flags = 0;
if (move_new) {
str_truncate(src, 0);
str_truncate(dest, 0);
/* we moved it - it's \Recent for use */
/* someone else moved it already */
/* not enough disk space, leave here */
} else {
"rename(%s, %s) failed: %m",
}
} else if (new_dir) {
}
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)
{
const struct mail_index_header *hdr;
return -1;
}
return -1;
}
if (ibox->last_cur_mtime == 0) {
/* first sync in this session, get cur stamp from index */
}
*new_changed_r = TRUE;
}
(ibox->last_cur_dirty &&
/* 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;
return -1;
}
seq = 0;
seq++;
if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
/* partial syncing */
continue;
}
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;
}
INDEX_CUSTOM_FLAGS_BYTE_COUNT) != 0) {
}
}
/* expunge the rest */
}
if (ret < 0)
else {
else {
}
}
/* now, sync the index */
ret = -1;
break;
}
}
ret = -1;
if (ret == 0) {
ibox->commit_log_file_seq = 0;
ibox->commit_log_file_offset = 0;
} else {
}
return ret;
}
{
return -1;
if (!new_changed && !cur_changed)
return 0;
return -1;
if (cur_changed) {
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;
int ret;
if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 ||
if (ret < 0)
return -1;
}
}