maildir-sync-index.c revision 6b77095184aeb8a9976a74fa9ba1a06740f40d0e
/* Copyright (C) 2007 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "maildir-storage.h"
#include "index-sync-changes.h"
#include "maildir-uidlist.h"
#include "maildir-keywords.h"
#include "maildir-filename.h"
#include "maildir-sync.h"
#include <stdio.h>
#include <unistd.h>
struct maildir_index_sync_context {
struct maildir_mailbox *mbox;
struct maildir_sync_context *maildir_sync_ctx;
struct mail_index_view *view;
struct mail_index_sync_ctx *sync_ctx;
struct mail_index_transaction *trans;
struct maildir_uidlist_sync_ctx *uidlist_sync_ctx;
struct index_sync_changes_context *sync_changes;
enum mail_flags flags;
bool changed;
};
struct maildir_keywords_sync_ctx *
{
return ctx->keywords_sync_ctx;
}
struct maildir_index_sync_context *ctx)
{
}
return 1;
}
return 0;
"unlink(%s) failed: %m", path);
return -1;
}
struct maildir_index_sync_context *ctx)
{
enum mailbox_sync_type sync_type;
fname++;
/* get the current flags and keywords */
/* apply changes */
/* and try renaming with the new name */
return 1;
}
return 0;
}
return -1;
}
{
int ret;
if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
/* partial syncing */
return;
}
/* most likely a race condition: we read the maildir, then someone else
expunged messages and committed changes to index. so, this message
shouldn't actually exist. */
if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RACING) == 0) {
/* mark it racy and check in next sync */
return;
}
&ctx->uidlist_sync_ctx);
}
/* give the new UID to it immediately */
i_warning("Maildir %s: Expunged message reappeared, giving a new UID "
}
struct maildir_sync_context *maildir_sync_ctx,
struct maildir_index_sync_context **ctx_r)
{
struct maildir_index_sync_context *ctx;
struct mail_index_sync_ctx *sync_ctx;
struct mail_index_view *view;
struct mail_index_transaction *trans;
return -1;
}
return 0;
}
{
else {
/* Set syncing_commit=TRUE so that if any sync callbacks try
to access mails which got lost (eg. expunge callback trying
to open the file which was just unlinked) we don't try to
start a second index sync and crash. */
ret = -1;
} else {
}
}
return ret;
}
static void
struct mail_index_transaction *trans)
{
const void *data;
data_size = 0;
/* nothing changed */
} else {
&mbox->maildir_hdr,
sizeof(mbox->maildir_hdr));
}
}
bool partial)
{
struct maildir_uidlist_iter_ctx *iter;
const struct mail_index_header *hdr;
struct mail_index_header empty_hdr;
const struct mail_index_record *rec;
const char *filename;
unsigned int changes = 0;
int ret = 0;
/* uidvalidity changed and index isn't being synced for the
first time, reset the index so we can add all messages as
new */
i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)",
}
/* the private flags are kept only in indexes. don't use them
at all even for newly seen mails */
if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
(uflags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 &&
(uflags & MAILDIR_UIDLIST_REC_FLAG_MOVED) == 0) {
/* mail is recent for next session as well */
}
if (uid < hdr_next_uid) {
seq--;
continue;
}
struct mail_keywords *kw;
MODIFY_REPLACE, kw);
}
continue;
}
ret = -1;
break;
}
/* expunged */
goto __again;
}
seq--;
continue;
}
&expunged) < 0) {
ret = -1;
break;
}
if (expunged) {
maildir_expunge, ctx) >= 0) {
/* successful expunge */
}
if ((++changes % MAILDIR_SLOW_MOVE_COUNT) == 0)
continue;
}
/* the private flags are stored only in indexes, keep them */
} else {
}
}
if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
/* partial syncing */
/* we last saw this mail in new/, but it's
not there anymore. possibly expunged,
make sure. */
full_rescan = TRUE;
}
continue;
}
/* apply flag changes to maildir */
maildir_sync_flags, ctx) < 0)
if ((++changes % MAILDIR_SLOW_MOVE_COUNT) == 0)
}
/* we haven't been able to update maildir with this
record's flag changes. don't sync them. */
continue;
}
/* just remove recent flag */
}
/* update keywords if they have changed */
ret = -1;
break;
}
struct mail_keywords *kw;
MODIFY_REPLACE, kw);
}
}
ret = -1;
}
if (!partial) {
/* expunge the rest */
}
if (uid_validity == 0) {
}
}
if (hdr_next_uid < next_uid) {
}
}