mbox-storage.c revision bfa7ef85a07f07b7d2e72471a584689cfb6adc31
/* 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", function,
}
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;
}
{
}
static int
{
return -1;
mbox->mbox_ext_idx =
0, 16, 1);
return 0;
}
{
bool move_to_memory;
/* if INBOX isn't under the root directory, it's probably in
}
return -1;
mbox->keep_lock_to =
}
}
}
{
if (index_storage_is_readonly(box))
return TRUE;
if (mbox_is_backend_readonly(mbox)) {
/* return read-only only if there are no private flags
(that are stored in index files) */
if (mailbox_get_private_flags_mask(box) == 0)
return TRUE;
}
return FALSE;
}
{
int ret;
}
if (ret == 0) {
return mbox_mailbox_open_existing(mbox);
"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;
}
if (mbox_sync_get_guid(mbox) < 0)
return -1;
}
return 0;
}
static int
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r)
{
if ((items & MAILBOX_METADATA_GUID) != 0) {
return -1;
}
}
{
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;
return &mt->t;
}
{
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;
}
{
if (!mbox->backend_readonly_set) {
}
return mbox->backend_readonly;
}
struct mail_storage mbox_storage = {
.v = {
NULL,
}
};
struct mailbox mbox_mailbox = {
.v = {
NULL,
NULL,
}
};