dbox-storage.c revision e59faf65ce864fe95dc00f5d52b8323cdbd0608a
/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "randgen.h"
#include "hex-binary.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "unlink-old-files.h"
#include "mailbox-uidvalidity.h"
#include "mailbox-list-private.h"
#include "index-storage.h"
#include "dbox-storage.h"
#include <stdio.h>
struct mailbox_list_settings *set)
{
}
{
const char *path;
}
{
else {
}
}
static bool
{
return FALSE;
/* check once in a while if there are temp files to clean up */
/* there haven't been any changes to this directory since we
last checked it. */
/* time to scan */
const char *prefix =
}
return TRUE;
}
{
"dbox doesn't support streamed mailboxes");
return -1;
}
return index_storage_mailbox_open(box);
/* INBOX always exists, create it */
return -1;
}
return -1;
return -1;
} else {
return -1;
}
}
static const char *
{
const char *root;
unsigned int len;
return NULL;
/* can't determine the alt path - shouldn't happen */
return NULL;
}
}
{
"Mailbox already exists");
return -1;
}
if (directory) {
return 0;
"Mailbox already exists");
"mkdir(%s) failed: %m", path);
}
return -1;
}
/* make sure the alt path doesn't exist yet. it shouldn't (except with
left it lying around we don't want to start overwriting files in
it. */
"Mailbox already exists");
return -1;
}
}
const char *mailbox_name ATTR_UNUSED,
enum mailbox_list_file_type type,
enum mailbox_info_flags *flags)
{
const char *path, *maildir_path;
int ret = 1;
/* try to avoid stat() with these checks */
if (type != MAILBOX_LIST_FILE_TYPE_DIR &&
/* it's a file */
return 0;
}
/* need to stat() then */
/* non-directory */
ret = 0;
/* no subdirectories */
*flags |= MAILBOX_NOCHILDREN;
/* default configuration: we have one directory
containing the mailboxes. if there are 3 links,
either this is a selectable mailbox without children
or non-selectable mailbox with children */
*flags |= MAILBOX_CHILDREN;
} else {
/* non-default configuration: all subdirectories are
child mailboxes. */
*flags |= MAILBOX_CHILDREN;
}
/* doesn't exist - probably a non-existing subscribed mailbox */
*flags |= MAILBOX_NONEXISTENT;
} else {
/* non-selectable. probably either access denied, or symlink
destination not found. don't bother logging errors. */
*flags |= MAILBOX_NOSELECT;
}
/* make sure it's a selectable mailbox */
*flags |= MAILBOX_NOSELECT;
/* now we know what link count 3 means. */
if ((*flags & MAILBOX_NOSELECT) != 0)
*flags |= MAILBOX_CHILDREN;
else
*flags |= MAILBOX_NOCHILDREN;
}
}
return ret;
}
static int
const char *oldname,
struct mailbox_list *newlist,
const char *newname,
{
const char *path;
return 0;
/* destination dbox storage doesn't have alt-path defined.
we can't do the rename easily. */
"Can't rename mailboxes across specified storages.");
return -1;
}
return 1;
}
const char *oldname,
struct mailbox_list *newlist,
const char *newname)
{
const char *alt_oldpath, *alt_newpath;
int ret;
&alt_oldpath, &alt_newpath);
if (ret <= 0)
return ret;
/* race condition or a directory left there lying around?
safest to just report error. */
"Target mailbox already exists");
return -1;
return -1;
}
return 0;
}
bool rename_children)
{
int ret;
&alt_newpath);
if (ret <= 0)
return ret;
/* ok */
if (!rename_children) {
"rmdir(%s) failed: %m", path);
}
}
/* renaming is done already, so just log the error */
}
return 0;
}
static const char *dbox_get_trash_dest(const char *trash_dir)
{
const char *path;
unsigned char randbuf[16];
do {
return path;
}
const char **trash_dest_r)
{
int ret;
/* first try renaming the actual mailbox to trash directory */
/* either source mailbox doesn't exist or trash directory
doesn't exist. try creating the trash and retrying. */
const char *origin;
"mkdir(%s) failed: %m", trash_dir);
return -1;
}
}
if (ret == 0)
return 1;
return -1;
} else {
/* mailbox not found - what about the directory? */
/* delete the directory */
return -1;
} else if (!mailbox_list_set_error_from_errno(list)) {
path);
return -1;
}
return 0;
}
}
int ret, const char *trash_dest)
{
if (ret > 0) {
"unlink_directory(%s) failed: %m", trash_dest);
ret = -1;
}
/* if there's an alt path, delete it too */
"unlink_directory(%s) failed: %m", alt_path);
ret = -1;
}
}
/* try to delete the parent directory also */
}
return ret;
if (deleted)
return ret;
t_strdup_printf("Directory %s isn't empty, "
"can't delete it.", name));
} else if (!mailbox_list_set_error_from_errno(list)) {
path);
}
return -1;
}