maildir-util.c revision a8c1d873ebe624cf65893d79e1a509203116cb9a
/* Copyright (c) 2004-2012 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "str.h"
#include "mkdir-parents.h"
#include "mailbox-list-private.h"
#include "maildir-storage.h"
#include "maildir-uidlist.h"
#include "maildir-keywords.h"
#include "maildir-filename-flags.h"
#include "maildir-sync.h"
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <utime.h>
#define MAILDIR_RESYNC_RETRY_COUNT 10
static const char *
const char *fname,
bool *have_flags_r)
{
struct maildir_keywords_sync_ctx *kw_ctx;
enum mail_flags flags;
const char *p;
*have_flags_r = FALSE;
return fname;
}
if (array_count(&keywords) == 0) {
} else {
*have_flags_r = TRUE;
}
if (*have_flags_r) {
/* don't even bother looking into new/ dir */
} else if ((*uidlist_flags & MAILDIR_UIDLIST_REC_FLAG_MOVED) == 0 &&
((*uidlist_flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 ||
/* probably in new/ dir, drop ":2," from fname */
if (p != NULL)
}
return fname;
}
{
bool have_flags;
int ret;
if (ret <= 0)
if ((flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
/* let's see if we can guess the filename based on index */
&flags, &have_flags);
}
ret = 0;
if ((flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0) {
/* probably in new/ dir */
}
if (ret == 0) {
}
/* file was found. make sure we remember its latest name. */
} else if (ret == 0 &&
(flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0) {
/* file wasn't found. mark this message nonsynced, so we can
retry the lookup by guessing the flags */
}
return ret;
}
void *context ATTR_UNUSED)
{
/* most likely a symlink pointing to a nonexistent file */
"Maildir: Symlink destination doesn't exist: %s", path);
return -2;
} else {
"maildir_file_do(%s): Filename keeps changing", path);
return -1;
}
}
{
int i, ret;
T_BEGIN {
} T_END;
/* try guessing again with refreshed flags */
if (maildir_sync_refresh_flags_view(mbox) == 0)
} T_END;
for (i = 0; i < MAILDIR_RESYNC_RETRY_COUNT && ret == 0; i++) {
/* file is either renamed or deleted. sync the maildir and
see which one. if file appears to be renamed constantly,
don't try to open it more than 10 times. */
return -1;
T_BEGIN {
} T_END;
}
if (i == MAILDIR_RESYNC_RETRY_COUNT) T_BEGIN {
} T_END;
}
{
perm->file_create_gid_origin) == 0)
return 0;
switch (errno) {
case EEXIST:
return 0;
case ENOENT:
if (type == MAILBOX_LIST_PATH_TYPE_MAILBOX ||
/* mailbox was being deleted just now */
return -1;
}
/* should work now, try again */
}
/* fall through */
default:
"mkdir(%s) failed: %m", path);
return -1;
}
}
{
const char *path;
unsigned int i;
/* @UNSAFE: get a list of directories we want to create */
for (i = 0; i < N_ELEMENTS(subdirs); i++) {
}
for (i = 0; i < N_ELEMENTS(dirs); i++) {
continue;
"stat(%s) failed: %m", path);
break;
}
break;
}
}
{
int ret;
else {
}
return FALSE;
}
/* maildir itself exists. create all of its subdirectories in case
they got lost. */
T_BEGIN {
} T_END;
}
{
/* There's a directory in maildir, get rid of it.
In some installations this was caused by a messed up configuration
Also Dovecot v2.0.0 - v2.0.4 sometimes may have renamed tmp/
directory under new/ or cur/. */
"Maildir: rmdir()ed unwanted empty directory: %s",
path);
return 1;
/* someone else rmdired or renamed it */
return 0;
"Maildir: Found unwanted directory %s, "
"but rmdir() failed: %m", path);
return -1;
}
/* It's not safe to delete this directory since it has some files in it,
but it's also not helpful to log this message over and over again.
Get rid of this error by renaming the directory elsewhere */
fname = p + 1;
"Maildir: renamed unwanted directory %s to %s",
return 1;
/* someone else renamed it (could have been flag change) */
return 0;
} else {
"Maildir: Found unwanted directory, "
return -1;
}
}