mailbox-list-fs.c revision 91b203fd2132510a47a4b34252c0ae0efd688a19
/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "hostpid.h"
#include "mkdir-parents.h"
#include "subscription-file.h"
#include "mail-storage.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 FALSE;
return TRUE;
}
static bool
{
const char *p;
bool newdir;
/* make sure it's not absolute path */
return FALSE;
/* make sure the mailbox name doesn't contain any foolishness:
"../" could give access outside the mailbox directory.
"./" and "//" could fool ACL checks. */
for (p = name; *p != '\0'; p++) {
if (newdir) {
if (p[0] == '/')
return FALSE; /* // */
if (p[0] == '.') {
if (p[1] == '/' || p[1] == '\0')
return FALSE; /* ./ */
if (p[1] == '.' &&
(p[2] == '/' || p[2] == '\0'))
return FALSE; /* ../ */
}
if (maildir_len > 0 &&
maildir_len) == 0 &&
/* don't allow maildir_name to be used as part
of the mailbox name */
return FALSE;
}
}
newdir = p[0] == '/';
}
/* "." and ".." aren't allowed. */
return FALSE;
}
return TRUE;
}
static bool
{
return TRUE;
}
static bool
{
return FALSE;
return TRUE;
}
static bool
{
return FALSE;
return FALSE;
return TRUE;
return FALSE;
}
static const char *
enum mailbox_list_path_type type)
{
const char *path;
/* return root directories */
switch (type) {
}
i_unreached();
}
return name;
switch (type) {
break;
break;
break;
return "";
}
break;
}
/* If INBOX is a file, index and control directories are located
in root directory. */
return set->inbox_path;
} else {
set->maildir_name);
}
}
static int
enum mailbox_name_status *status)
{
const char *path;
return 0;
}
return 0;
}
return 0;
return 0;
} else {
return -1;
}
}
static const char *
{
}
static const char *
{
/* pattern overrides reference */
} else if (*ref != '\0') {
/* merge reference and pattern */
}
return pattern;
}
{
const char *path;
}
{
/* let the backend handle the rest */
}
{
return 0;
return -1;
}
"rmdir(%s) failed: %m", oldpath);
}
}
return 0;
}
const char *oldname,
struct mailbox_list *newlist,
const char *newname, bool rename_children)
{
if (rename_children)
else {
/* we can't do this, our children would get renamed with us */
"Can't rename mailbox without its children.");
return -1;
}
/* create the hierarchy */
if (p != NULL) {
p = t_strdup_until(newpath, p);
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;
}
return -1;
}
/* NOTE: renaming INBOX works just fine with us, it's simply recreated
the next time it's needed. */
} else if (!mailbox_list_set_error_from_errno(oldlist)) {
}
return -1;
}
if (!rename_children) {
/* if there are no child mailboxes, get rid of the mailbox
directory entirely. */
rmdir_parent = TRUE;
"rmdir(%s) failed: %m", oldpath);
}
}
return 0;
}
struct mailbox_list fs_mailbox_list = {
{
NULL,
NULL,
}
};