# HG changeset patch # User Timo Sirainen # Date 1104347425 -7200 # Node ID 146897976cfaf57e18c4fdd2083c38b67d8dac12 # Parent bf6a77e42151566e98361b08191308c885a4e6c5 Added mail_debug setting. Moved full_filesystem_access from global variable to flag in mail_create*() functions. diff -r bf6a77e42151 -r 146897976cfa dovecot-example.conf --- a/dovecot-example.conf Wed Dec 29 21:09:21 2004 +0200 +++ b/dovecot-example.conf Wed Dec 29 21:10:25 2004 +0200 @@ -177,6 +177,10 @@ # their mail directory anyway. #mail_chroot = +# Enable mail process debugging. This can help you figure out why Dovecot +# isn't finding your mails. +#mail_debug = no + # Default MAIL environment to use when it's not set. By leaving this empty # dovecot tries to do some automatic detection as described in # doc/mail-storages.txt. There's a few special variables you can use, eg.: diff -r bf6a77e42151 -r 146897976cfa src/imap/namespace.c --- a/src/imap/namespace.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/imap/namespace.c Wed Dec 29 21:10:25 2004 +0200 @@ -27,7 +27,7 @@ static struct namespace * namespace_add_env(pool_t pool, const char *data, unsigned int num, - const char *user) + const char *user, enum mail_storage_flags flags) { struct namespace *ns; const char *sep, *type, *prefix; @@ -55,11 +55,20 @@ if (prefix == NULL) prefix = ""; + if ((flags & MAIL_STORAGE_FLAG_DEBUG) != 0) { + i_info("Namespace: type=%s, prefix=%s, sep=%s, " + "inbox=%s, hidden=%s, subscriptions=%s", + type == NULL ? "" : type, prefix, sep == NULL ? "" : sep, + inbox ? "yes" : "no", + hidden ? "yes" : "no", + subscriptions ? "yes" : "no"); + } + ns->prefix = p_strdup(pool, prefix); ns->inbox = inbox; ns->hidden = hidden; ns->subscriptions = subscriptions; - ns->storage = mail_storage_create_with_data(data, user); + ns->storage = mail_storage_create_with_data(data, user, flags); if (ns->storage == NULL) { i_fatal("Failed to create storage for '%s' with data: %s", ns->prefix, data); @@ -74,9 +83,16 @@ struct namespace *namespace_init(pool_t pool, const char *user) { struct namespace *namespaces, *ns, **ns_p; + enum mail_storage_flags flags; const char *mail, *data; unsigned int i; + flags = 0; + if (getenv("FULL_FILESYSTEM_ACCESS") != NULL) + flags |= MAIL_STORAGE_FLAG_FULL_FS_ACCESS; + if (getenv("DEBUG") != NULL) + flags |= MAIL_STORAGE_FLAG_DEBUG; + namespaces = NULL; ns_p = &namespaces; /* first try NAMESPACE_* environments */ @@ -89,7 +105,7 @@ break; t_push(); - *ns_p = namespace_add_env(pool, data, i, user); + *ns_p = namespace_add_env(pool, data, i, user, flags); t_pop(); ns_p = &(*ns_p)->next; @@ -108,7 +124,7 @@ } ns = p_new(pool, struct namespace, 1); - ns->storage = mail_storage_create_with_data(mail, user); + ns->storage = mail_storage_create_with_data(mail, user, flags); if (ns->storage == NULL) { if (mail != NULL && *mail != '\0') i_fatal("Failed to create storage with data: %s", mail); diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/index-storage.c Wed Dec 29 21:10:25 2004 +0200 @@ -38,8 +38,10 @@ static struct timeout *to_index = NULL; static int index_storage_refcount = 0; -void index_storage_init(struct index_storage *storage __attr_unused__) +void index_storage_init(struct index_storage *storage, + enum mail_storage_flags flags) { + storage->storage.flags = flags; index_storage_refcount++; } diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/index-storage.h Wed Dec 29 21:10:25 2004 +0200 @@ -132,7 +132,8 @@ void index_storage_unref(struct mail_index *index); void index_storage_destroy_unrefed(void); -void index_storage_init(struct index_storage *storage); +void index_storage_init(struct index_storage *storage, + enum mail_storage_flags flags); void index_storage_deinit(struct index_storage *storage); struct index_mailbox * diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/maildir/maildir-list.c --- a/src/lib-storage/index/maildir/maildir-list.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/maildir/maildir-list.c Wed Dec 29 21:10:25 2004 +0200 @@ -288,7 +288,8 @@ if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) { if (!maildir_fill_subscribed(ctx, glob)) return &ctx->mailbox_ctx; - } else if (full_filesystem_access && (p = strrchr(mask, '/')) != NULL) { + } else if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (p = strrchr(mask, '/')) != NULL) { dir = t_strdup_until(mask, p); ctx->prefix = p_strdup_until(pool, mask, p+1); diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.c Wed Dec 29 21:10:25 2004 +0200 @@ -30,8 +30,10 @@ static int verify_inbox(struct index_storage *storage); static struct mail_storage * -maildir_create(const char *data, const char *user) +maildir_create(const char *data, const char *user, + enum mail_storage_flags flags) { + int debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0; struct index_storage *storage; const char *root_dir, *inbox_dir, *index_dir, *control_dir; const char *home, *path, *p; @@ -41,20 +43,35 @@ if (data == NULL || *data == '\0') { /* we'll need to figure out the maildir location ourself. - it's either root dir if we've already chroot()ed, or - $HOME/Maildir otherwise */ - if (access("/cur", R_OK|W_OK|X_OK) == 0) + It's $HOME/Maildir unless we are chrooted. */ + if ((home = getenv("HOME")) != NULL) { + path = t_strconcat(home, "/Maildir", NULL); + if (access(path, R_OK|W_OK|X_OK) == 0) { + if (debug) { + i_info("maildir: root exists (%s)", + path); + } + root_dir = path; + } else { + if (debug) { + i_info("maildir: access(%s, rwx): " + "failed: %m", path); + } + } + } else { + if (debug) + i_info("maildir: HOME not set"); + } + + if (access("/cur", R_OK|W_OK|X_OK) == 0) { + if (debug) + i_info("maildir: /cur exists, assuming chroot"); root_dir = "/"; - else { - home = getenv("HOME"); - if (home != NULL) { - path = t_strconcat(home, "/Maildir", NULL); - if (access(path, R_OK|W_OK|X_OK) == 0) - root_dir = path; - } } } else { /* [:INBOX=] [:INDEX=] [:CONTROL=] */ + if (debug) + i_info("maildir: data=%s", data); p = strchr(data, ':'); if (p == NULL) root_dir = data; @@ -74,8 +91,11 @@ } } - if (root_dir == NULL) + if (root_dir == NULL) { + if (debug) + i_info("maildir: couldn't find root dir"); return NULL; + } /* strip trailing '/' */ len = strlen(root_dir); @@ -87,6 +107,13 @@ else if (strcmp(index_dir, "MEMORY") == 0) index_dir = NULL; + if (debug) { + i_info("maildir: root=%s, index=%s, control=%s, inbox=%s", + root_dir, index_dir == NULL ? "" : index_dir, + control_dir == NULL ? "" : control_dir, + inbox_dir == NULL ? "" : inbox_dir); + } + storage = i_new(struct index_storage, 1); storage->storage = maildir_storage; @@ -100,7 +127,7 @@ storage->control_dir = i_strdup(home_expand(control_dir)); storage->user = i_strdup(user); storage->callbacks = i_new(struct mail_storage_callbacks, 1); - index_storage_init(storage); + index_storage_init(storage, flags); (void)verify_inbox(storage); return &storage->storage; @@ -122,17 +149,31 @@ i_free(storage); } -static int maildir_autodetect(const char *data) +static int maildir_autodetect(const char *data, enum mail_storage_flags flags) { + int debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0; struct stat st; + const char *path; data = t_strcut(data, ':'); - return stat(t_strconcat(data, "/cur", NULL), &st) == 0 && - S_ISDIR(st.st_mode); + path = t_strconcat(data, "/cur", NULL); + if (stat(path, &st) < 0) { + if (debug) + i_info("maildir autodetect: stat(%s) failed: %m", path); + return FALSE; + } + + if (!S_ISDIR(st.st_mode)) { + if (debug) + i_info("maildir autodetect: %s not a directory", path); + return FALSE; + } + return TRUE; } -static int maildir_is_valid_create_name(const char *name) +static int maildir_is_valid_create_name(struct mail_storage *storage, + const char *name) { size_t len; @@ -142,7 +183,7 @@ strchr(name, '*') != NULL || strchr(name, '%') != NULL) return FALSE; - if (full_filesystem_access) + if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0) return TRUE; if (*name == '~' || strchr(name, '/') != NULL) @@ -151,12 +192,13 @@ return TRUE; } -static int maildir_is_valid_existing_name(const char *name) +static int maildir_is_valid_existing_name(struct mail_storage *storage, + const char *name) { if (name[0] == '\0' || name[strlen(name)-1] == '/') return FALSE; - if (full_filesystem_access) + if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0) return TRUE; if (*name == '~' || strchr(name, '/') != NULL) @@ -181,7 +223,8 @@ const char *maildir_get_path(struct index_storage *storage, const char *name) { - if (full_filesystem_access && (*name == '/' || *name == '~')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) return maildir_get_absolute_path(name, FALSE); if (strcmp(name, "INBOX") == 0) { @@ -195,7 +238,8 @@ static const char * maildir_get_unlink_path(struct index_storage *storage, const char *name) { - if (full_filesystem_access && (*name == '/' || *name == '~')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) return maildir_get_absolute_path(name, TRUE); return maildir_get_path(storage, @@ -212,7 +256,8 @@ strcmp(storage->index_dir, storage->dir) == 0) return storage->dir; - if (full_filesystem_access && (*name == '/' || *name == '~')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) return maildir_get_absolute_path(name, FALSE); return t_strconcat(storage->index_dir, "/"MAILDIR_FS_SEP_S, name, NULL); @@ -224,7 +269,8 @@ if (storage->control_dir == NULL) return maildir_get_path(storage, name); - if (full_filesystem_access && (*name == '/' || *name == '~')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) return maildir_get_absolute_path(name, FALSE); return t_strconcat(storage->control_dir, "/"MAILDIR_FS_SEP_S, @@ -411,7 +457,7 @@ return maildir_open(storage, "INBOX", flags); } - if (!maildir_is_valid_existing_name(name)) { + if (!maildir_is_valid_existing_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return NULL; } @@ -445,7 +491,7 @@ mail_storage_clear_error(_storage); - if (!maildir_is_valid_create_name(name)) { + if (!maildir_is_valid_create_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -477,7 +523,7 @@ return -1; } - if (!maildir_is_valid_existing_name(name)) { + if (!maildir_is_valid_existing_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -624,8 +670,8 @@ mail_storage_clear_error(_storage); - if (!maildir_is_valid_existing_name(oldname) || - !maildir_is_valid_create_name(newname)) { + if (!maildir_is_valid_existing_name(_storage, oldname) || + !maildir_is_valid_create_name(_storage, newname)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -693,7 +739,7 @@ mail_storage_clear_error(_storage); - if (!maildir_is_valid_existing_name(name)) { + if (!maildir_is_valid_existing_name(_storage, name)) { *status = MAILBOX_NAME_INVALID; return 0; } @@ -704,7 +750,7 @@ return 0; } - if (!maildir_is_valid_create_name(name)) { + if (!maildir_is_valid_create_name(_storage, name)) { *status = MAILBOX_NAME_INVALID; return 0; } @@ -776,6 +822,7 @@ index_storage_get_last_error, NULL, + 0, 0 }; diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/mbox/mbox-list.c --- a/src/lib-storage/index/mbox/mbox-list.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/mbox/mbox-list.c Wed Dec 29 21:10:25 2004 +0200 @@ -63,8 +63,8 @@ static const char * mbox_get_path(struct index_storage *storage, const char *name) { - if (!full_filesystem_access || name == NULL || - (*name != '/' && *name != '~' && *name != '\0')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) == 0 || + name == NULL || (*name != '/' && *name != '~' && *name != '\0')) return t_strconcat(storage->dir, "/", name, NULL); else return home_expand(name); @@ -116,8 +116,8 @@ mail_storage_clear_error(storage); /* check that we're not trying to do any "../../" lists */ - if (!mbox_is_valid_mask(ref) || - !mbox_is_valid_mask(mask)) { + if (!mbox_is_valid_mask(storage, ref) || + !mbox_is_valid_mask(storage, mask)) { mail_storage_set_error(storage, "Invalid mask"); return &ctx->mailbox_ctx; } diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Dec 29 21:10:25 2004 +0200 @@ -59,79 +59,166 @@ return TRUE; } -static int mbox_autodetect(const char *data) +static int mbox_is_file(const char *path, const char *name, int debug) { - const char *path; + struct stat st; + + if (stat(path, &st) < 0) { + if (debug) { + i_info("mbox autodetect: %s: stat(%s) failed: %m", + name, path); + } + return FALSE; + } + if (S_ISDIR(st.st_mode)) { + if (debug) { + i_info("mbox autodetect: %s: is a directory (%s)", + name, path); + } + return FALSE; + } + if (access(path, R_OK|W_OK) < 0) { + if (debug) { + i_info("mbox autodetect: %s: no R/W access (%s)", + name, path); + } + return FALSE; + } + + if (debug) + i_info("mbox autodetect: %s: yes (%s)", name, path); + return TRUE; +} + +static int mbox_is_dir(const char *path, const char *name, int debug) +{ struct stat st; - data = t_strcut(data, ':'); + if (stat(path, &st) < 0) { + if (debug) { + i_info("mbox autodetect: %s: stat(%s) failed: %m", + name, path); + } + return FALSE; + } + if (!S_ISDIR(st.st_mode)) { + if (debug) { + i_info("mbox autodetect: %s: is not a directory (%s)", + name, path); + } + return FALSE; + } + if (access(path, R_OK|W_OK|X_OK) < 0) { + if (debug) { + i_info("mbox autodetect: %s: no R/W/X access (%s)", + name, path); + } + return FALSE; + } - /* Is it INBOX file? */ - if (*data != '\0' && stat(data, &st) == 0 && !S_ISDIR(st.st_mode) && - access(data, R_OK|W_OK) == 0) + if (debug) + i_info("mbox autodetect: %s: yes (%s)", name, path); + return TRUE; +} + +static int mbox_autodetect(const char *data, enum mail_storage_flags flags) +{ + int debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0; + const char *path; + + path = t_strcut(data, ':'); + + if (debug) { + if (strchr(data, ':') != NULL) { + i_info("mbox autodetect: data=%s, splitting ':' -> %s", + data, path); + } else { + i_info("mbox autodetect: data=%s", data); + } + } + + if (*path != '\0' && mbox_is_file(path, "INBOX file", debug)) return TRUE; - /* or directory for IMAP folders? */ - path = t_strconcat(data, "/.imap", NULL); - if (stat(path, &st) == 0 && S_ISDIR(st.st_mode) && - access(path, R_OK|W_OK|X_OK) == 0) + if (mbox_is_dir(t_strconcat(path, "/.imap", NULL), "has .imap/", debug)) return TRUE; - - path = t_strconcat(data, "/inbox", NULL); - if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) && - access(path, R_OK|W_OK) == 0) + if (mbox_is_file(t_strconcat(path, "/inbox", NULL), "has inbox", debug)) return TRUE; - - path = t_strconcat(data, "/mbox", NULL); - if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) && - access(path, R_OK|W_OK) == 0) + if (mbox_is_file(t_strconcat(path, "/mbox", NULL), "has mbox", debug)) return TRUE; return FALSE; } -static const char *get_root_dir(void) +static const char *get_root_dir(enum mail_storage_flags flags) { const char *home, *path; - - if (mbox_autodetect("")) - return "/"; + int debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0; home = getenv("HOME"); if (home != NULL) { path = t_strconcat(home, "/mail", NULL); - if (access(path, R_OK|W_OK|X_OK) == 0) + if (access(path, R_OK|W_OK|X_OK) == 0) { + if (debug) + i_info("mbox: root exists (%s)", path); return path; + } + if (debug) + i_info("mbox: root: access(%s, rwx) failed: %m", path); path = t_strconcat(home, "/Mail", NULL); - if (access(path, R_OK|W_OK|X_OK) == 0) + if (access(path, R_OK|W_OK|X_OK) == 0) { + if (debug) + i_info("mbox: root exists (%s)", path); return path; + } + if (debug) + i_info("mbox: root: access(%s, rwx) failed: %m", path); } + if (debug) + i_info("mbox: checking if we are chrooted:"); + if (mbox_autodetect("", flags)) + return "/"; + + if (debug) + i_info("mbox: root directory not found"); + return NULL; } -static const char *get_inbox_file(const char *root_dir, int only_root) +static const char * +get_inbox_file(const char *root_dir, int only_root, int debug) { const char *user, *path; - if (!only_root) { - user = getenv("USER"); - if (user != NULL) { - path = t_strconcat("/var/mail/", user, NULL); - if (access(path, R_OK|W_OK) == 0) - return path; + if (!only_root && (user = getenv("USER")) != NULL) { + path = t_strconcat("/var/mail/", user, NULL); + if (access(path, R_OK|W_OK) == 0) { + if (debug) + i_info("mbox: INBOX exists (%s)", path); + return path; + } + if (debug) + i_info("mbox: INBOX: access(%s, rw) failed: %m", path); - path = t_strconcat("/var/spool/mail/", user, NULL); - if (access(path, R_OK|W_OK) == 0) - return path; + path = t_strconcat("/var/spool/mail/", user, NULL); + if (access(path, R_OK|W_OK) == 0) { + if (debug) + i_info("mbox: INBOX exists (%s)", path); + return path; } + if (debug) + i_info("mbox: INBOX: access(%s, rw) failed: %m", path); } - return t_strconcat(root_dir, "/inbox", NULL); + path = t_strconcat(root_dir, "/inbox", NULL); + if (debug) + i_info("mbox: INBOX defaulted to %s", path); + return path; } -static const char *create_root_dir(void) +static const char *create_root_dir(int debug) { const char *home, *path; @@ -148,11 +235,15 @@ return NULL; } + if (debug) + i_info("mbox: root directory created: %s", path); return path; } -static struct mail_storage *mbox_create(const char *data, const char *user) +static struct mail_storage * +mbox_create(const char *data, const char *user, enum mail_storage_flags flags) { + int debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0; struct index_storage *storage; const char *root_dir, *inbox_file, *index_dir, *p; struct stat st; @@ -165,21 +256,23 @@ /* we'll need to figure out the mail location ourself. it's root dir if we've already chroot()ed, otherwise either $HOME/mail or $HOME/Mail */ - root_dir = get_root_dir(); + root_dir = get_root_dir(flags); } else { /* | [:INBOX=] [:INDEX=] */ + if (debug) + i_info("mbox: data=%s", data); p = strchr(data, ':'); if (p == NULL) { if (stat(data, &st) < 0) { - i_error("Invalid mbox file %s: %m", data); + i_error("Invalid mbox path %s: %m", data); return NULL; } if (S_ISDIR(st.st_mode)) root_dir = data; else { - root_dir = get_root_dir(); + root_dir = get_root_dir(flags); inbox_file = data; } } else { @@ -196,7 +289,7 @@ } if (root_dir == NULL) { - root_dir = create_root_dir(); + root_dir = create_root_dir(debug); if (root_dir == NULL) return NULL; } else { @@ -214,13 +307,19 @@ } if (inbox_file == NULL) - inbox_file = get_inbox_file(root_dir, !autodetect); + inbox_file = get_inbox_file(root_dir, !autodetect, debug); if (index_dir == NULL) index_dir = root_dir; else if (strcmp(index_dir, "MEMORY") == 0) index_dir = NULL; + if (debug) { + i_info("mbox: root=%s, index=%s, inbox=%s", + root_dir, index_dir == NULL ? "" : index_dir, + inbox_file == NULL ? "" : inbox_file); + } + storage = i_new(struct index_storage, 1); storage->storage = mbox_storage; @@ -229,7 +328,7 @@ storage->index_dir = i_strdup(home_expand(index_dir)); storage->user = i_strdup(user); storage->callbacks = i_new(struct mail_storage_callbacks, 1); - index_storage_init(storage); + index_storage_init(storage, flags); return &storage->storage; } @@ -247,12 +346,12 @@ i_free(storage); } -int mbox_is_valid_mask(const char *mask) +int mbox_is_valid_mask(struct mail_storage *storage, const char *mask) { const char *p; int newdir; - if (full_filesystem_access) + if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0) return TRUE; /* make sure it's not absolute path */ @@ -270,7 +369,8 @@ return TRUE; } -static int mbox_is_valid_create_name(const char *name) +static int mbox_is_valid_create_name(struct mail_storage *storage, + const char *name) { size_t len; @@ -279,10 +379,11 @@ strchr(name, '*') != NULL || strchr(name, '%') != NULL) return FALSE; - return mbox_is_valid_mask(name); + return mbox_is_valid_mask(storage, name); } -static int mbox_is_valid_existing_name(const char *name) +static int mbox_is_valid_existing_name(struct mail_storage *storage, + const char *name) { size_t len; @@ -290,7 +391,7 @@ if (name[0] == '\0' || name[len-1] == '/') return FALSE; - return mbox_is_valid_mask(name); + return mbox_is_valid_mask(storage, name); } static const char *mbox_get_index_dir(struct index_storage *storage, @@ -301,7 +402,8 @@ if (storage->index_dir == NULL) return NULL; - if (full_filesystem_access && (*name == '/' || *name == '~')) { + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) { name = home_expand(name); p = strrchr(name, '/'); return t_strconcat(t_strdup_until(name, p), @@ -361,7 +463,8 @@ { if (strcmp(name, "INBOX") == 0) return storage->inbox_path; - if (full_filesystem_access && (*name == '/' || *name == '~')) + if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 && + (*name == '/' || *name == '~')) return home_expand(name); return t_strconcat(storage->dir, "/", name, NULL); } @@ -449,7 +552,7 @@ return mbox_open(storage, "INBOX", flags); } - if (!mbox_is_valid_existing_name(name)) { + if (!mbox_is_valid_existing_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return NULL; } @@ -490,7 +593,7 @@ mail_storage_clear_error(_storage); - if (!mbox_is_valid_create_name(name)) { + if (!mbox_is_valid_create_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -573,7 +676,7 @@ return -1; } - if (!mbox_is_valid_existing_name(name)) { + if (!mbox_is_valid_existing_name(_storage, name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -660,8 +763,8 @@ mail_storage_clear_error(_storage); - if (!mbox_is_valid_existing_name(oldname) || - !mbox_is_valid_create_name(newname)) { + if (!mbox_is_valid_existing_name(_storage, oldname) || + !mbox_is_valid_create_name(_storage, newname)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; } @@ -757,7 +860,7 @@ mail_storage_clear_error(_storage); - if (!mbox_is_valid_existing_name(name)) { + if (!mbox_is_valid_existing_name(_storage, name)) { *status = MAILBOX_NAME_INVALID; return 0; } @@ -768,7 +871,7 @@ return 0; } - if (!mbox_is_valid_create_name(name)) { + if (!mbox_is_valid_create_name(_storage, name)) { *status = MAILBOX_NAME_INVALID; return 0; } @@ -843,6 +946,7 @@ index_storage_get_last_error, NULL, + 0, 0 }; diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/index/mbox/mbox-storage.h --- a/src/lib-storage/index/mbox/mbox-storage.h Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.h Wed Dec 29 21:10:25 2004 +0200 @@ -53,6 +53,6 @@ int mbox_transaction_save_commit(struct mbox_save_context *ctx); void mbox_transaction_save_rollback(struct mbox_save_context *ctx); -int mbox_is_valid_mask(const char *mask); +int mbox_is_valid_mask(struct mail_storage *storage, const char *mask); #endif diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/mail-storage-private.h Wed Dec 29 21:10:25 2004 +0200 @@ -7,10 +7,11 @@ char *name; char hierarchy_sep; - struct mail_storage *(*create)(const char *data, const char *user); + struct mail_storage *(*create)(const char *data, const char *user, + enum mail_storage_flags flags); void (*destroy)(struct mail_storage *storage); - int (*autodetect)(const char *data); + int (*autodetect)(const char *data, enum mail_storage_flags flags); void (*set_callbacks)(struct mail_storage *storage, struct mail_storage_callbacks *callbacks, @@ -46,6 +47,7 @@ /* private: */ char *error; + enum mail_storage_flags flags; unsigned int syntax_error:1; /* Give a BAD reply instead of NO */ }; diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/mail-storage.c Wed Dec 29 21:10:25 2004 +0200 @@ -19,11 +19,9 @@ }; static struct mail_storage_list *storages = NULL; -int full_filesystem_access = FALSE; void mail_storage_init(void) { - full_filesystem_access = getenv("FULL_FILESYSTEM_ACCESS") != NULL; } void mail_storage_deinit(void) @@ -69,7 +67,8 @@ } struct mail_storage * -mail_storage_create(const char *name, const char *data, const char *user) +mail_storage_create(const char *name, const char *data, const char *user, + enum mail_storage_flags flags) { struct mail_storage_list *list; @@ -77,20 +76,20 @@ for (list = storages; list != NULL; list = list->next) { if (strcasecmp(list->storage->name, name) == 0) - return list->storage->create(data, user); + return list->storage->create(data, user, flags); } return NULL; } struct mail_storage * -mail_storage_create_default(const char *user) +mail_storage_create_default(const char *user, enum mail_storage_flags flags) { struct mail_storage_list *list; struct mail_storage *storage; for (list = storages; list != NULL; list = list->next) { - storage = list->storage->create(NULL, user); + storage = list->storage->create(NULL, user, flags); if (storage != NULL) return storage; } @@ -98,12 +97,13 @@ return NULL; } -static struct mail_storage *mail_storage_autodetect(const char *data) +static struct mail_storage * +mail_storage_autodetect(const char *data, enum mail_storage_flags flags) { struct mail_storage_list *list; for (list = storages; list != NULL; list = list->next) { - if (list->storage->autodetect(data)) + if (list->storage->autodetect(data, flags)) return list->storage; } @@ -111,13 +111,14 @@ } struct mail_storage * -mail_storage_create_with_data(const char *data, const char *user) +mail_storage_create_with_data(const char *data, const char *user, + enum mail_storage_flags flags) { struct mail_storage *storage; const char *p, *name; if (data == NULL || *data == '\0') - return mail_storage_create_default(user); + return mail_storage_create_default(user, flags); /* check if we're in the form of mailformat:data (eg. maildir:Maildir) */ @@ -126,11 +127,11 @@ if (*p == ':') { name = t_strdup_until(data, p); - storage = mail_storage_create(name, p+1, user); + storage = mail_storage_create(name, p+1, user, flags); } else { - storage = mail_storage_autodetect(data); + storage = mail_storage_autodetect(data, flags); if (storage != NULL) - storage = storage->create(data, user); + storage = storage->create(data, user, flags); } return storage; diff -r bf6a77e42151 -r 146897976cfa src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Wed Dec 29 21:09:21 2004 +0200 +++ b/src/lib-storage/mail-storage.h Wed Dec 29 21:10:25 2004 +0200 @@ -5,6 +5,13 @@ #include "mail-types.h" +enum mail_storage_flags { + /* Print debugging information while initializing the storage */ + MAIL_STORAGE_FLAG_DEBUG = 0x01, + /* Allow full filesystem access with absolute or relative paths. */ + MAIL_STORAGE_FLAG_FULL_FS_ACCESS = 0x02 +}; + enum mailbox_open_flags { MAILBOX_OPEN_READONLY = 0x01, MAILBOX_OPEN_FAST = 0x02, @@ -156,8 +163,6 @@ typedef void mailbox_notify_callback_t(struct mailbox *box, void *context); -extern int full_filesystem_access; - void mail_storage_init(void); void mail_storage_deinit(void); @@ -176,12 +181,15 @@ If namespace is non-NULL, all mailbox names are expected to begin with it. hierarchy_sep overrides the default separator if it's not '\0'. */ struct mail_storage * -mail_storage_create(const char *name, const char *data, const char *user); +mail_storage_create(const char *name, const char *data, const char *user, + enum mail_storage_flags flags); void mail_storage_destroy(struct mail_storage *storage); -struct mail_storage *mail_storage_create_default(const char *user); +struct mail_storage * +mail_storage_create_default(const char *user, enum mail_storage_flags flags); struct mail_storage * -mail_storage_create_with_data(const char *data, const char *user); +mail_storage_create_with_data(const char *data, const char *user, + enum mail_storage_flags flags); char mail_storage_get_hierarchy_sep(struct mail_storage *storage); diff -r bf6a77e42151 -r 146897976cfa src/master/mail-process.c --- a/src/master/mail-process.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/master/mail-process.c Wed Dec 29 21:10:25 2004 +0200 @@ -214,6 +214,8 @@ env_put("MAILDIR_STAT_DIRS=1"); if (set->maildir_copy_with_hardlinks) env_put("MAILDIR_COPY_WITH_HARDLINKS=1"); + if (set->mail_debug) + env_put("DEBUG=1"); if (set->mail_full_filesystem_access) env_put("FULL_FILESYSTEM_ACCESS=1"); if (set->pop3_no_flag_updates) diff -r bf6a77e42151 -r 146897976cfa src/master/master-settings.c --- a/src/master/master-settings.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/master/master-settings.c Wed Dec 29 21:10:25 2004 +0200 @@ -91,6 +91,7 @@ DEF(SET_STR, mail_cache_fields), DEF(SET_STR, mail_never_cache_fields), DEF(SET_INT, mailbox_idle_check_interval), + DEF(SET_BOOL, mail_debug), DEF(SET_BOOL, mail_full_filesystem_access), DEF(SET_INT, mail_max_keyword_length), DEF(SET_BOOL, mail_save_crlf), @@ -258,6 +259,7 @@ MEMBER(mail_cache_fields) "flags", MEMBER(mail_never_cache_fields) "imap.envelope", MEMBER(mailbox_idle_check_interval) 30, + MEMBER(mail_debug) FALSE, MEMBER(mail_full_filesystem_access) FALSE, MEMBER(mail_max_keyword_length) 50, MEMBER(mail_save_crlf) FALSE, diff -r bf6a77e42151 -r 146897976cfa src/master/master-settings.h --- a/src/master/master-settings.h Wed Dec 29 21:09:21 2004 +0200 +++ b/src/master/master-settings.h Wed Dec 29 21:10:25 2004 +0200 @@ -62,6 +62,7 @@ const char *mail_cache_fields; const char *mail_never_cache_fields; unsigned int mailbox_idle_check_interval; + int mail_debug; int mail_full_filesystem_access; int mail_max_keyword_length; int mail_save_crlf; diff -r bf6a77e42151 -r 146897976cfa src/pop3/main.c --- a/src/pop3/main.c Wed Dec 29 21:09:21 2004 +0200 +++ b/src/pop3/main.c Wed Dec 29 21:10:25 2004 +0200 @@ -141,6 +141,7 @@ static int main_init(void) { + enum mail_storage_flags flags; struct mail_storage *storage; const char *mail; @@ -172,7 +173,13 @@ uidl_format = "%v.%u"; uidl_keymask = parse_uidl_keymask(uidl_format); - storage = mail_storage_create_with_data(mail, getenv("USER")); + flags = 0; + if (getenv("FULL_FILESYSTEM_ACCESS") != NULL) + flags |= MAIL_STORAGE_FLAG_FULL_FS_ACCESS; + if (getenv("DEBUG") != NULL) + flags |= MAIL_STORAGE_FLAG_DEBUG; + + storage = mail_storage_create_with_data(mail, getenv("USER"), flags); if (storage == NULL) { /* failed */ if (mail != NULL && *mail != '\0')