dbox-storage.c revision 68801241c575c0ae8f5574cf0b0792bdff63c95b
/* Copyright (C) 2005 Timo Sirainen */
#include "lib.h"
#include "home-expand.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "subscription-file/subscription-file.h"
#include "mail-copy.h"
#include "index-mail.h"
#include "dbox-uidlist.h"
#include "dbox-sync.h"
#include "dbox-file.h"
#include "dbox-storage.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Don't allow creating too long mailbox names. They could start causing
problems when they reach the limit. */
extern struct mail_storage dbox_storage;
extern struct mailbox dbox_mailbox;
{
else
return FALSE;
return TRUE;
}
static struct mail_storage *
enum mail_storage_flags flags,
{
struct dbox_storage *storage;
struct index_storage *istorage;
/* we won't do any guessing for this format. */
if (debug)
i_info("dbox: mailbox location not given");
return NULL;
}
/* <root dir> [:INDEX=<dir>] */
if (debug)
if (p == NULL)
else {
do {
p++;
p = strchr(p, ':');
} while (p != NULL);
}
/* strip trailing '/' */
if (debug) {
i_info("dbox: root=%s, index=%s",
}
return NULL;
}
}
{
}
{
const char *path;
if (debug)
return FALSE;
}
if (debug)
return FALSE;
}
return TRUE;
}
{
const char *p;
bool newdir;
return TRUE;
/* 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 = mask; *p != '\0'; p++) {
if (newdir) {
if (p[0] == '/')
return FALSE; /* // */
if (p[0] == '.') {
if (p[1] == '/')
return FALSE; /* ./ */
if (p[1] == '.' && p[2] == '/')
return FALSE; /* ../ */
}
if (strncmp(p, DBOX_MAILDIR_NAME,
sizeof(DBOX_MAILDIR_NAME)-1) == 0 &&
/* don't allow the dbox-Mails directory to be
used as part of the mask */
return FALSE;
}
}
newdir = p[0] == '/';
}
/* "." and ".." aren't allowed. */
return FALSE;
}
return TRUE;
}
const char *name)
{
return FALSE;
}
const char *name)
{
return FALSE;
}
static const char *
{
return home_expand(name);
}
{
const char *path;
if (dbox_handle_errors(storage))
return -1;
"mkdir(%s) failed: %m", dir);
return -1;
}
return 0;
}
{
const char *dir;
return 0;
return 0;
"mkdir(%s) failed: %m", dir);
return -1;
}
return 0;
}
{
return FALSE;
}
static const char *
{
const char *p;
return NULL;
}
}
static const char *
{
if (*name == '\0')
}
static const char *
{
}
static struct mailbox *
enum mailbox_open_flags flags)
{
struct dbox_mailbox *mbox;
struct mail_index *index;
return NULL;
return NULL;
FALSE) < 0) {
/* the memory was already freed */
return NULL;
}
else
else
else
}
static struct mailbox *
{
const char *path;
"dbox doesn't support streamed mailboxes");
return NULL;
}
return NULL;
}
return NULL;
} else {
path);
return NULL;
}
}
const char *name,
bool directory __attr_unused__)
{
return -1;
}
return -1;
}
}
const char *name)
{
return -1;
}
return -1;
}
return -1;
}
/* exists as a \NoSelect mailbox */
return 0;
"Mailbox has only submailboxes: %s", name);
} else {
"rmdir() failed for %s: %m", path);
}
return -1;
}
/* make sure the indexes are closed before trying to delete the
directory that contains them */
if (!dbox_handle_errors(istorage)) {
"unlink_directory() failed for %s: %m",
}
return -1;
}
/* try also removing the root directory. it can fail if the deleted
mailbox had submailboxes. do it as long as we can. */
if (p == NULL)
break;
}
return 0;
}
{
return -1;
}
/* create the hierarchy */
if (p != NULL) {
p = t_strdup_until(newpath, p);
if (mkdir_parents(p, CREATE_MODE) < 0) {
if (dbox_handle_errors(storage))
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 (!dbox_handle_errors(storage)) {
}
return -1;
}
return 0;
}
{
const char *path;
}
const char *name,
enum mailbox_name_status *status)
{
return 0;
}
return 0;
}
return 0;
}
return 0;
} else {
path);
return -1;
}
}
{
return 0;
}
static void
{
return;
}
}
struct mail_storage dbox_storage = {
{
}
};
struct mailbox dbox_mailbox = {
{
}
};