mailbox-list.c revision 563273bdac80393af63b9520cbf4d24cc0efd028
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen then start renaming them to larger names from end to beginning, which
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen eventually would start causing the failures when trying to use too
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen long mailbox names. */
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen struct mailbox_list_iterate_context *backend_ctx;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstruct mailbox_list_module_register mailbox_list_module_register = { 0 };
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid (*hook_mailbox_list_created)(struct mailbox_list *list);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool mailbox_list_driver_find(const char *name, unsigned int *idx_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i, count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen drivers = array_get(&mailbox_list_drivers, &count);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < count; i++) {
3c73d884362b72c86753939551c94f8baa5702f8Timo Sirainen if (strcasecmp(drivers[i]->name, name) == 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_register(const struct mailbox_list *list)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen unsigned int idx;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (mailbox_list_driver_find(list->name, &idx)) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_fatal("mailbox_list_register(%s): duplicate driver",
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen array_append(&mailbox_list_drivers, &list, 1);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainenvoid mailbox_list_unregister(const struct mailbox_list *list)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen unsigned int idx;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (!mailbox_list_driver_find(list->name, &idx)) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_fatal("mailbox_list_unregister(%s): unknown driver",
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainenint mailbox_list_create(const char *driver, struct mail_namespace *ns,
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen enum mailbox_list_flags flags, const char **error_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int idx;
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen i_assert(set->root_dir == NULL || *set->root_dir != '\0');
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen if (!mailbox_list_driver_find(driver, &idx)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *error_r = t_strdup_printf("Unknown mailbox list driver: %s",
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen class_p = array_idx(&mailbox_list_drivers, idx);
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen /* copy settings */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen list->set.root_dir = p_strdup(list->pool, set->root_dir);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen list->set.index_dir = set->index_dir == NULL ||
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen strcmp(set->index_dir, set->root_dir) == 0 ? NULL :
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen list->set.control_dir = set->control_dir == NULL ||
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen strcmp(set->control_dir, set->root_dir) == 0 ? NULL :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.inbox_path = p_strdup(list->pool, set->inbox_path);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen p_strdup(list->pool, set->subscription_fname);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen list->set.maildir_name = set->maildir_name == NULL ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (list->props & MAILBOX_LIST_PROP_NO_MAILDIR_NAME) != 0 ? "" :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (set->mailbox_dir_name == NULL || *set->mailbox_dir_name == '\0')
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen else if (set->mailbox_dir_name[strlen(set->mailbox_dir_name)-1] == '/') {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen p_strconcat(list->pool, set->mailbox_dir_name, "/", NULL);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen i_info("%s: root=%s, index=%s, control=%s, inbox=%s",
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen list->set.root_dir == NULL ? "" : list->set.root_dir,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen list->set.index_dir == NULL ? "" : list->set.index_dir,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int fix_path(struct mail_namespace *ns, const char *path,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char **path_r)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (mail_user_try_home_expand(ns->user, &path) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_settings_parse(const char *data,
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen struct mail_namespace *ns, const char **error_r)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen /* <root dir> */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Home directory not set, can't expand ~/ for "
70df8f39fb3db7c49b18c855178f8172176a037aTimo Sirainen *error_r = t_strdup_printf("Unknown setting: %s", key);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Home directory not set, can't expand ~/ for "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (set->index_dir != NULL && strcmp(set->index_dir, "MEMORY") == 0)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenvoid mailbox_list_destroy(struct mailbox_list **_list)
237a6211c7fc4d6dbb58dd0467da6dba1b8f21f6Timo Sirainenconst char *mailbox_list_get_driver_name(const struct mailbox_list *list)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenchar mailbox_list_get_hierarchy_sep(const struct mailbox_list *list)
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenenum mailbox_list_flags mailbox_list_get_flags(const struct mailbox_list *list)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenmailbox_list_get_namespace(const struct mailbox_list *list)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen /* add the execute bit if either read or write bit is set */
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenmailbox_list_get_user(const struct mailbox_list *list)
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainenint mailbox_list_get_storage(struct mailbox_list **list, const char **name,
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen return (*list)->v.get_storage(list, name, storage_r);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainenvoid mailbox_list_get_closest_storage(struct mailbox_list *list,
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainenmailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m",
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen i_info("Namespace %s: Permission lookup failed from %s",
d519a0449d0e536a32db93305516fdbd7db6773dTimo Sirainen /* return safe defaults */
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen /* we're getting permissions from a file.
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen apply +x modes as necessary. */
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen /* directory's GID is used automatically for new
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen } else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen /* group has same permissions as world, so don't bother
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen changing it */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* using our own gid, no need to change it */
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (list->mail_set->mail_debug && name == NULL) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen i_info("Namespace %s: Using permissions from %s: "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_get_permissions(struct mailbox_list *list, const char *name,
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen if (list->file_create_mode != (mode_t)-1 && name == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_permissions_full(list, name, mode_r, &dir_mode, gid_r);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid mailbox_list_get_dir_permissions(struct mailbox_list *list,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (list->dir_create_mode != (mode_t)-1 && name == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_permissions_full(list, name, &file_mode,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_pattern(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.is_valid_pattern(list, pattern);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_existing_name(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.is_valid_existing_name(list, name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool mailbox_list_is_valid_create_name(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_get_path(struct mailbox_list *list, const char *name,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainenconst char *mailbox_list_get_temp_prefix(struct mailbox_list *list)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_get_global_temp_prefix(struct mailbox_list *list)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenconst char *mailbox_list_join_refpattern(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.join_refpattern(list, ref, pattern);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* the default implementation: */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* merge reference and pattern */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_get_mailbox_name_status(struct mailbox_list *list,
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen if (!mailbox_list_is_valid_existing_name(list, name)) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen return list->v.get_mailbox_name_status(list, name, status);
fbd671a3f51a5f92535923fcaf05fed1e5712ae4Timo Sirainenmailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return mailbox_list_iter_init_multiple(list, patterns, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_init_multiple(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *const *patterns,
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen return list->v.iter_init(list, patterns, flags);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic const struct mailbox_info *
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenmailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen info = mailbox_list_iter_next(ctx->backend_ctx);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (info == NULL && ctx->namespaces != NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* go to the next namespace */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen mailbox_list_iter_init_multiple(ctx->namespaces->list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_ns_iter_deinit(struct mailbox_list_iterate_context *_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_init_namespaces(struct mail_namespace *namespaces,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *const *patterns,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i, count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen pool = pool_alloconly_create("mailbox list namespaces", 256);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx = p_new(pool, struct ns_list_iterate_context, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.list = p_new(pool, struct mailbox_list, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next;
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->patterns = p_new(pool, const char *, count + 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < count; i++)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->patterns[i] = p_strdup(pool, patterns[i]);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->backend_ctx = mailbox_list_iter_init_multiple(namespaces->list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_list_iterate_context *ctx = *_ctx;
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainenint mailbox_list_set_subscribed(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return list->v.set_subscribed(list, name, set);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!mailbox_list_is_valid_existing_name(list, name)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Invalid mailbox name");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "INBOX can't be deleted.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool nullequals(const void *p1, const void *p2)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return (p1 == NULL && p2 == NULL) || (p1 != NULL && p2 != NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_rename_mailbox(struct mailbox_list *oldlist,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_get_storage(&oldlist, &oldname, &oldstorage) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_get_closest_storage(newlist, &newstorage);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!mailbox_list_is_valid_existing_name(oldlist, oldname) ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen !mailbox_list_is_valid_create_name(newlist, newname)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_PARAMS,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Invalid mailbox name");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (strcmp(oldstorage->name, newstorage->name) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Can't rename mailbox to another storage type.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!nullequals(oldlist->set.index_dir, newlist->set.index_dir) ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen !nullequals(oldlist->set.control_dir, newlist->set.control_dir)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Can't rename mailboxes across specified storages.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Renaming not supported across non-private namespaces.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return oldlist->v.rename_mailbox(oldlist, oldname, newlist, newname,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int mailbox_list_try_delete(struct mailbox_list *list, const char *dir)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (unlink_directory(dir, TRUE) == 0 || errno == ENOENT)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* We're most likely using NFS and we can't delete
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen .nfs* files. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_INUSE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "Mailbox is still open in another session, "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "can't delete it.");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint mailbox_list_delete_index_control(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* delete the index directory first, so that if we crash we don't
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen leave indexes for deleted mailboxes lying around */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*index_dir != '\0' && strcmp(index_dir, path) != 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_list_try_delete(list, index_dir) < 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* control directory next */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dir = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL);
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenstatic void node_fix_parents(struct mailbox_node *node)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* If we happened to create any of the parents, we need to mark them
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen nonexistent. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_iter_update_real(struct mailbox_list_iter_update_context *ctx,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen struct mail_namespace *ns = ctx->iter_ctx->list->ns;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_info_flags create_flags = 0, always_flags;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *p;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen (ctx->iter_ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0)
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen create_flags = MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen mailbox_tree_get(ctx->tree_ctx, name, &created);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen /* We don't want to show the parent mailboxes unless
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen something else matches them, but if they are matched
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen we want to show them having child subscriptions */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* We've a (possibly) non-subscribed parent mailbox
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen which has a subscribed child mailbox. Make sure we
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return the parent mailbox. */
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen /* see if parent matches */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen always_flags = MAILBOX_CHILDREN | ctx->parent_flags;
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainenvoid mailbox_list_iter_update(struct mailbox_list_iter_update_context *ctx,
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainenbool mailbox_list_name_is_too_large(const char *name, char sep)
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_list_get_file_type(const struct dirent *d ATTR_UNUSED)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen switch (d->d_type) {
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainenbool mailbox_list_try_get_absolute_path(struct mailbox_list *list,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char **name)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!list->mail_set->mail_full_filesystem_access)
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen /* try to expand home directory */
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen /* ~/dir - use the configured home directory */
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen if (mail_user_try_home_expand(list->ns->user, name) == 0)
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen /* ~otheruser/dir - assume we're using system users */
return FALSE;
const char *error_string;
return FALSE;
return TRUE;
const char *str;