mailbox-list-fs.c revision ff7056842f14fd3b30a2d327dfab165b9d15dd30
/* Copyright (C) 2006-2007 Timo Sirainen */
#include "lib.h"
#include "hostpid.h"
#include "home-expand.h"
#include "mkdir-parents.h"
#include "subscription-file.h"
#include "mailbox-list-fs.h"
#include <stdio.h>
#include <unistd.h>
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)
{
/* return root directories */
switch (type) {
}
i_unreached();
}
if (home_try_expand(&name) == 0)
return name;
/* fallback to using ~dir */
}
switch (type) {
break;
break;
name);
break;
return "";
}
break;
}
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 *
{
return list->temp_prefix;
}
static const char *
{
/* mask overrides reference */
} else if (*ref != '\0') {
/* merge reference and mask */
}
return mask;
}
{
const char *path;
}
{
/* let the backend handle the rest */
}
{
/* create the hierarchy */
if (p != NULL) {
p = t_strdup_until(newpath, p);
if (mkdir_parents(p, CREATE_MODE) < 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;
}
/* 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(list)) {
}
return -1;
}
/* we need to rename the index directory as well */
if (*old_indexdir != '\0') {
"rename(%s, %s) failed: %m",
}
}
return 0;
}
struct mailbox_list fs_mailbox_list = {
{
NULL,
}
};