mbox-storage.c revision 7f97ca94363c9e38fbbaaef204d6d01c54af6fc4
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define CREATE_MODE 0770 /* umask() should limit it more */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* How often to touch the dotlock file when using KEEP_LOCKED flag */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Assume that if atime < mtime, there are new mails. If it's good enough for
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina UW-IMAP, it's good enough for us. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina (st).st_atime < (st).st_mtime ? MAILBOX_MARKED : MAILBOX_UNMARKED)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* NOTE: must be sorted for istream-header-filter. Note that it's not such
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina a good idea to change this list, as the messages will then change from
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina client's point of view. So if you do it, change all mailboxes' UIDVALIDITY
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina so all caches are reset. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaconst char *mbox_hide_headers[] = {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Content-Length",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "X-IMAPbase",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "X-Keywords",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaunsigned int mbox_hide_headers_count = N_ELEMENTS(mbox_hide_headers);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* A bit ugly duplification of the above list. It's safe to modify this list
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina without bad side effects, just keep the list sorted. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Content-Length",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "X-Delivery-ID"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "X-IMAPbase",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "X-Keywords",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaunsigned int mbox_save_drop_headers_count = N_ELEMENTS(mbox_save_drop_headers);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic MODULE_CONTEXT_DEFINE_INIT(mbox_mailbox_list_module,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic int mbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic int mbox_list_delete_mailbox(struct mailbox_list *list,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *name);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina mail_storage_set_error(&mbox->storage->storage,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina mail_storage_set_critical(&mbox->storage->storage,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "%s failed with mbox file %s: %m",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic bool mbox_is_file(const char *path, const char *name, bool debug)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox autodetect: %s: stat(%s) failed: %m",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox autodetect: %s: is a directory (%s)",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox autodetect: %s: no R/W access (%s)",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox autodetect: %s: yes (%s)", name, path);
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashovstatic bool mbox_is_dir(const char *path, const char *name, bool debug)
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov i_info("mbox autodetect: %s: stat(%s) failed: %m",
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov i_info("mbox autodetect: %s: is not a directory (%s)",
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov i_info("mbox autodetect: %s: no R/W/X access (%s)",
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov i_info("mbox autodetect: %s: yes (%s)", name, path);
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashovstatic bool mbox_autodetect(const char *data, enum mail_storage_flags flags)
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox autodetect: data=%s, splitting ':' -> %s",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (*path != '\0' && mbox_is_file(path, "INBOX file", debug))
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (mbox_is_dir(t_strconcat(path, "/"MBOX_INDEX_DIR_NAME, NULL),
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (mbox_is_file(t_strconcat(path, "/inbox", NULL), "has inbox", debug))
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (mbox_is_file(t_strconcat(path, "/mbox", NULL), "has mbox", debug))
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic const char *get_root_dir(enum mail_storage_flags flags)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
836dae913497e150bd0ec11eee1e256e4fcc0bb7Nikolai Kondrashov i_info("mbox: root: access(%s, rwx) failed: %m", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox: root: access(%s, rwx) failed: %m", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox: root mail directory not found");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic const char *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaget_inbox_file(const char *root_dir, bool only_root, bool debug)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (!only_root && (user = getenv("USER")) != NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox: INBOX: access(%s, rw) failed: %m", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina path = t_strconcat("/var/spool/mail/", user, NULL);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox: INBOX: access(%s, rw) failed: %m", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic const char *create_root_dir(bool debug, const char **error_r)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "home directory is missing";
c778c36c5170c2b9f1cf7a6e3b0811124534df03Jakub Hrozek *error_r = t_strdup_printf("mkdir(%s) failed: %m", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina i_info("mbox: root directory created: %s", path);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinambox_get_list_settings(struct mailbox_list_settings *list_set,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *data, enum mail_storage_flags flags,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *p;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina list_set->subscription_fname = MBOX_SUBSCRIPTION_FILE_NAME;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* we'll need to figure out the mail location ourself.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina it's root dir if we've already chroot()ed, otherwise
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina either $HOME/mail or $HOME/Mail */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0 &&
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* if the data points to a file, treat it as an INBOX */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (stat(data, &st) < 0 || S_ISDIR(st.st_mode))
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (mailbox_list_settings_parse(data, list_set,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
const char *path, *p;
if (p == NULL)
return path;
const char **error_r)
const char *layout;
int fd;
rootdir);
const char *env;
unsigned int min_size;
return FALSE;
if (min_size == 0)
return FALSE;
return FALSE;
static struct mbox_mailbox *
return NULL;
return mbox;
static struct mailbox *
static struct mailbox *
const char *path;
return NULL;
static struct mailbox *
const char *path;
return NULL;
name));
return NULL;
path);
return NULL;
bool directory)
const char *path, *p;
int fd;
if (p != NULL) {
if (directory) {
int ret = 0;
const char *inbox_path;
return FALSE;
const char *name)
static void mbox_class_init(void)
static void mbox_class_deinit(void)
NULL,
NULL,
NULL,