dbox-storage.c revision 5f8c5ba7dae54b4df12115b1984874493cc3692f
/* 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-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. */
struct rename_context {
bool found;
const char *newname;
};
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 there's no "../" stuff */
for (p = mask; *p != '\0'; p++) {
return FALSE;
newdir = p[0] == '/';
}
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 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;
"Maildir doesn't support streamed mailboxes");
return NULL;
}
return NULL;
}
name);
return NULL;
} else {
path);
return NULL;
}
}
const char *name,
bool directory __attr_unused__)
{
return -1;
}
return -1;
}
}
const char *name)
{
return -1;
}
return -1;
}
"Mailbox doesn't exist: %s", name);
return -1;
}
/* exists as a \NoSelect mailbox */
return 0;
"Mailbox has only submailboxes: %s", name);
} else {
"rmdir() failed for %s: %m", path);
}
return -1;
}
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. */
"Mailbox doesn't exist: %s", oldname);
} 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 = {
{
}
};