mailbox-list-fs.c revision 638600575ee95f2513c683ef09cb188f76eacd22
/* Copyright (c) 2006-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "hostpid.h"
#include "mkdir-parents.h"
#include "mailbox-log.h"
#include "subscription-file.h"
#include "mail-storage.h"
#include "mailbox-list-subscriptions.h"
#include "mailbox-list-delete.h"
#include "mailbox-list-fs.h"
#include <stdio.h>
#include <unistd.h>
#define GLOBAL_TEMP_PREFIX ".temp."
extern struct mailbox_list fs_mailbox_list;
static struct mailbox_list *fs_list_alloc(void)
{
struct fs_mailbox_list *list;
}
{
}
{
return '/';
}
static const char *
{
set->maildir_name);
} else {
}
}
static int
{
/* return root directories */
}
if (type == MAILBOX_LIST_PATH_TYPE_INDEX &&
return 0;
return 1;
}
switch (type) {
return 1;
}
break;
return 0;
/* maildir_name is for the mailbox, caller is asking
for the directory name */
return 1;
}
break;
break;
return 0;
break;
return 1;
}
break;
return 1;
}
/* fall through */
return 0;
return 1;
}
break;
return 0;
return 1;
i_unreached();
}
if (type == MAILBOX_LIST_PATH_TYPE_ALT_DIR ||
/* don't use inbox_path */
/* If INBOX is a file, index and control directories are
located in root directory. */
return 1;
}
}
return 0;
} else {
set->maildir_name);
}
return 1;
}
static const char *
{
}
static const char *
{
/* pattern overrides reference */
} else if (*ref != '\0') {
/* merge reference and pattern */
}
return pattern;
}
{
enum mailbox_list_path_type type;
const char *path;
"Subscriptions not supported");
return -1;
}
}
{
const char *root_dir;
}
static int
{
bool rmdir_path;
int ret;
if (ret < 0)
return -1;
if (ret > 0) {
/* try to delete the parent directory */
&path) <= 0)
i_unreached();
"rmdir(%s) failed: %m", path);
}
return 0;
}
}
&path) <= 0)
i_unreached();
}
{
const char *path;
int ret;
if (ret < 0)
return -1;
} else {
}
}
const char *path)
{
return -1;
return 0;
}
{
char sep;
int ret;
&path) <= 0)
i_unreached();
/* it should exist only in the mail directory */
if (ret == 0)
return 0;
/* the primary list location is the index directory, but it
exists in both index and mail directories. */
&path) <= 0)
i_unreached();
return 0;
/* partial existence: exists in _DIR, but not in
_INDEX. return success anyway. */
return 0;
}
/* a) both directories didn't exist
b) index directory couldn't be rmdir()ed for some reason */
}
/* mbox workaround: if only .imap/ directory is preventing the
deletion, remove it */
&child_path) > 0 &&
/* drop the "/child" part out. */
/* try again */
return 0;
}
}
"Mailbox has children, delete them first");
} else {
}
return -1;
}
{
return 0;
return 0;
/* make sure the newparent exists */
struct mailbox_permissions perm;
perm.file_create_gid_origin) < 0 &&
return -1;
"mkdir_parents(%s) failed: %m", newparent);
return -1;
}
}
return -1;
}
"rmdir(%s) failed: %m", oldpath);
}
}
/* avoid leaving empty directories lying around */
return 0;
}
const char *oldname,
struct mailbox_list *newlist,
const char *newname)
{
struct mail_storage *oldstorage;
bool rmdir_parent = FALSE;
return -1;
MAILBOX_LIST_PATH_TYPE_DIR, &oldpath) <= 0 ||
MAILBOX_LIST_PATH_TYPE_DIR, &newpath) <= 0)
i_unreached();
&alt_newpath) < 0)
i_unreached();
/* most likely INBOX */
t_strdup_printf("Renaming %s isn't supported.",
oldname));
return -1;
}
/* if we're renaming under another mailbox, require its permissions
to be same as ours. */
"Renaming not supported across conflicting "
"directory permissions");
return -1;
}
/* create the hierarchy */
if (p != NULL) {
p = t_strdup_until(newpath, p);
new_perm.file_create_gid_origin) < 0 &&
return -1;
"mkdir_parents(%s) failed: %m", p);
return -1;
}
}
/* first check that the destination mailbox doesn't exist.
this is racy, but we need to be atomic and there's hardly any
possibility that someone actually tries to rename two mailboxes
to same new one */
"Target mailbox already exists");
return -1;
"Target mailbox doesn't allow inferior mailboxes");
return -1;
newpath);
return -1;
}
if (alt_newpath != NULL) {
/* race condition or a directory left there lying around?
safest to just report error. */
"Target mailbox already exists");
return -1;
return -1;
}
}
} else if (!mailbox_list_set_error_from_errno(oldlist)) {
}
return -1;
}
if (alt_newpath != NULL) {
}
return 0;
}
struct mailbox_list fs_mailbox_list = {
.props = 0,
.v = {
.alloc = fs_list_alloc,
.deinit = fs_list_deinit,
}
};