Mercurial > dovecot > core-2.2
changeset 5500:4862cb37106c HEAD
Moved namespace handling to lib-storage. Beginnings of namespace support for
non-IMAP parts of Dovecot.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 03 Apr 2007 11:34:27 +0300 |
parents | e1e19a0db57d |
children | e9745c1c4d14 |
files | src/deliver/deliver.c src/deliver/deliver.h src/imap/Makefile.am src/imap/client.c src/imap/client.h src/imap/cmd-create.c src/imap/cmd-list.c src/imap/cmd-namespace.c src/imap/commands-util.c src/imap/commands-util.h src/imap/main.c src/imap/namespace.c src/imap/namespace.h src/lib-storage/Makefile.am src/lib-storage/mail-namespace.c src/lib-storage/mail-namespace.h src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/plugins/convert/convert-storage.c src/plugins/expire/expire-tool.c src/plugins/lazy-expunge/lazy-expunge-plugin.c src/pop3/client.c src/pop3/client.h src/pop3/main.c |
diffstat | 25 files changed, 478 insertions(+), 433 deletions(-) [+] |
line wrap: on
line diff
--- a/src/deliver/deliver.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/deliver/deliver.c Tue Apr 03 11:34:27 2007 +0300 @@ -18,6 +18,7 @@ #include "message-address.h" #include "istream-header-filter.h" #include "mbox-storage.h" +#include "mail-namespace.h" #include "dict-client.h" #include "mbox-from.h" #include "auth-client.h" @@ -75,26 +76,35 @@ } static struct mailbox * -mailbox_open_or_create_synced(struct mail_storage *storage, const char *name) +mailbox_open_or_create_synced(struct mail_namespace *namespaces, + struct mail_storage **storage_r, const char *name) { + struct mail_namespace *ns; struct mailbox *box; bool syntax, temp; - box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | + ns = mail_namespace_find(namespaces, &name); + if (ns == NULL) { + *storage_r = NULL; + return NULL; + } + *storage_r = ns->storage; + + box = mailbox_open(ns->storage, name, NULL, MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (box != NULL || no_mailbox_autocreate) return box; - (void)mail_storage_get_last_error(storage, &syntax, &temp); + (void)mail_storage_get_last_error(ns->storage, &syntax, &temp); if (syntax || temp) return NULL; /* probably the mailbox just doesn't exist. try creating it. */ - if (mail_storage_mailbox_create(storage, name, FALSE) < 0) + if (mail_storage_mailbox_create(ns->storage, name, FALSE) < 0) return NULL; /* and try opening again */ - box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | + box = mailbox_open(ns->storage, name, NULL, MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (box == NULL) return NULL; @@ -106,7 +116,8 @@ return box; } -int deliver_save(struct mail_storage *storage, const char *mailbox, +int deliver_save(struct mail_namespace *namespaces, + struct mail_storage **storage_r, const char *mailbox, struct mail *mail, enum mail_flags flags, const char *const *keywords) { @@ -119,7 +130,7 @@ if (strcmp(mailbox, default_mailbox_name) == 0) tried_default_save = TRUE; - box = mailbox_open_or_create_synced(storage, mailbox); + box = mailbox_open_or_create_synced(namespaces, storage_r, mailbox); if (box == NULL) return -1; @@ -480,14 +491,14 @@ const char *auth_socket; const char *home, *destination, *user, *mail_env, *value; const struct var_expand_table *table; - enum mail_storage_flags flags; - enum file_lock_method lock_method; - struct mail_storage *storage, *mbox_storage; + struct mail_namespace *ns, *mbox_ns; + struct mail_storage *storage; struct mailbox *box; struct istream *input; struct mailbox_transaction_context *t; struct mail *mail; uid_t process_euid; + pool_t namespace_pool; int i, ret; i_set_failure_exit_callback(failure_exit_callback); @@ -644,7 +655,8 @@ mail_storage_register_all(); mailbox_list_register_all(); - /* MAIL comes from userdb, MAIL_LOCATION from dovecot.conf */ + /* MAIL comes from userdb, MAIL_LOCATION from dovecot.conf. + FIXME: should remove these and support namespaces.. */ mail_env = getenv("MAIL"); if (mail_env == NULL) mail_env = getenv("MAIL_LOCATION"); @@ -656,23 +668,20 @@ table = get_var_expand_table(destination, getenv("HOME")); mail_env = expand_mail_env(mail_env, table); } + env_put(t_strconcat("MAIL=", mail_env, NULL)); module_dir_init(modules); - /* FIXME: how should we handle namespaces? */ - mail_storage_parse_env(&flags, &lock_method); - storage = mail_storage_create(NULL, mail_env, destination, - flags, lock_method); - if (storage == NULL) { - i_fatal_status(EX_TEMPFAIL, - "Failed to create storage for '%s' with mail '%s'", - destination, mail_env == NULL ? "(null)" : mail_env); - } + namespace_pool = pool_alloconly_create("namespaces", 1024); + if (mail_namespaces_init(namespace_pool, destination, &ns) < 0) + exit(EX_TEMPFAIL); - mbox_storage = mail_storage_create("mbox", "/tmp", destination, 0, - FILE_LOCK_METHOD_FCNTL); + mbox_ns = mail_namespaces_init_empty(namespace_pool); + if (mail_storage_create(mbox_ns, "mbox", "/tmp", destination, + 0, FILE_LOCK_METHOD_FCNTL) < 0) + i_fatal("Couldn't create internal mbox storage"); input = create_mbox_stream(0, envelope_sender); - box = mailbox_open(mbox_storage, "Dovecot Delivery Mail", input, + box = mailbox_open(mbox_ns->storage, "Dovecot Delivery Mail", input, MAILBOX_OPEN_NO_INDEX_FILES | MAILBOX_OPEN_MBOX_ONE_MSG_ONLY); if (box == NULL) @@ -687,18 +696,18 @@ default_mailbox_name = mailbox; ret = deliver_mail == NULL ? 0 : - deliver_mail(storage, mail, destination, mailbox); + deliver_mail(ns, &storage, mail, destination, mailbox); if (ret == 0 || (ret < 0 && !tried_default_save)) { /* plugins didn't handle this. save into the default mailbox. */ i_stream_seek(input, 0); - ret = deliver_save(storage, mailbox, mail, 0, NULL); + ret = deliver_save(ns, &storage, mailbox, mail, 0, NULL); } if (ret < 0 && strcasecmp(mailbox, "INBOX") != 0) { /* still didn't work. try once more to save it to INBOX. */ i_stream_seek(input, 0); - ret = deliver_save(storage, "INBOX", mail, 0, NULL); + ret = deliver_save(ns, &storage, "INBOX", mail, 0, NULL); } if (ret < 0) { @@ -723,8 +732,8 @@ mailbox_transaction_rollback(&t); mailbox_close(&box); - mail_storage_destroy(&mbox_storage); - mail_storage_destroy(&storage); + mail_namespaces_deinit(&mbox_ns); + mail_namespaces_deinit(&ns); module_dir_unload(&modules); mail_storage_deinit();
--- a/src/deliver/deliver.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/deliver/deliver.h Tue Apr 03 11:34:27 2007 +0300 @@ -14,7 +14,9 @@ extern struct deliver_settings *deliver_set; -typedef int deliver_mail_func_t(struct mail_storage *storage, struct mail *mail, +typedef int deliver_mail_func_t(struct mail_namespace *namespaces, + struct mail_storage **storage_r, + struct mail *mail, const char *username, const char *mailbox); extern deliver_mail_func_t *deliver_mail; @@ -22,7 +24,8 @@ void deliver_env_clean(void); /* Save a mail into given mailbox with given flags and keywords. */ -int deliver_save(struct mail_storage *storage, const char *mailbox, +int deliver_save(struct mail_namespace *namespaces, + struct mail_storage **storage_r, const char *mailbox, struct mail *mail, enum mail_flags flags, const char *const *keywords);
--- a/src/imap/Makefile.am Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/Makefile.am Tue Apr 03 11:34:27 2007 +0300 @@ -84,8 +84,7 @@ imap-sync.c \ imap-thread.c \ mail-storage-callbacks.c \ - main.c \ - namespace.c + main.c headers = \ @@ -99,8 +98,7 @@ imap-search.h \ imap-sort.h \ imap-sync.h \ - imap-thread.h \ - namespace.h + imap-thread.h if INSTALL_HEADERS pkginc_libdir=$(pkgincludedir)/src/imap
--- a/src/imap/client.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/client.c Tue Apr 03 11:34:27 2007 +0300 @@ -6,7 +6,7 @@ #include "istream.h" #include "ostream.h" #include "commands.h" -#include "namespace.h" +#include "mail-namespace.h" #include <stdlib.h> #include <unistd.h> @@ -17,7 +17,7 @@ static struct timeout *to_idle; struct client *client_create(int fd_in, int fd_out, - struct namespace *namespaces) + struct mail_namespace *namespaces) { struct client *client; @@ -95,7 +95,7 @@ if (client->mailbox != NULL) mailbox_close(&client->mailbox); - namespace_deinit(client->namespaces); + mail_namespaces_deinit(&client->namespaces); if (client->free_parser != NULL) imap_parser_destroy(&client->free_parser);
--- a/src/imap/client.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/client.h Tue Apr 03 11:34:27 2007 +0300 @@ -43,7 +43,7 @@ struct istream *input; struct ostream *output; - struct namespace *namespaces; + struct mail_namespace *namespaces; struct mailbox *mailbox; struct mailbox_keywords keywords; unsigned int select_counter; /* increased when mailbox is changed */ @@ -73,7 +73,7 @@ /* Create new client with specified input/output handles. socket specifies if the handle is a socket. */ struct client *client_create(int fd_in, int fd_out, - struct namespace *namespaces); + struct mail_namespace *namespaces); void client_destroy(struct client *client, const char *reason); /* Disconnect client connection */
--- a/src/imap/cmd-create.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/cmd-create.c Tue Apr 03 11:34:27 2007 +0300 @@ -1,12 +1,12 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "common.h" -#include "namespace.h" +#include "mail-namespace.h" #include "commands.h" bool cmd_create(struct client_command_context *cmd) { - struct namespace *ns; + struct mail_namespace *ns; const char *mailbox, *full_mailbox; bool directory; size_t len;
--- a/src/imap/cmd-list.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/cmd-list.c Tue Apr 03 11:34:27 2007 +0300 @@ -6,7 +6,7 @@ #include "imap-quote.h" #include "imap-match.h" #include "commands.h" -#include "namespace.h" +#include "mail-namespace.h" enum { _MAILBOX_LIST_ITER_HIDE_CHILDREN = 0x1000000, @@ -18,7 +18,7 @@ const char *mask; enum mailbox_list_flags list_flags; - struct namespace *ns; + struct mail_namespace *ns; struct mailbox_list_iterate_context *list_iter; struct imap_match_glob *glob; @@ -232,7 +232,7 @@ struct cmd_list_context *ctx) { struct client *client = cmd->client; - struct namespace *ns = ctx->ns; + struct mail_namespace *ns = ctx->ns; const char *cur_ns_prefix, *cur_ref, *cur_mask; enum imap_match_result match; enum imap_match_result inbox_match; @@ -392,8 +392,8 @@ ctx->glob = NULL; } - cur_ref = namespace_fix_sep(ns, cur_ref); - cur_mask = namespace_fix_sep(ns, cur_mask); + cur_ref = mail_namespace_fix_sep(ns, cur_ref); + cur_mask = mail_namespace_fix_sep(ns, cur_mask); list_flags = ctx->list_flags; if (ctx->match_inbox) @@ -438,7 +438,7 @@ bool _cmd_list_full(struct client_command_context *cmd, bool lsub) { struct client *client = cmd->client; - struct namespace *ns; + struct mail_namespace *ns; struct imap_arg *args; enum mailbox_list_flags list_flags; struct cmd_list_context *ctx; @@ -485,19 +485,20 @@ concept which probably no other client uses than Pine. Just try our best to emulate UW-IMAP behavior and hopefully we're fine. */ - ns = namespace_find_visible(client->namespaces, &ref); + ns = mail_namespace_find_visible(client->namespaces, &ref); if (ns != NULL) ns_prefix = ns->prefix; else { const char *empty = ""; ns_prefix = ""; - ns = namespace_find(client->namespaces, &empty); + ns = mail_namespace_find(client->namespaces, &empty); if (ns == NULL) { /* we must reply something. use INBOX namespace's separator. */ const char *inbox = "INBOX"; - ns = namespace_find(client->namespaces, &inbox); + ns = mail_namespace_find(client->namespaces, + &inbox); } }
--- a/src/imap/cmd-namespace.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/cmd-namespace.c Tue Apr 03 11:34:27 2007 +0300 @@ -4,10 +4,10 @@ #include "str.h" #include "imap-quote.h" #include "commands.h" -#include "namespace.h" +#include "mail-namespace.h" -static void list_namespaces(struct namespace *ns, enum namespace_type type, - string_t *str) +static void list_namespaces(struct mail_namespace *ns, + enum namespace_type type, string_t *str) { bool found = FALSE;
--- a/src/imap/commands-util.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/commands-util.c Tue Apr 03 11:34:27 2007 +0300 @@ -10,7 +10,7 @@ #include "imap-parser.h" #include "imap-sync.h" #include "imap-util.h" -#include "namespace.h" +#include "mail-namespace.h" /* Maximum length for mailbox name, including it's path. This isn't fully exact since the user can create folder hierarchy with small names, then @@ -18,12 +18,12 @@ to them, mbox/maildir currently allow paths only up to PATH_MAX. */ #define MAILBOX_MAX_NAME_LEN 512 -struct namespace * +struct mail_namespace * client_find_namespace(struct client_command_context *cmd, const char **mailbox) { - struct namespace *ns; + struct mail_namespace *ns; - ns = namespace_find(cmd->client->namespaces, mailbox); + ns = mail_namespace_find(cmd->client->namespaces, mailbox); if (ns != NULL) return ns; @@ -34,7 +34,7 @@ struct mail_storage * client_find_storage(struct client_command_context *cmd, const char **mailbox) { - struct namespace *ns; + struct mail_namespace *ns; ns = client_find_namespace(cmd, mailbox); return ns == NULL ? NULL : ns->storage; @@ -44,7 +44,7 @@ const char *mailbox, bool should_exist, bool should_not_exist) { - struct namespace *ns; + struct mail_namespace *ns; struct mailbox_list *list; enum mailbox_name_status mailbox_status; const char *orig_mailbox, *p;
--- a/src/imap/commands-util.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/commands-util.h Tue Apr 03 11:34:27 2007 +0300 @@ -11,7 +11,7 @@ /* Finds namespace for given mailbox from namespaces. If not found, sends "Unknown namespace" error message to client. */ -struct namespace * +struct mail_namespace * client_find_namespace(struct client_command_context *cmd, const char **mailbox); /* Finds mail storage for given mailbox from namespaces. If not found, sends "Unknown namespace" error message to client. */
--- a/src/imap/main.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/imap/main.c Tue Apr 03 11:34:27 2007 +0300 @@ -14,7 +14,7 @@ #include "dict-client.h" #include "mail-storage.h" #include "commands.h" -#include "namespace.h" +#include "mail-namespace.h" #include "imap-thread.h" #include <stdio.h> @@ -163,6 +163,7 @@ static void main_init(void) { struct client *client; + struct mail_namespace *ns; const char *user, *str; lib_signals_init(); @@ -232,7 +233,9 @@ parse_workarounds(); namespace_pool = pool_alloconly_create("namespaces", 1024); - client = client_create(0, 1, namespace_init(namespace_pool, user)); + if (mail_namespaces_init(namespace_pool, user, &ns) < 0) + exit(FATAL_DEFAULT); + client = client_create(0, 1, ns); o_stream_cork(client->output); if (IS_STANDALONE()) {
--- a/src/imap/namespace.c Tue Apr 03 10:31:48 2007 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,248 +0,0 @@ -/* Copyright (C) 2003 Timo Sirainen */ - -#include "common.h" -#include "file-lock.h" -#include "commands.h" -#include "namespace.h" - -#include <stdlib.h> - -static void namespace_init_storage(struct namespace *ns) -{ - ns->prefix_len = strlen(ns->prefix); - ns->real_sep = mail_storage_get_hierarchy_sep(ns->storage); - - if (ns->sep == '\0') - ns->sep = ns->real_sep; - - if (ns->sep == '"' || ns->sep == '\\') { - ns->sep_str[0] = '\\'; - ns->sep_str[1] = ns->sep; - } else { - ns->sep_str[0] = ns->sep; - } -} - -static struct namespace * -namespace_add_env(pool_t pool, const char *data, unsigned int num, - const char *user, enum mail_storage_flags flags, - enum file_lock_method lock_method) -{ - struct namespace *ns; - const char *sep, *type, *prefix; - bool inbox, hidden, subscriptions; - - ns = p_new(pool, struct namespace, 1); - - sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num)); - type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num)); - prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num)); - inbox = getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL; - hidden = getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL; - subscriptions = getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS", - num)) != NULL; - - if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0) - ns->type = NAMESPACE_PRIVATE; - else if (strncmp(type, "shared", 6) == 0) - ns->type = NAMESPACE_SHARED; - else if (strncmp(type, "public", 6) == 0) - ns->type = NAMESPACE_PUBLIC; - else - i_fatal("Unknown namespace type: %s", type); - - if (ns->type != NAMESPACE_PRIVATE) - flags |= MAIL_STORAGE_FLAG_SHARED_NAMESPACE; - if (ns->inbox) - flags |= MAIL_STORAGE_FLAG_HAS_INBOX; - - 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(NULL, data, user, flags, lock_method); - if (ns->storage == NULL) { - i_fatal("Failed to create storage for '%s' with data: %s", - ns->prefix, data); - } - - if (sep != NULL) - ns->sep = *sep; - namespace_init_storage(ns); - return ns; -} - -struct namespace *namespace_init(pool_t pool, const char *user) -{ - struct namespace *namespaces, *ns, **ns_p; - enum mail_storage_flags flags; - enum file_lock_method lock_method; - const char *mail, *data; - unsigned int i; - - mail_storage_parse_env(&flags, &lock_method); - namespaces = NULL; ns_p = &namespaces; - - /* first try NAMESPACE_* environments */ - for (i = 1; ; i++) { - t_push(); - data = getenv(t_strdup_printf("NAMESPACE_%u", i)); - t_pop(); - - if (data == NULL) - break; - - t_push(); - *ns_p = namespace_add_env(pool, data, i, user, flags, - lock_method); - t_pop(); - - ns_p = &(*ns_p)->next; - } - - if (namespaces != NULL) - return namespaces; - - /* fallback to MAIL */ - mail = getenv("MAIL"); - if (mail == NULL) { - /* support also maildir-specific environment */ - mail = getenv("MAILDIR"); - if (mail != NULL) - mail = t_strconcat("maildir:", mail, NULL); - } - - ns = p_new(pool, struct namespace, 1); - ns->type = NAMESPACE_PRIVATE; - ns->inbox = TRUE; - ns->subscriptions = TRUE; - ns->prefix = ""; - - flags |= MAIL_STORAGE_FLAG_HAS_INBOX; - ns->storage = mail_storage_create(NULL, mail, user, flags, lock_method); - if (ns->storage == NULL) { - if (mail != NULL && *mail != '\0') - i_fatal("Failed to create storage with data: %s", mail); - else { - const char *home; - - home = getenv("HOME"); - if (home == NULL) home = "not set"; - - i_fatal("MAIL environment missing and " - "autodetection failed (home %s)", home); - } - } - - namespace_init_storage(ns); - return ns; -} - -void namespace_deinit(struct namespace *namespaces) -{ - while (namespaces != NULL) { - mail_storage_destroy(&namespaces->storage); - namespaces = namespaces->next; - } -} - -const char *namespace_fix_sep(struct namespace *ns, const char *name) -{ - char *ret, *p; - - if (ns->sep == ns->real_sep) - return name; - - ret = p_strdup(unsafe_data_stack_pool, name); - for (p = ret; *p != '\0'; p++) { - if (*p == ns->sep) - *p = ns->real_sep; - } - return ret; -} - -static struct namespace * -namespace_find_int(struct namespace *namespaces, const char **mailbox, - int show_hidden) -{ -#define CHECK_VISIBILITY(ns, show_hidden) \ - ((!(ns)->hidden) || (show_hidden)) - struct namespace *ns = namespaces; - const char *box = *mailbox; - struct namespace *best = NULL; - size_t best_len = 0; - bool inbox; - - inbox = strncasecmp(box, "INBOX", 5) == 0; - if (inbox && box[5] == '\0') { - /* find the INBOX namespace */ - *mailbox = "INBOX"; - while (ns != NULL) { - if (ns->inbox && CHECK_VISIBILITY(ns, show_hidden)) - return ns; - if (*ns->prefix == '\0') - best = ns; - ns = ns->next; - } - return best; - } - - for (; ns != NULL; ns = ns->next) { - if (ns->prefix_len >= best_len && - (strncmp(ns->prefix, box, ns->prefix_len) == 0 || - (inbox && strncmp(ns->prefix, "INBOX", 5) == 0 && - strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) && - CHECK_VISIBILITY(ns, show_hidden)) { - best = ns; - best_len = ns->prefix_len; - } - } - - if (best != NULL) { - if (best_len > 0) - *mailbox += best_len; - else if (inbox && (box[5] == best->sep || box[5] == '\0')) - *mailbox = t_strconcat("INBOX", box+5, NULL); - - *mailbox = namespace_fix_sep(best, *mailbox); - } - - return best; -} - -struct namespace * -namespace_find(struct namespace *namespaces, const char **mailbox) -{ - return namespace_find_int(namespaces, mailbox, TRUE); -} - -struct namespace * -namespace_find_visible(struct namespace *namespaces, const char **mailbox) -{ - return namespace_find_int(namespaces, mailbox, FALSE); -} - -struct namespace * -namespace_find_prefix(struct namespace *namespaces, const char *prefix) -{ - struct namespace *ns; - unsigned int len = strlen(prefix); - - for (ns = namespaces; ns != NULL; ns = ns->next) { - if (ns->prefix_len == len && strcmp(ns->prefix, prefix) == 0) - return ns; - } - return NULL; -}
--- a/src/imap/namespace.h Tue Apr 03 10:31:48 2007 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -#ifndef __NAMESPACE_H -#define __NAMESPACE_H - -enum namespace_type { - NAMESPACE_PRIVATE, - NAMESPACE_SHARED, - NAMESPACE_PUBLIC -}; - -struct namespace { - struct namespace *next; - - enum namespace_type type; - char sep, real_sep, sep_str[3]; - - const char *prefix; - size_t prefix_len; - - bool inbox, hidden, subscriptions; - struct mail_storage *storage; -}; - -struct namespace *namespace_init(pool_t pool, const char *user); -void namespace_deinit(struct namespace *namespaces); - -const char *namespace_fix_sep(struct namespace *ns, const char *name); - -struct namespace * -namespace_find(struct namespace *namespaces, const char **mailbox); -struct namespace * -namespace_find_visible(struct namespace *namespaces, const char **mailbox); -struct namespace * -namespace_find_prefix(struct namespace *namespaces, const char *prefix); - -#endif
--- a/src/lib-storage/Makefile.am Tue Apr 03 10:31:48 2007 +0300 +++ b/src/lib-storage/Makefile.am Tue Apr 03 11:34:27 2007 +0300 @@ -11,6 +11,7 @@ libstorage_a_SOURCES = \ mail.c \ mail-copy.c \ + mail-namespace.c \ mail-search.c \ mail-storage.c \ mailbox-list.c \ @@ -18,6 +19,7 @@ headers = \ mail-copy.h \ + mail-namespace.h \ mail-search.h \ mail-storage.h \ mail-storage-private.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mail-namespace.c Tue Apr 03 11:34:27 2007 +0300 @@ -0,0 +1,273 @@ +/* Copyright (C) 2005-2007 Timo Sirainen */ + +#include "lib.h" +#include "file-lock.h" +#include "mail-storage.h" +#include "mail-namespace.h" + +#include <stdlib.h> + +static void namespace_init_storage(struct mail_namespace *ns) +{ + ns->prefix_len = strlen(ns->prefix); + ns->real_sep = mail_storage_get_hierarchy_sep(ns->storage); + + if (ns->sep == '\0') + ns->sep = ns->real_sep; + + if (ns->sep == '"' || ns->sep == '\\') { + ns->sep_str[0] = '\\'; + ns->sep_str[1] = ns->sep; + } else { + ns->sep_str[0] = ns->sep; + } +} + +static struct mail_namespace * +namespace_add_env(pool_t pool, const char *data, unsigned int num, + const char *user, enum mail_storage_flags flags, + enum file_lock_method lock_method) +{ + struct mail_namespace *ns; + const char *sep, *type, *prefix; + bool inbox, hidden, subscriptions; + + ns = p_new(pool, struct mail_namespace, 1); + + sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num)); + type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num)); + prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num)); + inbox = getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL; + hidden = getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL; + subscriptions = getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS", + num)) != NULL; + + if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0) + ns->type = NAMESPACE_PRIVATE; + else if (strncmp(type, "shared", 6) == 0) + ns->type = NAMESPACE_SHARED; + else if (strncmp(type, "public", 6) == 0) + ns->type = NAMESPACE_PUBLIC; + else { + i_error("Unknown namespace type: %s", type); + return NULL; + } + + if (ns->type != NAMESPACE_PRIVATE) + flags |= MAIL_STORAGE_FLAG_SHARED_NAMESPACE; + if (ns->inbox) + flags |= MAIL_STORAGE_FLAG_HAS_INBOX; + + 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; + if (mail_storage_create(ns, NULL, data, user, flags, lock_method) < 0) { + i_error("Failed to create storage for '%s' with data: %s", + ns->prefix, data); + return NULL; + } + + if (sep != NULL) + ns->sep = *sep; + namespace_init_storage(ns); + return ns; +} + +int mail_namespaces_init(pool_t pool, const char *user, + struct mail_namespace **namespaces_r) +{ + struct mail_namespace *namespaces, *ns, **ns_p; + enum mail_storage_flags flags; + enum file_lock_method lock_method; + const char *mail, *data; + unsigned int i; + + mail_storage_parse_env(&flags, &lock_method); + namespaces = NULL; ns_p = &namespaces; + + /* first try NAMESPACE_* environments */ + for (i = 1; ; i++) { + t_push(); + data = getenv(t_strdup_printf("NAMESPACE_%u", i)); + t_pop(); + + if (data == NULL) + break; + + t_push(); + *ns_p = namespace_add_env(pool, data, i, user, flags, + lock_method); + t_pop(); + + if (*ns_p != NULL) + return -1; + + ns_p = &(*ns_p)->next; + } + + if (namespaces != NULL) { + *namespaces_r = namespaces; + return 0; + } + + /* fallback to MAIL */ + mail = getenv("MAIL"); + if (mail == NULL) { + /* support also maildir-specific environment */ + mail = getenv("MAILDIR"); + if (mail != NULL) + mail = t_strconcat("maildir:", mail, NULL); + } + + ns = p_new(pool, struct mail_namespace, 1); + ns->type = NAMESPACE_PRIVATE; + ns->inbox = TRUE; + ns->subscriptions = TRUE; + ns->prefix = ""; + + flags |= MAIL_STORAGE_FLAG_HAS_INBOX; + if (mail_storage_create(ns, NULL, mail, user, flags, lock_method) < 0) { + if (mail != NULL && *mail != '\0') + i_error("Failed to create storage with data: %s", mail); + else { + const char *home; + + home = getenv("HOME"); + if (home == NULL) home = "not set"; + + i_error("MAIL environment missing and " + "autodetection failed (home %s)", home); + } + return -1; + } + + namespace_init_storage(ns); + *namespaces_r = ns; + return 0; +} + +struct mail_namespace *mail_namespaces_init_empty(pool_t pool) +{ + struct mail_namespace *ns; + + ns = p_new(pool, struct mail_namespace, 1); + ns->prefix = ""; + return ns; +} + +void mail_namespaces_deinit(struct mail_namespace **_namespaces) +{ + struct mail_namespace *namespaces = *_namespaces; + + *_namespaces = NULL; + while (namespaces != NULL) { + if (namespaces->storage != NULL) + mail_storage_destroy(&namespaces->storage); + namespaces = namespaces->next; + } +} + +const char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name) +{ + char *ret, *p; + + if (ns->sep == ns->real_sep) + return name; + + ret = p_strdup(unsafe_data_stack_pool, name); + for (p = ret; *p != '\0'; p++) { + if (*p == ns->sep) + *p = ns->real_sep; + } + return ret; +} + +static struct mail_namespace * +mail_namespace_find_int(struct mail_namespace *namespaces, const char **mailbox, + bool show_hidden) +{ +#define CHECK_VISIBILITY(ns, show_hidden) \ + ((!(ns)->hidden) || (show_hidden)) + struct mail_namespace *ns = namespaces; + const char *box = *mailbox; + struct mail_namespace *best = NULL; + size_t best_len = 0; + bool inbox; + + inbox = strncasecmp(box, "INBOX", 5) == 0; + if (inbox && box[5] == '\0') { + /* find the INBOX namespace */ + *mailbox = "INBOX"; + while (ns != NULL) { + if (ns->inbox && CHECK_VISIBILITY(ns, show_hidden)) + return ns; + if (*ns->prefix == '\0') + best = ns; + ns = ns->next; + } + return best; + } + + for (; ns != NULL; ns = ns->next) { + if (ns->prefix_len >= best_len && + (strncmp(ns->prefix, box, ns->prefix_len) == 0 || + (inbox && strncmp(ns->prefix, "INBOX", 5) == 0 && + strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) && + CHECK_VISIBILITY(ns, show_hidden)) { + best = ns; + best_len = ns->prefix_len; + } + } + + if (best != NULL) { + if (best_len > 0) + *mailbox += best_len; + else if (inbox && (box[5] == best->sep || box[5] == '\0')) + *mailbox = t_strconcat("INBOX", box+5, NULL); + + *mailbox = mail_namespace_fix_sep(best, *mailbox); + } + + return best; +} + +struct mail_namespace * +mail_namespace_find(struct mail_namespace *namespaces, const char **mailbox) +{ + return mail_namespace_find_int(namespaces, mailbox, TRUE); +} + +struct mail_namespace * +mail_namespace_find_visible(struct mail_namespace *namespaces, + const char **mailbox) +{ + return mail_namespace_find_int(namespaces, mailbox, FALSE); +} + +struct mail_namespace * +mail_namespace_find_prefix(struct mail_namespace *namespaces, + const char *prefix) +{ + struct mail_namespace *ns; + unsigned int len = strlen(prefix); + + for (ns = namespaces; ns != NULL; ns = ns->next) { + if (ns->prefix_len == len && + strcmp(ns->prefix, prefix) == 0) + return ns; + } + return NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mail-namespace.h Tue Apr 03 11:34:27 2007 +0300 @@ -0,0 +1,39 @@ +#ifndef __MAIL_NAMESPACE_H +#define __MAIL_NAMESPACE_H + +enum namespace_type { + NAMESPACE_PRIVATE, + NAMESPACE_SHARED, + NAMESPACE_PUBLIC +}; + +struct mail_namespace { + struct mail_namespace *next; + + enum namespace_type type; + char sep, real_sep, sep_str[3]; + + const char *prefix; + size_t prefix_len; + + bool inbox, hidden, subscriptions; + struct mail_storage *storage; +}; + +int mail_namespaces_init(pool_t pool, const char *user, + struct mail_namespace **namespaces_r); +struct mail_namespace *mail_namespaces_init_empty(pool_t pool); +void mail_namespaces_deinit(struct mail_namespace **namespaces); + +const char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name); + +struct mail_namespace * +mail_namespace_find(struct mail_namespace *namespaces, const char **mailbox); +struct mail_namespace * +mail_namespace_find_visible(struct mail_namespace *namespaces, + const char **mailbox); +struct mail_namespace * +mail_namespace_find_prefix(struct mail_namespace *namespaces, + const char *prefix); + +#endif
--- a/src/lib-storage/mail-storage-private.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/lib-storage/mail-storage-private.h Tue Apr 03 11:34:27 2007 +0300 @@ -53,6 +53,7 @@ pool_t pool; char *error; + struct mail_namespace *ns; struct mailbox_list *list; const char *user; /* name of user accessing the storage */
--- a/src/lib-storage/mail-storage.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/lib-storage/mail-storage.c Tue Apr 03 11:34:27 2007 +0300 @@ -7,6 +7,7 @@ #include "mail-index-private.h" #include "mailbox-list-private.h" #include "mail-storage-private.h" +#include "mail-namespace.h" #include "index/index-storage.h" #include <stdlib.h> @@ -149,10 +150,10 @@ } } -struct mail_storage * -mail_storage_create(const char *driver, const char *data, const char *user, - enum mail_storage_flags flags, - enum file_lock_method lock_method) +int mail_storage_create(struct mail_namespace *ns, const char *driver, + const char *data, const char *user, + enum mail_storage_flags flags, + enum file_lock_method lock_method) { struct mail_storage *storage_class, *storage; struct mail_storage *const *classes; @@ -173,14 +174,14 @@ "don't know what to do with it: %s " "(try prefixing it with mbox: or maildir:)", data); - return NULL; + return -1; } classes = &storage_class; count = 1; } else { storage_class = mail_storage_find(driver); if (storage_class == NULL) - return NULL; + return -1; classes = &storage_class; count = 1; } @@ -190,6 +191,7 @@ storage->flags = flags; storage->lock_method = lock_method; storage->user = p_strdup(storage->pool, user); + storage->ns = ns; storage->callbacks = p_new(storage->pool, struct mail_storage_callbacks, 1); @@ -202,11 +204,13 @@ pool_unref(storage->pool); } if (i == count) - return NULL; + return -1; if (hook_mail_storage_created != NULL) hook_mail_storage_created(storage); - return storage; + + ns->storage = storage; + return 0; } void mail_storage_destroy(struct mail_storage **_storage) @@ -319,6 +323,11 @@ return storage->list; } +struct mail_namespace *mail_storage_get_namespace(struct mail_storage *storage) +{ + return storage->ns; +} + void mail_storage_set_callbacks(struct mail_storage *storage, struct mail_storage_callbacks *callbacks, void *context)
--- a/src/lib-storage/mail-storage.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/lib-storage/mail-storage.h Tue Apr 03 11:34:27 2007 +0300 @@ -136,6 +136,7 @@ MAILBOX_SYNC_TYPE_KEYWORDS = 0x04 }; +struct mail_namespace; struct mail_storage; struct mail_search_arg; struct mail_keywords; @@ -204,15 +205,16 @@ /* Create a new instance of registered mail storage class with given storage-specific data. If driver is NULL, it's tried to be autodetected from data. If data is NULL, it uses the first storage that exists. - May return NULL if anything fails. */ -struct mail_storage * -mail_storage_create(const char *driver, const char *data, const char *user, - enum mail_storage_flags flags, - enum file_lock_method lock_method); + The storage is put into ns->storage. */ +int mail_storage_create(struct mail_namespace *ns, const char *driver, + const char *data, const char *user, + enum mail_storage_flags flags, + enum file_lock_method lock_method); void mail_storage_destroy(struct mail_storage **storage); char mail_storage_get_hierarchy_sep(struct mail_storage *storage); struct mailbox_list *mail_storage_get_list(struct mail_storage *storage); +struct mail_namespace *mail_storage_get_namespace(struct mail_storage *storage); void mail_storage_set_list_error(struct mail_storage *storage); /* Set storage callback functions to use. */
--- a/src/plugins/convert/convert-storage.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/plugins/convert/convert-storage.c Tue Apr 03 11:34:27 2007 +0300 @@ -1,8 +1,10 @@ /* Copyright (C) 2006 Timo Sirainen */ #include "lib.h" +#include "file-lock.h" #include "file-dotlock.h" -#include "index-storage.h" +#include "mail-storage-private.h" +#include "mail-namespace.h" #include "mail-search.h" #include "convert-storage.h" @@ -246,25 +248,25 @@ const char *source_data, const char *dest_data, bool skip_broken_mailboxes) { - struct mail_storage *source_storage, *dest_storage; + struct mail_namespace *source_ns, *dest_ns; struct dotlock *dotlock; enum mail_storage_flags flags; enum file_lock_method lock_method; const char *path; int ret; + source_ns = mail_namespaces_init_empty(pool_datastack_create()); mail_storage_parse_env(&flags, &lock_method); flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE | MAIL_STORAGE_FLAG_HAS_INBOX; - source_storage = mail_storage_create(NULL, source_data, user, - flags, lock_method); - if (source_storage == NULL) { + if (mail_storage_create(source_ns, NULL, source_data, user, + flags, lock_method) < 0) { /* No need for conversion. */ return 0; } path = t_strconcat(home_dir, "/"CONVERT_LOCK_FILENAME, NULL); dotlock_settings.use_excl_lock = - (source_storage->flags & + (source_ns->storage->flags & MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0; ret = file_dotlock_create(&dotlock_settings, path, 0, &dotlock); if (ret <= 0) { @@ -275,27 +277,26 @@ /* just in case if another process just had converted the mailbox, reopen the source storage */ - mail_storage_destroy(&source_storage); - source_storage = mail_storage_create(NULL, source_data, user, - flags, lock_method); - if (source_storage == NULL) { + mail_storage_destroy(&source_ns->storage); + if (mail_storage_create(source_ns, NULL, source_data, user, + flags, lock_method) < 0) { /* No need for conversion anymore. */ file_dotlock_delete(&dotlock); return 0; } - dest_storage = mail_storage_create(NULL, dest_data, user, - flags, lock_method); - if (dest_storage == NULL) { + dest_ns = mail_namespaces_init_empty(pool_datastack_create()); + if (mail_storage_create(dest_ns, NULL, dest_data, user, + flags, lock_method) < 0) { i_error("Mailbox conversion: Failed to create destination " "storage with data: %s", dest_data); ret = -1; } else { - ret = mailbox_list_copy(source_storage, dest_storage, dotlock, - skip_broken_mailboxes); + ret = mailbox_list_copy(source_ns->storage, dest_ns->storage, + dotlock, skip_broken_mailboxes); if (ret == 0) { - ret = mailbox_list_copy_subscriptions(source_storage, - dest_storage); + ret = mailbox_list_copy_subscriptions( + source_ns->storage, dest_ns->storage); } } @@ -305,7 +306,7 @@ const char *src, *dest; bool is_file; - src = mail_storage_get_mailbox_path(source_storage, "", + src = mail_storage_get_mailbox_path(source_ns->storage, "", &is_file); if (src != NULL) { dest = t_strconcat(src, "-converted", NULL); @@ -319,8 +320,7 @@ } file_dotlock_delete(&dotlock); - if (dest_storage != NULL) - mail_storage_destroy(&dest_storage); - mail_storage_destroy(&source_storage); + mail_namespaces_deinit(&dest_ns); + mail_namespaces_deinit(&source_ns); return ret; }
--- a/src/plugins/expire/expire-tool.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/plugins/expire/expire-tool.c Tue Apr 03 11:34:27 2007 +0300 @@ -8,6 +8,7 @@ #include "dict-client.h" #include "mail-search.h" #include "mail-storage.h" +#include "mail-namespace.h" #include "auth-client.h" #include "expire-env.h" @@ -23,14 +24,12 @@ struct auth_connection *auth_conn; char *user; - struct mail_storage *storage; + pool_t namespace_pool; + struct mail_namespace *ns; }; static int user_init(struct expire_context *ctx, const char *user) { - enum mail_storage_flags flags; - enum file_lock_method lock_method; - const char *mail_env; int ret; if ((ret = auth_client_put_user_env(ctx->auth_conn, user)) <= 0) { @@ -41,22 +40,16 @@ return 0; } - mail_env = getenv("MAIL"); - mail_storage_parse_env(&flags, &lock_method); - ctx->storage = mail_storage_create(NULL, mail_env, user, - flags, lock_method); - if (ctx->storage == NULL) { - i_error("Failed to create storage for '%s' with mail '%s'", - user, mail_env == NULL ? "(null)" : mail_env); + if (mail_namespaces_init(ctx->namespace_pool, user, &ctx->ns) < 0) return -1; - } return 1; } static void user_deinit(struct expire_context *ctx) { - mail_storage_destroy(&ctx->storage); + mail_namespaces_deinit(&ctx->ns); i_free_and_null(ctx->user); + p_clear(ctx->namespace_pool); } static int @@ -64,6 +57,7 @@ const char *mailbox, time_t expire_secs, time_t *oldest_r) { + struct mail_namespace *ns; struct mailbox *box; struct mail_search_context *search_ctx; struct mailbox_transaction_context *t; @@ -86,7 +80,11 @@ search_arg.type = SEARCH_ALL; search_arg.next = NULL; - box = mailbox_open(ctx->storage, mailbox, NULL, 0); + ns = mail_namespace_find(ctx->ns, &mailbox); + if (ns == NULL) + return -1; + + box = mailbox_open(ns->storage, mailbox, NULL, 0); t = mailbox_transaction_begin(box, 0); search_ctx = mailbox_search_init(t, NULL, &search_arg, NULL); mail = mail_alloc(t, 0, NULL); @@ -150,6 +148,7 @@ memset(&ctx, 0, sizeof(ctx)); ctx.auth_conn = auth_connection_init(auth_socket); + ctx.namespace_pool = pool_alloconly_create("namespaces", 1024); env = expire_env_init(getenv("EXPIRE")); dict = dict_init(getenv("EXPIRE_DICT"), DICT_DATA_TYPE_UINT32, ""); trans = dict_transaction_begin(dict);
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c Tue Apr 03 11:34:27 2007 +0300 @@ -7,7 +7,7 @@ #include "seq-range-array.h" #include "maildir-storage.h" #include "client.h" -#include "namespace.h" +#include "mail-namespace.h" #include "lazy-expunge-plugin.h" #include <stdio.h> @@ -63,7 +63,7 @@ static MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mailbox_list_module, &mailbox_list_module_register); -static struct namespace *lazy_namespaces[LAZY_NAMESPACE_COUNT]; +static struct mail_namespace *lazy_namespaces[LAZY_NAMESPACE_COUNT]; static struct mailbox * mailbox_open_or_create(struct mail_storage *storage, const char *name) @@ -515,7 +515,7 @@ i_fatal("lazy_expunge: Missing namespace #%d", i + 1); lazy_namespaces[i] = - namespace_find_prefix((*client)->namespaces, name); + mail_namespace_find_prefix((*client)->namespaces, name); if (lazy_namespaces[i] == NULL) i_fatal("lazy_expunge: Unknown namespace: '%s'", name); if (strcmp(lazy_namespaces[i]->storage->name, "maildir") != 0) {
--- a/src/pop3/client.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/pop3/client.c Tue Apr 03 11:34:27 2007 +0300 @@ -11,6 +11,7 @@ #include "mail-storage.h" #include "commands.h" #include "mail-search.h" +#include "mail-namespace.h" #include <stdlib.h> #include <unistd.h> @@ -124,8 +125,10 @@ } struct client *client_create(int fd_in, int fd_out, - struct mail_storage *storage) + struct mail_namespace *namespaces) { + struct mail_storage *storage; + const char *inbox; struct client *client; enum mailbox_open_flags flags; const char *errmsg; @@ -146,8 +149,18 @@ client->io = io_add(fd_in, IO_READ, client_input, client); client->last_input = ioloop_time; - client->storage = storage; + + client->namespaces = namespaces; + inbox = "INBOX"; + client->inbox_ns = mail_namespace_find(namespaces, &inbox); + if (client->inbox_ns == NULL) { + client_send_line(client, "-ERR No INBOX namespace for user."); + client_destroy(client, "No INBOX namespace for user."); + return NULL; + } + + storage = client->inbox_ns->storage; mail_storage_set_callbacks(storage, &mail_storage_callbacks, client); flags = 0; @@ -237,7 +250,7 @@ } if (client->mailbox != NULL) mailbox_close(&client->mailbox); - mail_storage_destroy(&client->storage); + mail_namespaces_deinit(&client->namespaces); i_free(client->message_sizes); i_free(client->deleted_bitmask); @@ -333,7 +346,7 @@ return; } - error = mail_storage_get_last_error(client->storage, &syntax, + error = mail_storage_get_last_error(client->inbox_ns->storage, &syntax, &temporary_error); client_send_line(client, "-ERR %s", error != NULL ? error : "BUG: Unknown error");
--- a/src/pop3/client.h Tue Apr 03 10:31:48 2007 +0300 +++ b/src/pop3/client.h Tue Apr 03 11:34:27 2007 +0300 @@ -15,7 +15,7 @@ command_func_t *cmd; void *cmd_context; - struct mail_storage *storage; + struct mail_namespace *namespaces, *inbox_ns; struct mailbox *mailbox; struct mailbox_transaction_context *trans; @@ -49,7 +49,7 @@ /* Create new client with specified input/output handles. socket specifies if the handle is a socket. */ struct client *client_create(int fd_in, int fd_out, - struct mail_storage *storage); + struct mail_namespace *namespaces); void client_destroy(struct client *client, const char *reason); /* Disconnect client connection */
--- a/src/pop3/main.c Tue Apr 03 10:31:48 2007 +0300 +++ b/src/pop3/main.c Tue Apr 03 11:34:27 2007 +0300 @@ -13,6 +13,7 @@ #include "var-expand.h" #include "dict-client.h" #include "mail-storage.h" +#include "mail-namespace.h" #include <stdio.h> #include <stdlib.h> @@ -38,6 +39,7 @@ void (*hook_client_created)(struct client **client) = NULL; static struct module *modules = NULL; +static pool_t namespace_pool; static char log_prefix[128]; /* syslog() needs this to be permanent */ static struct io *log_io = NULL; @@ -180,10 +182,7 @@ static int main_init(void) { - enum mail_storage_flags flags; - enum file_lock_method lock_method; - struct mail_storage *storage; - const char *mail; + struct mail_namespace *ns; lib_signals_init(); lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); @@ -213,14 +212,6 @@ module_dir_init(modules); - mail = getenv("MAIL"); - if (mail == NULL) { - /* support also maildir-specific environment */ - mail = getenv("MAILDIR"); - if (mail != NULL) - mail = t_strconcat("maildir:", mail, NULL); - } - parse_workarounds(); enable_last_command = getenv("POP3_ENABLE_LAST") != NULL; no_flag_updates = getenv("POP3_NO_FLAG_UPDATES") != NULL; @@ -238,25 +229,10 @@ i_fatal("pop3_uidl_format setting doesn't contain any " "%% variables."); - mail_storage_parse_env(&flags, &lock_method); - storage = mail_storage_create(NULL, mail, getenv("USER"), - flags, lock_method); - if (storage == NULL) { - /* failed */ - if (mail != NULL && *mail != '\0') - i_fatal("Failed to create storage with data: %s", mail); - else { - const char *home; - - home = getenv("HOME"); - if (home == NULL) home = "not set"; - - i_fatal("MAIL environment missing and " - "autodetection failed (home %s)", home); - } - } - - return client_create(0, 1, storage) != NULL; + namespace_pool = pool_alloconly_create("namespaces", 1024); + if (mail_namespaces_init(namespace_pool, getenv("USER"), &ns) < 0) + exit(FATAL_DEFAULT); + return client_create(0, 1, ns) != NULL; } static void main_deinit(void)