maildir-storage.c revision 352cd70b5850eb0815f1ee3bb4e7533d2c8c4c5f
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "lib.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "ioloop.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "mkdir-parents.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "eacces-error.h"
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek#include "unlink-old-files.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "mailbox-uidvalidity.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "mailbox-list-private.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "maildir-storage.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "maildir-uidlist.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "maildir-keywords.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "maildir-sync.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include "index-mail.h"
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#include <sys/stat.h>
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek#define MAILDIR_LIST_CONTEXT(obj) \
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek MODULE_CONTEXT(obj, maildir_mailbox_list_module)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstruct maildir_mailbox_list_context {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek union mailbox_list_module_context module_ctx;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek const struct maildir_settings *set;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek};
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekextern struct mail_storage maildir_storage;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekextern struct mailbox maildir_mailbox;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic MODULE_CONTEXT_DEFINE_INIT(maildir_mailbox_list_module,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek &mailbox_list_module_register);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březinastatic const char *maildir_subdirs[] = { "cur", "new", "tmp" };
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bosestatic struct mail_storage *maildir_storage_alloc(void)
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose{
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose struct maildir_storage *storage;
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose pool_t pool;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek pool = pool_alloconly_create("maildir storage", 512+256);
50c9d542e8bf641412debaa82a4dcf67ddb72258Lukas Slebodnik storage = p_new(pool, struct maildir_storage, 1);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->storage = maildir_storage;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->storage.pool = pool;
61b58801f1e37c054affc99f6fe900f7b3ef7972Lukas Slebodnik return &storage->storage;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic int
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekmaildir_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek const char **error_r ATTR_UNUSED)
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct maildir_storage *storage = (struct maildir_storage *)_storage;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct mailbox_list *list = ns->list;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek const char *dir;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->set = mail_storage_get_driver_settings(_storage);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
9cc2223e0bc0478c1b47a47fd71bba7e7129492dJakub Hrozek storage->maildir_list_ext_id = (uint32_t)-1;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->temp_prefix = p_strdup(_storage->pool,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek mailbox_list_get_temp_prefix(list));
7543052f562f157f7b17fdc46a6777d80c0cb3bdSumit Bose
e4549c5364461644723361d688badde7fe137a25Sumit Bose if (list->set.control_dir == NULL && list->set.inbox_path == NULL &&
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek (ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek /* put the temp files into tmp/ directory preferrably */
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->temp_prefix = p_strconcat(_storage->pool, "tmp/",
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->temp_prefix, NULL);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek dir = mailbox_list_get_path(list, NULL,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek MAILBOX_LIST_PATH_TYPE_DIR);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek } else {
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose /* control dir should also be writable */
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek dir = mailbox_list_get_path(list, NULL,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek MAILBOX_LIST_PATH_TYPE_CONTROL);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek _storage->temp_path_prefix = p_strconcat(_storage->pool, dir, "/",
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek storage->temp_prefix, NULL);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return 0;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bosestatic void maildir_storage_get_list_settings(const struct mail_namespace *ns,
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose struct mailbox_list_settings *set)
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose{
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (set->layout == NULL)
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose set->layout = MAILBOX_LIST_NAME_MAILDIRPLUSPLUS;
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose if (set->subscription_fname == NULL)
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose set->subscription_fname = MAILDIR_SUBSCRIPTION_FILE_NAME;
36c266d467e9105041b33e9b1cdcd9ff073d893eSumit Bose
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (set->inbox_path == NULL && set->maildir_name == NULL &&
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek (strcmp(set->layout, MAILBOX_LIST_NAME_MAILDIRPLUSPLUS) == 0 ||
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek strcmp(set->layout, MAILBOX_LIST_NAME_FS) == 0) &&
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek (ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek /* Maildir++ INBOX is the Maildir base itself */
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek set->inbox_path = set->root_dir;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic const char *
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekmaildir_storage_find_root_dir(const struct mail_namespace *ns)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek bool debug = ns->mail_set->mail_debug;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha const char *home, *path;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek /* we'll need to figure out the maildir location ourself.
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek It's ~/Maildir unless we are chrooted. */
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (mail_user_get_home(ns->user, &home) > 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek path = t_strconcat(home, "/Maildir", NULL);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (access(path, R_OK|W_OK|X_OK) == 0) {
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha if (debug)
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha i_debug("maildir: root exists (%s)", path);
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha return path;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha }
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha if (debug)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek i_debug("maildir: access(%s, rwx): failed: %m", path);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek } else {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (debug)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek i_debug("maildir: Home directory not set");
32b976eb666044d106dd85e27f8d0bb1d7b6cd6cSumit Bose if (access("/cur", R_OK|W_OK|X_OK) == 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (debug)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek i_debug("maildir: /cur exists, assuming chroot");
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return "/";
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return NULL;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
4f3a9d837a55b49448eca3c713c85a406207e523Simo Sorcestatic bool maildir_storage_autodetect(const struct mail_namespace *ns,
4f3a9d837a55b49448eca3c713c85a406207e523Simo Sorce struct mailbox_list_settings *set)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek bool debug = ns->mail_set->mail_debug;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct stat st;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek const char *path, *root_dir;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (set->root_dir != NULL)
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina root_dir = set->root_dir;
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina else {
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina root_dir = maildir_storage_find_root_dir(ns);
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina if (root_dir == NULL) {
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina if (debug)
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina i_debug("maildir: couldn't find root dir");
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina return FALSE;
4f3a9d837a55b49448eca3c713c85a406207e523Simo Sorce }
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina }
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina
0713b92ec9f10b6dd913dc56cbc7845d1b025ccbPavel Březina path = t_strconcat(root_dir, "/cur", NULL);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (stat(path, &st) < 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (debug)
343b053bc61792023003d077ae81c05ff1676a89Sumit Bose i_debug("maildir autodetect: stat(%s) failed: %m", path);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return FALSE;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (!S_ISDIR(st.st_mode)) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (debug)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek i_debug("maildir autodetect: %s not a directory", path);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return FALSE;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek set->root_dir = root_dir;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_storage_get_list_settings(ns, set);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return TRUE;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic int
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnikmkdir_verify(struct mail_storage *storage, struct mail_namespace *ns,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek const char *dir, mode_t mode, gid_t gid, const char *gid_origin,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek bool verify)
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct stat st;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (verify) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (stat(dir, &st) == 0)
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik return 0;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
9cc2223e0bc0478c1b47a47fd71bba7e7129492dJakub Hrozek if (errno != ENOENT) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek mail_storage_set_critical(storage,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek "stat(%s) failed: %m", dir);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return -1;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose }
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose if (mkdir_parents_chgrp(dir, mode, gid, gid_origin) == 0)
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose return 0;
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose if (errno == EEXIST) {
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose if (verify)
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose return 0;
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose mail_storage_set_error(storage, MAIL_ERROR_EXISTS,
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose "Mailbox already exists");
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose } else if (errno == ENOENT) {
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose "Mailbox was deleted while it was being created");
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose } else if (errno == EACCES) {
54039570d26e29444c398aa4ad6ba638f1713566Sumit Bose if (ns->type == NAMESPACE_SHARED) {
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik /* shared namespace, don't log permission errors */
e1aed98d7c195f844ac8e85050d04f3ca5f899b3Sumit Bose mail_storage_set_error(storage, MAIL_ERROR_PERM,
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha MAIL_ERRSTR_NO_PERMISSION);
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik return -1;
e1aed98d7c195f844ac8e85050d04f3ca5f899b3Sumit Bose }
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha mail_storage_set_critical(storage, "%s",
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha mail_error_create_eacces_msg("mkdir", dir));
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha } else {
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik mail_storage_set_critical(storage,
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha "mkdir(%s) failed: %m", dir);
9cc2223e0bc0478c1b47a47fd71bba7e7129492dJakub Hrozek }
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha return -1;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha}
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jhastatic int maildir_check_tmp(struct mail_storage *storage, const char *dir)
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik{
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek const char *path;
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik struct stat st;
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek /* if tmp/ directory exists, we need to clean it up once in a while */
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek path = t_strconcat(dir, "/tmp", NULL);
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik if (stat(path, &st) < 0) {
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek if (errno == ENOENT)
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek return 0;
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek if (errno == EACCES) {
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek mail_storage_set_critical(storage, "%s",
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek mail_error_eacces_msg("stat", path));
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek return -1;
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik }
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik return -1;
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose }
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose if (st.st_atime > st.st_ctime + MAILDIR_TMP_DELETE_SECS) {
35567de112cd5d82acb582cbdb44c8652bbdfda1Lukas Slebodnik /* the directory should be empty. we won't do anything
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose until ctime changes. */
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose } else if (st.st_atime < ioloop_time - MAILDIR_TMP_SCAN_SECS) {
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose /* time to scan */
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose (void)unlink_old_files(path, "",
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose ioloop_time - MAILDIR_TMP_DELETE_SECS);
1a45124f3f300f9afdcb08eab0938e5e7d0534d9Sumit Bose }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return 1;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina}
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina/* create or fix maildir, ignore if it already exists */
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březinastatic int create_maildir(struct mailbox *box, bool verify)
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina{
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina const struct mailbox_permissions *perm = mailbox_get_permissions(box);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina const char *path;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina unsigned int i;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina enum mail_error error;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina int ret = 0;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina path = t_strconcat(mailbox_get_path(box), "/",
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina maildir_subdirs[i], NULL);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina if (mkdir_verify(box->storage, box->list->ns, path,
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina perm->dir_create_mode, perm->file_create_gid,
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina perm->file_create_gid_origin, verify) < 0) {
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina error = mailbox_get_last_mail_error(box);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina if (error != MAIL_ERROR_EXISTS)
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina return -1;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina /* try to create all of the directories in case one
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina of them doesn't exist */
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina ret = -1;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina }
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina }
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina return ret;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina}
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březinastatic void maildir_lock_touch_timeout(struct maildir_mailbox *mbox)
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina{
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina (void)maildir_uidlist_lock_touch(mbox->uidlist);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina}
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březinastatic struct mailbox *
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březinamaildir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina const char *vname, enum mailbox_flags flags)
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct maildir_mailbox *mbox;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek pool_t pool;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina pool = pool_alloconly_create("maildir mailbox", 1024*3);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox = p_new(pool, struct maildir_mailbox, 1);
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox->box = maildir_mailbox;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox->box.pool = pool;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox->box.storage = storage;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox->box.list = list;
8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5Pavel Březina mbox->box.mail_vfuncs = &maildir_mail_vfuncs;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha index_storage_mailbox_alloc(&mbox->box, vname, flags,
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha MAILDIR_INDEX_PREFIX);
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha mbox->storage = (struct maildir_storage *)storage;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha return &mbox->box;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha}
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jhastatic int maildir_mailbox_open_existing(struct mailbox *box)
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha{
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha mbox->uidlist = maildir_uidlist_init(mbox);
a044c9a1012d11a2a75e9976ebf186d2d781d291Pallavi Jha mbox->keywords = maildir_keywords_init(mbox);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if ((box->flags & MAILBOX_FLAG_KEEP_LOCKED) != 0) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (maildir_uidlist_lock(mbox->uidlist) <= 0)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return -1;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek mbox->keep_lock_to = timeout_add(MAILDIR_LOCK_TOUCH_SECS * 1000,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_lock_touch_timeout,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek mbox);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek if (index_storage_mailbox_open(box, FALSE) < 0)
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek return -1;
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek mbox->maildir_ext_id =
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek mail_index_ext_register(mbox->box.index, "maildir",
bbd6f73bbad478a450ecfa2933a63de6dc269778Jakub Hrozek sizeof(mbox->maildir_hdr), 0, 0);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return 0;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic bool maildir_storage_is_readonly(struct mailbox *box)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (index_storage_is_readonly(box))
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return TRUE;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek if (maildir_is_backend_readonly(mbox)) {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek /* return read-only only if there are no private flags
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek (that are stored in index files) */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (mailbox_get_private_flags_mask(box) == 0)
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek return TRUE;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return FALSE;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekstatic int
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozekmaildir_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek enum mailbox_existence *existence_r)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek{
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return index_storage_mailbox_exists_full(box, "cur", existence_r);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozekstatic int maildir_mailbox_open(struct mailbox *box)
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek{
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek const char *box_path = mailbox_get_path(box);
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek const char *root_dir;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek struct stat st;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek int ret;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek /* begin by checking if tmp/ directory exists and if it should be
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek cleaned up. */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek ret = maildir_check_tmp(box->storage, box_path);
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (ret > 0) {
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek /* exists */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek return maildir_mailbox_open_existing(box);
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek }
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (ret < 0)
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek return -1;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek /* tmp/ directory doesn't exist. does the maildir? */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek root_dir = mailbox_list_get_path(box->list, NULL,
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek MAILBOX_LIST_PATH_TYPE_MAILBOX);
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (strcmp(box_path, root_dir) == 0) {
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek /* root directory. either INBOX or some other namespace root */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek errno = ENOENT;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek } else if (stat(box_path, &st) == 0) {
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek /* yes, we'll need to create the missing dirs */
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (create_maildir(box, TRUE) < 0)
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek return -1;
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek return maildir_mailbox_open_existing(box);
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek }
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek if (errno == ENOENT) {
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
34926c3809b19f9e70f18931e44bf993321647a8Jakub Hrozek T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek return -1;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek } else {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek mail_storage_set_critical(box->storage,
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek "stat(%s) failed: %m", box_path);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek return -1;
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek }
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek}
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozekstatic int maildir_create_shared(struct mailbox *box)
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek{
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek const struct mailbox_permissions *perm = mailbox_get_permissions(box);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek const char *path;
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek mode_t old_mask;
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek int fd;
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek old_mask = umask(0);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek path = t_strconcat(mailbox_get_path(box), "/dovecot-shared", NULL);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek fd = open(path, O_WRONLY | O_CREAT, perm->file_create_mode);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek umask(old_mask);
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek if (fd == -1) {
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek mail_storage_set_critical(box->storage, "open(%s) failed: %m",
aa648535f445e7a95bf6dedc7c43bb5f94ab7354Jakub Hrozek path);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (fchown(fd, (uid_t)-1, perm->file_create_gid) < 0) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (errno == EPERM) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mail_storage_set_critical(box->storage, "%s",
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek eperm_error_get_chgrp("fchown", path,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek perm->file_create_gid,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek perm->file_create_gid_origin));
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek } else {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mail_storage_set_critical(box->storage,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek "fchown(%s) failed: %m", path);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek (void)close(fd);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return 0;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekstatic int
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekmaildir_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_uidlist *uidlist;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek int ret;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (!box->opened) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (mailbox_open(box) < 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek uidlist = mbox->uidlist;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (maildir_uidlist_lock(uidlist) <= 0)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio return -1;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (!guid_128_is_empty(update->mailbox_guid))
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_uidlist_set_mailbox_guid(uidlist, update->mailbox_guid);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (update->uid_validity != 0)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_uidlist_set_uid_validity(uidlist, update->uid_validity);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (update->min_next_uid != 0) {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_uidlist_set_next_uid(uidlist, update->min_next_uid,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio FALSE);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio }
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio ret = maildir_uidlist_update(uidlist);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (ret == 0)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio ret = index_storage_mailbox_update(box, update);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_uidlist_unlock(uidlist);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio return ret;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio}
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciostatic int
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciomaildir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek bool directory)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek const char *root_dir, *shared_path;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct stat st;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek int ret;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (directory &&
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek (box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) == 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return 0;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek ret = maildir_check_tmp(box->storage, mailbox_get_path(box));
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (ret > 0) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek "Mailbox already exists");
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (ret < 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (create_maildir(box, FALSE) < 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek /* if dovecot-shared exists in the root dir, copy it to newly
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek created mailboxes */
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek root_dir = mailbox_list_get_path(box->list, NULL,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek MAILBOX_LIST_PATH_TYPE_MAILBOX);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek shared_path = t_strconcat(root_dir, "/dovecot-shared", NULL);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (stat(shared_path, &st) == 0) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (maildir_create_shared(box) < 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return update == NULL ? 0 : maildir_mailbox_update(box, update);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekstatic int
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekmaildir_mailbox_get_metadata(struct mailbox *box,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek enum mailbox_metadata_items items,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct mailbox_metadata *metadata_r)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if ((items & MAILBOX_METADATA_GUID) != 0) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (maildir_uidlist_get_mailbox_guid(mbox->uidlist,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek metadata_r->guid) < 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return -1;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return index_mailbox_get_metadata(box, items, metadata_r);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekstatic void maildir_mailbox_close(struct mailbox *box)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (mbox->keep_lock_to != NULL) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_uidlist_unlock(mbox->uidlist);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek timeout_remove(&mbox->keep_lock_to);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (mbox->flags_view != NULL)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mail_index_view_close(&mbox->flags_view);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (mbox->keywords != NULL)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_keywords_deinit(&mbox->keywords);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_uidlist_deinit(&mbox->uidlist);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek index_storage_mailbox_close(box);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekstatic void maildir_notify_changes(struct mailbox *box)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek const char *box_path = mailbox_get_path(box);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (box->notify_callback == NULL)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio index_mailbox_check_remove_all(&mbox->box);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio else {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio index_mailbox_check_add(&mbox->box,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio t_strconcat(box_path, "/new", NULL));
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio index_mailbox_check_add(&mbox->box,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio t_strconcat(box_path, "/cur", NULL));
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio }
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio}
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciostatic bool
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciomaildir_is_internal_name(struct mailbox_list *list ATTR_UNUSED,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio const char *name)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio{
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio return strcmp(name, "cur") == 0 ||
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio strcmp(name, "new") == 0 ||
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio strcmp(name, "tmp") == 0;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio}
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciostatic void maildir_storage_add_list(struct mail_storage *storage,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio struct mailbox_list *list)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox_list_context *mlist;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mlist = p_new(list->pool, struct maildir_mailbox_list_context, 1);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mlist->module_ctx.super = list->v;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mlist->set = mail_storage_get_driver_settings(storage);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek list->v.is_internal_name = maildir_is_internal_name;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek MODULE_CONTEXT_SET(list, maildir_mailbox_list_module, mlist);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekuint32_t maildir_get_uidvalidity_next(struct mailbox_list *list)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek const char *path;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek path = mailbox_list_get_path(list, NULL,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek MAILBOX_LIST_PATH_TYPE_CONTROL);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek path = t_strconcat(path, "/"MAILDIR_UIDVALIDITY_FNAME, NULL);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return mailbox_uidvalidity_next(list, path);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekstatic enum mail_flags maildir_get_private_flags_mask(struct mailbox *box)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek const char *path, *path2;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek struct stat st;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (mbox->private_flags_mask_set)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return mbox->_private_flags_mask;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mbox->private_flags_mask_set = TRUE;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek path = mailbox_list_get_path(box->list, NULL,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek MAILBOX_LIST_PATH_TYPE_MAILBOX);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek path2 = mailbox_list_get_path(box->list, NULL,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek MAILBOX_LIST_PATH_TYPE_INDEX);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (strcmp(path, path2) == 0) {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek /* no separate index directory. we can't have private flags,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek so don't even bother checking if dovecot-shared exists */
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek } else {
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek path = t_strconcat(mailbox_get_path(box),
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek "/dovecot-shared", NULL);
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (stat(path, &st) == 0)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek mbox->_private_flags_mask = MAIL_SEEN;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek }
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek return mbox->_private_flags_mask;
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek}
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozekbool maildir_is_backend_readonly(struct maildir_mailbox *mbox)
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek{
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek if (!mbox->backend_readonly_set) {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio const char *box_path = mailbox_get_path(&mbox->box);
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio mbox->backend_readonly_set = TRUE;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio errno == EACCES)
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio mbox->backend_readonly = TRUE;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio }
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio return mbox->backend_readonly;
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio}
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciostruct mail_storage maildir_storage = {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio .name = MAILDIR_STORAGE_NAME,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio .class_flags = MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio .v = {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_get_setting_parser_info,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_alloc,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_create,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio NULL,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_add_list,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_get_list_settings,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_autodetect,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_mailbox_alloc,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio NULL
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio }
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio};
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidênciostruct mailbox maildir_mailbox = {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio .v = {
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_storage_is_readonly,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio index_storage_mailbox_enable,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_mailbox_exists,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_mailbox_open,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_mailbox_close,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio index_storage_mailbox_free,
a3442e4a268ad2172c89d58e6daa759eb4b39e7cFabiano Fidêncio maildir_mailbox_create,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_mailbox_update,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_mailbox_delete,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek index_storage_mailbox_rename,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek index_storage_get_status,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_mailbox_get_metadata,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_list_index_has_changed,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_list_index_update_sync,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_storage_sync_init,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek index_mailbox_sync_next,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek index_mailbox_sync_deinit,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek NULL,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_notify_changes,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_transaction_begin,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_transaction_commit,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_transaction_rollback,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_get_private_flags_mask,
32b976eb666044d106dd85e27f8d0bb1d7b6cd6cSumit Bose index_mail_alloc,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_search_init,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_search_deinit,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_search_next_nonblock,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_search_next_update_seq,
32b976eb666044d106dd85e27f8d0bb1d7b6cd6cSumit Bose maildir_save_alloc,
32b976eb666044d106dd85e27f8d0bb1d7b6cd6cSumit Bose maildir_save_begin,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_save_continue,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_save_finish,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_save_cancel,
2dcf7b9b65df21f2aee6cdf051a7fbdef6dfe034Jakub Hrozek maildir_copy,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_transaction_save_commit_pre,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_transaction_save_commit_post,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek maildir_transaction_save_rollback,
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek index_storage_is_inconsistent
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek};
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek