static int
cydir_get_list_settings(struct mailbox_list_settings *list_set,
- const char *data, enum mail_storage_flags flags,
+ const char *data, struct mail_storage *storage,
const char **layout_r, const char **error_r)
{
- bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
+ bool debug = (storage->flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
*layout_r = "fs";
if (debug)
i_info("cydir: data=%s", data);
- return mailbox_list_settings_parse(data, list_set, layout_r, NULL,
- error_r);
+ return mailbox_list_settings_parse(data, list_set, storage->ns,
+ layout_r, NULL, error_r);
}
static struct mail_storage *cydir_alloc(void)
struct stat st;
const char *layout;
- if (cydir_get_list_settings(&list_set, data, _storage->flags,
+ if (cydir_get_list_settings(&list_set, data, _storage,
&layout, error_r) < 0)
return -1;
list_set.mail_storage_flags = &_storage->flags;
static int
dbox_get_list_settings(struct mailbox_list_settings *list_set,
- const char *data, enum mail_storage_flags flags,
+ const char *data, struct mail_storage *storage,
const char **layout_r, const char **alt_dir_r,
const char **error_r)
{
- bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
+ bool debug = (storage->flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
*layout_r = "fs";
if (debug)
i_info("dbox: data=%s", data);
- return mailbox_list_settings_parse(data, list_set, layout_r, alt_dir_r,
- error_r);
+ return mailbox_list_settings_parse(data, list_set, storage->ns,
+ layout_r, alt_dir_r, error_r);
}
static struct mail_storage *dbox_alloc(void)
struct stat st;
const char *layout, *alt_dir;
- if (dbox_get_list_settings(&list_set, data, _storage->flags,
+ if (dbox_get_list_settings(&list_set, data, _storage,
&layout, &alt_dir, error_r) < 0)
return -1;
list_set.mail_storage_flags = &_storage->flags;
#include "array.h"
#include "hostpid.h"
#include "str.h"
-#include "home-expand.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "unlink-old-files.h"
} else {
if (debug)
i_info("maildir: data=%s", data);
- if (mailbox_list_settings_parse(data, list_set, layout_r, NULL,
- error_r) < 0)
+ if (mailbox_list_settings_parse(data, list_set, storage->ns,
+ layout_r, NULL, error_r) < 0)
return -1;
}
#include "restrict-access.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
-#include "home-expand.h"
#include "mbox-storage.h"
#include "mbox-lock.h"
#include "mbox-file.h"
if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0 &&
p == NULL && data[strlen(data)-1] != '/') {
/* if the data points to a file, treat it as an INBOX */
- data = home_expand(data);
+ data = mail_user_home_expand(storage->ns->user, data);
if (stat(data, &st) < 0 || S_ISDIR(st.st_mode))
list_set->root_dir = data;
else {
}
} else {
if (mailbox_list_settings_parse(data, list_set,
+ storage->ns,
layout_r, NULL,
error_r) < 0)
return -1;
static int
raw_get_list_settings(struct mailbox_list_settings *list_set,
- const char *data, enum mail_storage_flags flags,
+ const char *data, struct mail_storage *storage,
const char **layout_r, const char **error_r)
{
- bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
+ bool debug = (storage->flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
*layout_r = "fs";
if (debug)
i_info("raw: data=%s", data);
- return mailbox_list_settings_parse(data, list_set, layout_r, NULL,
- error_r);
+ return mailbox_list_settings_parse(data, list_set, storage->ns,
+ layout_r, NULL, error_r);
}
static struct mail_storage *raw_alloc(void)
struct stat st;
const char *layout;
- if (raw_get_list_settings(&list_set, data, _storage->flags,
+ if (raw_get_list_settings(&list_set, data, _storage,
&layout, error_r) < 0)
return -1;
list_set.mail_storage_flags = &_storage->flags;
#include "lib.h"
#include "array.h"
-#include "home-expand.h"
#include "unlink-directory.h"
#include "imap-match.h"
#include "mailbox-tree.h"
last = p;
}
name = p = t_strdup_until(name, last+1);
- if (home_try_expand(&name) == 0) {
+ if (mailbox_list_try_get_absolute_path(ctx->ctx.list,
+ &name)) {
*vpath = p;
return name;
}
#include "lib.h"
#include "hostpid.h"
-#include "home-expand.h"
#include "mkdir-parents.h"
#include "subscription-file.h"
#include "mailbox-list-fs.h"
fs_list_get_path(struct mailbox_list *_list, const char *name,
enum mailbox_list_path_type type)
{
- struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
const struct mailbox_list_settings *set = &_list->set;
if (name == NULL) {
i_assert(mailbox_list_is_valid_pattern(_list, name));
- if ((list->list.flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0 &&
- (*name == '/' || *name == '~')) {
- if (home_try_expand(&name) == 0)
- return name;
- /* fallback to using ~dir */
- }
+ if (mailbox_list_try_get_absolute_path(_list, &name))
+ return name;
switch (type) {
case MAILBOX_LIST_PATH_TYPE_DIR:
#include "lib.h"
#include "str.h"
-#include "home-expand.h"
#include "imap-match.h"
#include "mailbox-tree.h"
#include "mailbox-list-subscriptions.h"
#include "lib.h"
#include "array.h"
#include "hostpid.h"
-#include "home-expand.h"
#include "subscription-file.h"
#include "mailbox-list-maildir.h"
{
const char *p;
- if (home_try_expand(&name) < 0) {
+ if (!mailbox_list_try_get_absolute_path(list, &name)) {
/* fallback to using as ~name */
return name;
}
*_user = NULL;
user->v.deinit(user);
}
+
+const char *mail_user_home_expand(struct mail_user *user, const char *path)
+{
+ (void)mail_user_try_home_expand(user, &path);
+ return path;
+}
+
+int mail_user_try_home_expand(struct mail_user *user, const char **pathp)
+{
+ const char *path = *pathp;
+
+ if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) {
+ if (user->home == NULL)
+ return -1;
+
+ *pathp = t_strconcat(user->home, path + 1, NULL);
+ }
+ return 0;
+}
struct mail_user *mail_user_init(const char *username, const char *home);
void mail_user_deinit(struct mail_user **user);
+/* Replace ~/ at the beginning of the path with the user's home directory. */
+const char *mail_user_home_expand(struct mail_user *user, const char *path);
+/* Returns 0 if ok, -1 if home directory isn't set. */
+int mail_user_try_home_expand(struct mail_user *user, const char **path);
+
#endif
int mailbox_list_settings_parse(const char *data,
struct mailbox_list_settings *set,
+ struct mail_namespace *ns,
const char **layout, const char **alt_dir_r,
const char **error_r);
bool mailbox_list_name_is_too_large(const char *name, char sep);
enum mailbox_list_file_type mailbox_list_get_file_type(const struct dirent *d);
+bool mailbox_list_try_get_absolute_path(struct mailbox_list *list,
+ const char **name);
void mailbox_list_clear_error(struct mailbox_list *list);
void mailbox_list_set_error(struct mailbox_list *list,
return 0;
}
-static const char *fix_path(const char *path)
+static const char *fix_path(struct mail_namespace *ns, const char *path)
{
size_t len = strlen(path);
if (len > 1 && path[len-1] == '/')
path = t_strndup(path, len-1);
- return home_expand(path);
+ return mail_user_home_expand(ns->user, path);
}
int mailbox_list_settings_parse(const char *data,
struct mailbox_list_settings *set,
+ struct mail_namespace *ns,
const char **layout, const char **alt_dir_r,
const char **error_r)
{
/* <root dir> */
tmp = t_strsplit(data, ":");
- set->root_dir = fix_path(*tmp);
+ set->root_dir = fix_path(ns, *tmp);
tmp++;
for (; *tmp != NULL; tmp++) {
}
if (strcmp(key, "INBOX") == 0)
- set->inbox_path = fix_path(value);
+ set->inbox_path = fix_path(ns, value);
else if (strcmp(key, "INDEX") == 0)
- set->index_dir = fix_path(value);
+ set->index_dir = fix_path(ns, value);
else if (strcmp(key, "CONTROL") == 0)
- set->control_dir = fix_path(value);
+ set->control_dir = fix_path(ns, value);
else if (strcmp(key, "ALT") == 0 && alt_dir_r != NULL)
- *alt_dir_r = fix_path(value);
+ *alt_dir_r = fix_path(ns, value);
else if (strcmp(key, "LAYOUT") == 0)
*layout = value;
else if (strcmp(key, "SUBSCRIPTIONS") == 0)
- set->subscription_fname = fix_path(value);
+ set->subscription_fname = fix_path(ns, value);
else if (strcmp(key, "DIRNAME") == 0)
set->maildir_name = value;
else {
return type;
}
+bool mailbox_list_try_get_absolute_path(struct mailbox_list *list,
+ const char **name)
+{
+ if ((list->flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) == 0)
+ return FALSE;
+
+ if (**name == '/')
+ return TRUE;
+ if (**name != '~')
+ 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;
+ } else {
+ /* ~otheruser/dir - assume we're using system users */
+ if (home_try_expand(name) == 0)
+ return TRUE;
+ }
+ /* fallback to using ~dir */
+ return FALSE;
+}
+
const char *mailbox_list_get_last_error(struct mailbox_list *list,
enum mail_error *error_r)
{
static void mbox_snarf_mail_storage_created(struct mail_storage *storage)
{
struct mbox_snarf_mail_storage *mstorage;
+ const char *path;
+ path = mail_user_home_expand(storage->ns->user, getenv("MBOX_SNARF"));
mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1);
- mstorage->snarf_inbox_path =
- p_strdup(storage->pool, home_expand(getenv("MBOX_SNARF")));
+ mstorage->snarf_inbox_path = p_strdup(storage->pool, path);
mstorage->module_ctx.super = storage->v;
storage->v.mailbox_open = mbox_snarf_mailbox_open;
#include "lib.h"
#include "array.h"
#include "istream.h"
-#include "home-expand.h"
#include "mail-namespace.h"
#include "mail-search-build.h"
#include "quota-private.h"
static int
virtual_get_list_settings(struct mailbox_list_settings *list_set,
- const char *data, enum mail_storage_flags flags,
+ const char *data, struct mail_storage *storage,
const char **layout_r, const char **error_r)
{
- bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
+ bool debug = (storage->flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
*layout_r = "fs";
if (debug)
i_info("virtual: data=%s", data);
- return mailbox_list_settings_parse(data, list_set, layout_r, NULL,
- error_r);
+ return mailbox_list_settings_parse(data, list_set, storage->ns,
+ layout_r, NULL, error_r);
}
static struct mail_storage *virtual_alloc(void)
struct stat st;
const char *layout;
- if (virtual_get_list_settings(&list_set, data, _storage->flags,
+ if (virtual_get_list_settings(&list_set, data, _storage,
&layout, error_r) < 0)
return -1;
list_set.mail_storage_flags = &_storage->flags;
#include "lib.h"
#include "array.h"
#include "istream-zlib.h"
-#include "home-expand.h"
#include "istream.h"
#include "maildir/maildir-storage.h"
#include "maildir/maildir-uidlist.h"