/* Copyright (c) 2002-2018 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. */
struct mbox_mailbox_list {
};
/* 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)";
}
}
static int
{
const char *path, *p;
int ret;
if (ret <= 0)
return ret;
switch (type) {
/* kind of a kludge for backwards compatibility:
the subscriptions file is in the root control_dir
without .imap/ suffix */
return 1;
}
return 1;
}
if (p == NULL)
return 0;
break;
break;
}
return 1;
}
{
}
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;
}
}
"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)
{
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 *
{
else {
i_fatal("Invalid mbox_md5 setting: %s",
}
}
{
}
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 = 0;
if (mailbox_open(box) < 0)
return -1;
}
}
if (ret == 0)
return ret;
}
{
const char *inbox_path;
int fd;
/* try again with increased privileges */
(void)restrict_access_use_priv_gid();
}
if (fd != -1) {
i_close_fd(&fd);
return 0;
return -1;
"Mailbox already exists");
return -1;
} else {
"open(%s, O_CREAT) failed: %m", inbox_path);
return -1;
}
}
static int
bool directory)
{
return ret;
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;
}
i_close_fd(&fd);
}
}
{
/* 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
{
const char *errstr;
errstr = "Mailbox GUIDs are not permanent without index files";
" (mbox_min_index_size is non-zero)", NULL);
}
return -1;
}
if (mbox_sync_header_refresh(mbox) < 0)
return -1;
/* we have the GUID */
} else if (mbox_file_open(mbox) < 0)
return -1;
else if (mbox->backend_readonly) {
"Can't set mailbox GUID to a read-only mailbox");
return -1;
} else {
/* create another mailbox and sync */
int ret;
mailbox_free(&box2);
return ret;
}
return 0;
}
static int
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r)
{
return -1;
if ((items & MAILBOX_METADATA_GUID) != 0) {
return -1;
}
return 0;
}
{
else if (!mbox->no_mbox_file)
}
static bool
const char *name)
{
return TRUE;
}
struct mailbox_list *list)
{
/* have to use .imap/ directories */
}
}
static struct mailbox_transaction_context *
const char *reason)
{
if ((flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0)
return &mt->t;
}
static void
unsigned int lock_id2)
{
if (lock_id1 != 0)
if (lock_id2 != 0)
if (mbox->mbox_global_lock_id == 0) {
mbox->external_transactions > 0 ||
} else {
/* mailbox opened with MAILBOX_FLAG_KEEP_LOCKED */
}
}
static int
struct mail_transaction_commit_changes *changes_r)
{
int ret;
if ((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0) {
}
return ret;
}
static void
{
if ((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0) {
}
}
{
if (!mbox->backend_readonly_set) {
}
return mbox->backend_readonly;
}
.v = {
NULL,
NULL,
}
};
.v = {
NULL,
NULL,
}
};