From: Timo Sirainen Date: Thu, 18 Feb 2010 04:44:54 +0000 (+0200) Subject: mail_full_filesystem_access=yes: Replace absolute path with mailbox name whenever... X-Git-Tag: 2.0.beta3~55 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ff1777f61db8b45c72d8bcb843f9106eb0227ab6;p=thirdparty%2Fdovecot%2Fcore.git mail_full_filesystem_access=yes: Replace absolute path with mailbox name whenever possible. For example "foo", "~/mail/foo" and "~user/mail/foo" can all point to the same "foo" mailbox. When accessing it via "foo", it may have different index settings and such, so convert the other forms to it whenever possible. --HG-- branch : HEAD --- diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index d8c43c9c6d..efdea7a1d6 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -912,29 +912,58 @@ mailbox_list_get_file_type(const struct dirent *d ATTR_UNUSED) return type; } +static bool +mailbox_list_try_get_home_path(struct mailbox_list *list, const char **name) +{ + if ((*name)[1] == '/') { + /* ~/dir - use the configured home directory */ + if (mail_user_try_home_expand(list->ns->user, name) < 0) + return FALSE; + } else { + /* ~otheruser/dir - assume we're using system users */ + if (home_try_expand(name) < 0) + return FALSE; + } + return TRUE; +} + bool mailbox_list_try_get_absolute_path(struct mailbox_list *list, const char **name) { - if (!list->mail_set->mail_full_filesystem_access) - return FALSE; + const char *root_dir, *path, *mailbox_name; + unsigned int len; - if (**name == '/') - return TRUE; - if (**name != '~') + if (!list->mail_set->mail_full_filesystem_access) return FALSE; - /* try to expand home directory */ - if ((*name)[1] == '/') { - /* ~/dir - use the configured home directory */ - if (mail_user_try_home_expand(list->ns->user, name) == 0) - return TRUE; + if (**name == '~') { + /* try to expand home directory */ + if (!mailbox_list_try_get_home_path(list, name)) { + /* fallback to using actual "~name" mailbox */ + return FALSE; + } } else { - /* ~otheruser/dir - assume we're using system users */ - if (home_try_expand(name) == 0) - return TRUE; + if (**name != '/') + return FALSE; } - /* fallback to using ~dir */ - return FALSE; + + /* okay, we have an absolute path now. but check first if it points to + same directory as one of our regular mailboxes. */ + root_dir = mailbox_list_get_path(list, NULL, + MAILBOX_LIST_PATH_TYPE_MAILBOX); + len = strlen(root_dir); + if (strncmp(root_dir, *name, len) == 0 && (*name)[len] == '/') { + mailbox_name = *name + len + 1; + path = mailbox_list_get_path(list, mailbox_name, + MAILBOX_LIST_PATH_TYPE_MAILBOX); + if (strcmp(path, *name) == 0) { + /* yeah, we can replace the full path with mailbox + name. this way we can use indexes. */ + *name = mailbox_name; + return FALSE; + } + } + return TRUE; } int mailbox_list_create_parent_dir(struct mailbox_list *list,