maildir-storage.c revision 37847ec8eaec9ad55c9df10ae109efe7b37ac573
e364bf323ef28133cdf28e6b31bad47999cdbe49Timo Sirainen/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define MAILDIR_SUBFOLDER_FILENAME "maildirfolder"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MODULE_CONTEXT(obj, maildir_mailbox_list_module)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(maildir_mailbox_list_module,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const char *maildir_subdirs[] = { "cur", "new", "tmp" };
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool maildir_is_internal_name(const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool maildir_storage_is_valid_existing_name(struct mailbox_list *list,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct maildir_mailbox_list *mlist = MAILDIR_LIST_CONTEXT(list);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mlist->module_ctx.super.is_valid_existing_name(list, name))
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* Don't allow the mailbox name to end in cur/new/tmp */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool maildir_storage_is_valid_create_name(struct mailbox_list *list,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct maildir_mailbox_list *mlist = MAILDIR_LIST_CONTEXT(list);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mlist->module_ctx.super.is_valid_create_name(list, name))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* Don't allow creating mailboxes under cur/new/tmp */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *const *tmp;
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen for (tmp = t_strsplit(name, "/"); *tmp != NULL; tmp++) {
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainenstatic struct mail_storage *maildir_storage_alloc(void)
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen pool = pool_alloconly_create("maildir storage", 512+256);
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen storage = p_new(pool, struct maildir_storage, 1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaildir_storage_create(struct mail_storage *_storage, struct mail_namespace *ns,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct maildir_storage *storage = (struct maildir_storage *)_storage;
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen const char *dir;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen storage->set = mail_storage_get_driver_settings(_storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen storage->temp_prefix = mailbox_list_get_temp_prefix(list);
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen if (list->set.control_dir == NULL && list->set.inbox_path == NULL &&
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen /* put the temp files into tmp/ directory preferrably */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen storage->temp_prefix = p_strconcat(_storage->pool, "tmp/",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* control dir should also be writable */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen _storage->temp_path_prefix = p_strconcat(_storage->pool, dir, "/",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void maildir_storage_get_list_settings(const struct mail_namespace *ns,
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen set->layout = MAILBOX_LIST_NAME_MAILDIRPLUSPLUS;
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen set->subscription_fname = MAILDIR_SUBSCRIPTION_FILE_NAME;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen set->dir_guid_fname = MAILDIR_DIR_GUID_FILE_NAME;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (strcmp(set->layout, MAILBOX_LIST_NAME_MAILDIRPLUSPLUS) == 0 ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen strcmp(set->layout, MAILBOX_LIST_NAME_FS) == 0) &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* Maildir++ INBOX is the Maildir base itself */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const char *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaildir_storage_find_root_dir(const struct mail_namespace *ns)
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen /* we'll need to figure out the maildir location ourself.
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen It's ~/Maildir unless we are chrooted. */
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (mail_user_get_home(ns->user, &home) > 0) {
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen i_info("maildir: access(%s, rwx): failed: %m", path);
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen i_info("maildir: /cur exists, assuming chroot");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool maildir_storage_autodetect(const struct mail_namespace *ns,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_info("maildir autodetect: stat(%s) failed: %m", path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_info("maildir autodetect: %s not a directory", path);
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainenmkdir_verify(struct mail_storage *storage, struct mail_namespace *ns,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen const char *dir, mode_t mode, gid_t gid, const char *gid_origin,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mkdir_parents_chgrp(dir, mode, gid, gid_origin) == 0)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen mail_storage_set_error(storage, MAIL_ERROR_EXISTS,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen "Mailbox already exists");
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen "Mailbox was deleted while it was being created");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* shared namespace, don't log permission errors */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_storage_set_error(storage, MAIL_ERROR_PERM,
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainenstatic int maildir_check_tmp(struct mail_storage *storage, const char *dir)
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen /* if tmp/ directory exists, we need to clean it up once in a while */
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (st.st_atime > st.st_ctime + MAILDIR_TMP_DELETE_SECS) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* the directory should be empty. we won't do anything
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen until ctime changes. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else if (st.st_atime < ioloop_time - MAILDIR_TMP_SCAN_SECS) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* time to scan */
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen/* create or fix maildir, ignore if it already exists */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainencreate_maildir(struct mail_storage *storage, struct mail_namespace *ns,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *dir, mode_t mode, gid_t gid, const char *gid_origin,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int i;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mkdir_verify(storage, ns, path, mode, gid,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void maildir_lock_touch_timeout(struct maildir_mailbox *mbox)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)maildir_uidlist_lock_touch(mbox->uidlist);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* add the execute bit if either read or write bit is set */
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainenstatic struct mailbox *
788f275469ad9ed530e440d6690d0e4381a323b2Timo Sirainenmaildir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen pool = pool_alloconly_create("maildir mailbox", 1024+512);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mbox = p_new(pool, struct maildir_mailbox, 1);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen mbox->ibox.mail_vfuncs = &maildir_mail_vfuncs;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mbox->ibox.save_commit_pre = maildir_transaction_save_commit_pre;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mbox->ibox.save_commit_post = maildir_transaction_save_commit_post;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mbox->ibox.save_rollback = maildir_transaction_save_rollback;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mbox->storage = (struct maildir_storage *)storage;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_ext_register(mbox->ibox.index, "maildir",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int maildir_mailbox_open_existing(struct mailbox *box)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* for shared mailboxes get the create mode from the
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen permissions of dovecot-shared file. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen shared_path = t_strconcat(box->path, "/dovecot-shared", NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* Ignore GID */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen box->dir_create_mode = get_dir_mode(st.st_mode & 0666);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if ((box->flags & MAILBOX_FLAG_KEEP_LOCKED) != 0) {
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen mbox->keep_lock_to = timeout_add(MAILDIR_LOCK_TOUCH_SECS * 1000,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (access(t_strconcat(box->path, "/cur", NULL), W_OK) < 0 &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int maildir_mailbox_open(struct mailbox *box)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "Maildir doesn't support streamed mailboxes");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* begin by checking if tmp/ directory exists and if it should be
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen cleaned up. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = maildir_check_tmp(box->storage, box->path);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* tmp/ directory doesn't exist. does the maildir? */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (inbox || (*box->name != '\0' && stat(box->path, &st) == 0)) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* yes, we'll need to create the missing dirs */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen mailbox_list_get_dir_permissions(box->list, box->name,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (create_maildir(box->storage, box->list->ns, box->path,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else if (*box->name == '\0' || errno == ENOENT) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaildir_create_shared(struct mail_storage *storage, struct mail_namespace *ns,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* add the execute bit if either read or write bit is set */
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen if (create_maildir(storage, ns, dir, mode, gid, gid_origin, FALSE) < 0)
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen path = t_strconcat(dir, "/dovecot-shared", NULL);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen fd = open(path, O_WRONLY | O_CREAT, mode & 0666);
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen mail_storage_set_critical(storage, "open(%s) failed: %m", path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmaildir_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct maildir_uidlist *uidlist = mbox->uidlist;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!mail_guid_128_is_empty(update->mailbox_guid))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen maildir_uidlist_set_mailbox_guid(uidlist, update->mailbox_guid);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen maildir_uidlist_set_uid_validity(uidlist, update->uid_validity);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen maildir_uidlist_set_next_uid(uidlist, update->min_next_uid,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = index_storage_mailbox_update(box, update);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmaildir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *path, *root_dir, *shared_path, *gid_origin;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen path = mailbox_list_get_path(box->list, box->name,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen root_dir = mailbox_list_get_path(box->list, NULL,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* if dovecot-shared exists in the root dir, create the mailbox using
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen its permissions and gid, and copy the dovecot-shared inside it. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen shared_path = t_strconcat(root_dir, "/dovecot-shared", NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (maildir_create_shared(box->storage, box->list->ns, path,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &st.st_mode,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (create_maildir(box->storage, box->list->ns, path,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* Maildir++ spec wants that maildirfolder named file is created for
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen all subfolders. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen path = t_strconcat(path, "/" MAILDIR_SUBFOLDER_FILENAME, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* if dovecot-shared exists, use the same group */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* doesn't exist */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen } else if (fchown(fd, (uid_t)-1, st.st_gid) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Mailbox was deleted while it was being created");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenmaildir_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen index_storage_get_status(box, items, status_r);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)maildir_uidlist_get_mailbox_guid(mbox->uidlist,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const char *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaildir_get_unlink_dest(struct mailbox_list *list, const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (list->mail_set->mail_full_filesystem_access &&
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (strcmp(mailbox_list_get_driver_name(list),
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* Not maildir++ driver. Don't use this trick. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen return t_strdup_printf("%s/%c%c"MAILDIR_UNLINK_DIRNAME, root_dir,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenmaildir_delete_nonrecursive(struct mailbox_list *list, const char *path,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen unsigned int dir_len;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* skip . and .. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (d->d_name[1] == '.' && d->d_name[2] == '\0')
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen if (unlink_directory(str_c(full_path), TRUE) < 0) {
6a6e3c2538a08cc4880a8db7e0a9a3392122ea04Timo Sirainen "unlink_directory(%s) failed: %m",
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen /* trying to unlink() a directory gives either EPERM or EISDIR
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (non-POSIX). it doesn't really work anywhere in practise,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen so don't bother stat()ing the file first */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else if (errno != ENOENT && errno != EISDIR && errno != EPERM) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "unlink_directory(%s) failed: %m",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_list_set_critical(list, "closedir(%s) failed: %m",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen else if (errno != ENOENT && errno != ENOTEMPTY) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path);
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainenmaildir_delete_with_trash(struct mailbox_list *list, const char *src,
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen unsigned int count;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* rename the .maildir into ..DOVECOT-TRASH which atomically
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen marks it as being deleted. If we die before deleting the
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ..DOVECOT-TRASH directory, it gets deleted the next time
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox listing sees it. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* it was just deleted under us by
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen another process */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* already existed, delete it and try again */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (unlink_directory(dest, TRUE) < 0 && errno != ENOTEMPTY) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* it's already renamed to ..dir, which means it's
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen deleted as far as the client is concerned. Report
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void mailbox_get_guid(struct mailbox_list *list, const char *name,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen box = mailbox_alloc(list, name, NULL, MAILBOX_FLAG_KEEP_RECENT);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mailbox_get_status(box, STATUS_GUID, &status);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen memcpy(mailbox_guid, status.mailbox_guid, MAIL_GUID_128_SIZE);
int ret;
if (ret == 0) {
dir_guid);
bool rename_children)
int ret;
switch (type) {
ret = 0;
return ret;
int ret;
const char *path;
switch (type) {
const char *path;
ret = 0;
ret = 0;
ret = 0;
return ret;
const char *path;
NULL,
NULL,
NULL,
NULL,