mbox-storage.c revision 0992011130e9d0a498ca860ddbe4028398a530c5
/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "istream.h"
#include "restrict-access.h"
#include "master-service.h"
#include "mailbox-list-private.h"
#include "mbox-storage.h"
#include "mbox-lock.h"
#include "mbox-file.h"
#include "mbox-sync-private.h"
#include "istream-raw-mbox.h"
#include "mail-copy.h"
#include "index-mail.h"
/* How often to touch the dotlock file when using KEEP_LOCKED flag */
/* Assume that if atime < mtime, there are new mails. If it's good enough for
UW-IMAP, it's good enough for us. */
#define STAT_GET_MARKED(st) \
#define MBOX_LIST_CONTEXT(obj) \
struct mbox_mailbox_list {
const struct mbox_settings *set;
};
/* NOTE: must be sorted for istream-header-filter. Note that it's not such
a good idea to change this list, as the messages will then change from
client's point of view. So if you do it, change all mailboxes' UIDVALIDITY
so all caches are reset. */
const char *mbox_hide_headers[] = {
"Content-Length",
"Status",
"X-IMAP",
"X-IMAPbase",
"X-Keywords",
"X-Status",
"X-UID"
};
/* A bit ugly duplification of the above list. It's safe to modify this list
without bad side effects, just keep the list sorted. */
const char *mbox_save_drop_headers[] = {
"Content-Length",
"Status",
"X-Delivery-ID"
"X-IMAP",
"X-IMAPbase",
"X-Keywords",
"X-Status",
"X-UID"
};
extern struct mail_storage mbox_storage;
extern struct mailbox mbox_mailbox;
{
} else {
" (process was started with ulimit -f limit)";
"%s failed with mbox file %s: %m%s",
}
return -1;
}
static const char *
enum mailbox_list_path_type type)
{
const char *path, *p;
if (type == MAILBOX_LIST_PATH_TYPE_CONTROL ||
if (p == NULL)
return "";
}
return path;
}
static struct mail_storage *mbox_storage_alloc(void)
{
struct mbox_storage *storage;
}
static int
const char **error_r)
{
const char *dir;
/* we can't handle locking related problems. */
*error_r = "mbox requires client_limit=1 for service";
return -1;
}
if (*dir != '\0') {
}
"mbox root directory can't be a file: %s "
return -1;
}
return 0;
}
struct mailbox_list_settings *set)
{
}
}
{
if (debug) {
i_debug("mbox autodetect: %s: stat(%s) failed: %m",
}
return FALSE;
}
if (debug) {
i_debug("mbox autodetect: %s: is a directory (%s)",
}
return FALSE;
}
if (debug) {
i_debug("mbox autodetect: %s: no R/W access (%s)",
}
return FALSE;
}
if (debug)
return TRUE;
}
{
if (debug) {
i_debug("mbox autodetect: %s: stat(%s) failed: %m",
}
return FALSE;
}
if (debug) {
i_debug("mbox autodetect: %s: is not a directory (%s)",
}
return FALSE;
}
if (debug) {
i_debug("mbox autodetect: %s: no R/W/X access (%s)",
}
return FALSE;
}
if (debug)
return TRUE;
}
{
return TRUE;
return TRUE;
return TRUE;
return FALSE;
}
{
if (debug)
i_debug("maildir: Home directory not set");
home = "";
}
return path;
return path;
return NULL;
}
static const char *
{
const char *path;
if (debug)
return path;
}
if (debug)
if (debug)
return path;
}
if (debug)
return NULL;
}
struct mailbox_list_settings *set)
{
const char *root_dir, *inbox_path;
if (inbox_path == NULL &&
/* using location=<INBOX> */
return FALSE;
}
if (debug)
i_debug("mbox: couldn't find root dir");
return FALSE;
}
}
if (inbox_path == NULL) {
debug);
}
return TRUE;
}
{
return FALSE;
else {
"stat(%s) failed: %m", path);
return FALSE;
}
}
}
static struct mailbox *
{
struct mbox_mailbox *mbox;
struct index_mailbox_context *ibox;
mbox->mbox_ext_idx =
0, 16, 1);
}
{
}
{
const char *rootdir;
bool move_to_memory;
return -1;
}
}
/* if INBOX isn't under the root directory, it's probably in
}
return -1;
mbox->keep_lock_to =
}
}
}
{
int ret;
}
return mbox_mailbox_open_existing(mbox);
else if (ret == 0) {
"Mailbox isn't selectable");
return -1;
return -1;
return -1;
} else {
return -1;
}
}
static int
{
int ret;
if (mailbox_open(box) < 0)
return -1;
}
return ret;
}
{
const char *inbox_path;
int fd;
/* try again with increased privileges */
(void)restrict_access_use_priv_gid();
}
if (fd != -1) {
return 0;
return -1;
"Mailbox already exists");
return -1;
} else {
"open(%s, O_CREAT) failed: %m", inbox_path);
return -1;
}
}
static int
bool directory)
{
if (directory &&
return 0;
if (create_inbox(box) < 0)
return -1;
} else {
/* create the mbox file */
if (ret < 0)
return -1;
if (ret == 0) {
"Mailbox already exists");
return -1;
}
}
}
{
const struct mail_index_header *hdr;
enum mbox_sync_flags sync_flags = 0;
/* clear the corruption by forcing a full resync */
}
/* we've done changes to mbox which haven't been
written yet. do it now. */
}
}
if (mbox->mbox_global_lock_id != 0)
}
static int
{
"Mailbox GUIDs are not permanent without index files");
return -1;
}
return -1;
}
return 0;
}
{
else if (!mbox->no_mbox_file)
}
static bool
const char *name)
{
unsigned int len;
return TRUE;
}
struct mailbox_list *list)
{
struct mbox_mailbox_list *mlist;
/* have to use .imap/ directories */
}
}
static struct mailbox_transaction_context *
{
struct mbox_transaction_context *mt;
}
{
if (lock_id != 0)
if (mbox->mbox_global_lock_id == 0) {
} else {
/* mailbox opened with MAILBOX_FLAG_KEEP_LOCKED */
}
}
static int
struct mail_transaction_commit_changes *changes_r)
{
struct mbox_transaction_context *mt =
(struct mbox_transaction_context *)t;
int ret;
return ret;
}
static void
{
struct mbox_transaction_context *mt =
(struct mbox_transaction_context *)t;
}
struct mail_storage mbox_storage = {
.v = {
NULL,
}
};
struct mailbox mbox_mailbox = {
.v = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
}
};