# HG changeset patch # User Timo Sirainen # Date 1090531200 -10800 # Node ID 1371d41c375f08c8e8b670bbf9ff1330a1c6124b # Parent b65456de1b494dc7f90c4d8622e782aece9fd18a Moved namespace and hierarchy separator handling to imap-specific code. LIST now shows non-hidden namespaces in the LIST reply. diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-append.c --- a/src/imap/cmd-append.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-append.c Fri Jul 23 00:20:00 2004 +0300 @@ -69,7 +69,7 @@ if (!client_verify_mailbox_name(client, mailbox, TRUE, FALSE)) return TRUE; - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-copy.c --- a/src/imap/cmd-copy.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-copy.c Fri Jul 23 00:20:00 2004 +0300 @@ -75,7 +75,7 @@ if (search_arg == NULL) return TRUE; - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-create.c --- a/src/imap/cmd-create.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-create.c Fri Jul 23 00:20:00 2004 +0300 @@ -14,7 +14,7 @@ if (!client_read_string_args(client, 1, &mailbox)) return FALSE; - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-delete.c --- a/src/imap/cmd-delete.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-delete.c Fri Jul 23 00:20:00 2004 +0300 @@ -28,7 +28,7 @@ if (mailbox_close(mailbox) < 0) client_send_untagged_storage_error(client, storage); } else { - storage = client_find_storage(client, name); + storage = client_find_storage(client, &name); if (storage == NULL) return TRUE; } diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-list.c --- a/src/imap/cmd-list.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-list.c Fri Jul 23 00:20:00 2004 +0300 @@ -48,34 +48,6 @@ return *str == '\0' ? "" : str+1; } -static int mailbox_list(struct client *client, struct mail_storage *storage, - const char *mask, const char *sep, const char *reply, - enum mailbox_list_flags list_flags) -{ - struct mailbox_list_context *ctx; - struct mailbox_list *list; - string_t *str; - - ctx = mail_storage_mailbox_list_init(storage, mask, list_flags); - if (ctx == NULL) - return FALSE; - - str = t_str_new(256); - while ((list = mail_storage_mailbox_list_next(ctx)) != NULL) { - str_truncate(str, 0); - str_printfa(str, "* %s (%s) \"%s\" ", reply, - mailbox_flags2str(list->flags, list_flags), - sep); - if (strcasecmp(list->name, "INBOX") == 0) - str_append(str, "INBOX"); - else - imap_quote_append_string(str, list->name, FALSE); - client_send_line(client, str_c(str)); - } - - return mail_storage_mailbox_list_deinit(ctx); -} - static int parse_list_flags(struct client *client, struct imap_arg *args, enum mailbox_list_flags *list_flags) { @@ -104,15 +76,204 @@ return TRUE; } +static int +list_namespace_mailboxes(struct client *client, struct imap_match_glob *glob, + struct namespace *ns, struct mailbox_list_context *ctx, + enum mailbox_list_flags list_flags) +{ + struct mailbox_list *list; + const char *name; + string_t *str, *name_str; + int inbox_found = FALSE; + + t_push(); + str = t_str_new(256); + name_str = t_str_new(256); + while ((list = mail_storage_mailbox_list_next(ctx)) != NULL) { + str_truncate(name_str, 0); + str_append(name_str, ns->prefix); + str_append(name_str, list->name); + + if (ns->sep != ns->real_sep) { + char *p = str_c_modifyable(name_str); + for (; *p != '\0'; p++) { + if (*p == ns->real_sep) + *p = ns->sep; + } + } + name = str_c(name_str); + + if (*ns->prefix != '\0') { + /* With masks containing '*' we do the checks here + so prefix is included in matching */ + if (glob != NULL && + imap_match(glob, name) != IMAP_MATCH_YES) + continue; + } else if (strcasecmp(list->name, "INBOX") == 0) { + if (!ns->inbox) + continue; + + name = "INBOX"; + inbox_found = TRUE; + } + + str_truncate(str, 0); + str_printfa(str, "* LIST (%s) \"%s\" ", + mailbox_flags2str(list->flags, list_flags), + ns->sep_str); + imap_quote_append_string(str, name, FALSE); + client_send_line(client, str_c(str)); + } + t_pop(); + + if (!inbox_found && ns->inbox) { + /* INBOX always exists */ + str_printfa(str, "* LIST () \"%s\" \"INBOX\"", ns->sep_str); + client_send_line(client, str_c(str)); + } + + return mail_storage_mailbox_list_deinit(ctx); +} + +static void skip_prefix(const char **prefix, const char **mask, int inbox) +{ + size_t mask_len, prefix_len, len; + + prefix_len = strlen(*prefix); + mask_len = strlen(*mask); + len = I_MIN(prefix_len, mask_len); + + if (strncmp(*prefix, *mask, len) == 0 || + (inbox && len >= 6 && + strncasecmp(*prefix, *mask, 6) == 0)) { + *prefix += len; + *mask += len; + } +} + +static int list_mailboxes(struct client *client, + const char *ref, const char *mask, + enum mailbox_list_flags list_flags) +{ + struct namespace *ns; + struct mailbox_list_context *ctx; + struct imap_match_glob *glob; + enum imap_match_result match; + const char *cur_prefix, *cur_ref, *cur_mask; + size_t len; + int inbox; + + inbox = strncasecmp(ref, "INBOX", 5) == 0 || + (*ref == '\0' && strncasecmp(mask, "INBOX", 5) == 0); + + for (ns = client->namespaces; ns != NULL; ns = ns->next) { + t_push(); + cur_prefix = ns->prefix; + cur_ref = ref; + cur_mask = mask; + if (*ref != '\0') { + skip_prefix(&cur_prefix, &cur_ref, inbox); + + if (*cur_ref != '\0' && *cur_prefix != '\0') { + /* reference parameter didn't match with + namespace prefix. skip this. */ + t_pop(); + continue; + } + } + + if (*cur_ref == '\0' && *cur_prefix != '\0') { + skip_prefix(&cur_prefix, &cur_mask, + inbox && cur_ref == ref); + } + + glob = imap_match_init(pool_datastack_create(), mask, + inbox && cur_ref == ref, ns->sep); + + if (*cur_ref != '\0' || *cur_prefix == '\0') + match = IMAP_MATCH_CHILDREN; + else { + len = strlen(cur_prefix); + if (cur_prefix[len-1] == ns->sep) + cur_prefix = t_strndup(cur_prefix, len-1); + match = ns->hidden ? IMAP_MATCH_NO : + imap_match(glob, cur_prefix); + + if (match == IMAP_MATCH_YES) { + /* The prefix itself matches */ + string_t *str = t_str_new(128); + str_printfa(str, "* LIST (%s) \"%s\" ", + mailbox_flags2str(MAILBOX_PLACEHOLDER, + list_flags), + ns->sep_str); + len = strlen(ns->prefix); + imap_quote_append_string(str, + t_strndup(ns->prefix, len-1), FALSE); + client_send_line(client, str_c(str)); + } + } + + if (match >= 0) { + unsigned int count = 0; + if (*cur_prefix != '\0') { + /* we'll have to fix mask */ + for (; *cur_prefix != '\0'; cur_prefix++) { + if (*cur_prefix == ns->sep) + count++; + } + if (count == 0) + count = 1; + + while (count > 0) { + if (*cur_ref != '\0') { + while (*cur_ref != '\0' && + *cur_ref++ != ns->sep) + ; + } else { + while (*cur_mask != '\0' && + *cur_mask != '*' && + *cur_mask != ns->sep) + cur_mask++; + if (*cur_mask == '*') { + cur_mask = "*"; + break; + } + if (*cur_mask == '\0') + break; + cur_mask++; + } + count--; + } + } + + if (*cur_mask != '*' || strcmp(mask, "*") == 0) + glob = NULL; + + cur_ref = namespace_fix_sep(ns, cur_ref); + cur_mask = namespace_fix_sep(ns, cur_mask); + + ctx = mail_storage_mailbox_list_init(ns->storage, + cur_ref, cur_mask, + list_flags); + if (list_namespace_mailboxes(client, glob, ns, ctx, + list_flags) < 0) { + client_send_storage_error(client, ns->storage); + t_pop(); + return -1; + } + } + t_pop(); + } + + return 0; +} + int _cmd_list_full(struct client *client, int lsub) { struct namespace *ns; - struct mail_storage *storage; struct imap_arg *args; enum mailbox_list_flags list_flags; const char *ref, *mask; - char sep_chr, sep[3]; - int failed; /* [()] */ if (!client_read_args(client, 0, 0, &args)) @@ -145,56 +306,27 @@ return TRUE; } - /* FIXME: really needs some work.. */ - ns = namespace_find(client->namespaces, *ref != '\0' ? ref : mask); - if (ns != NULL) - storage = ns->storage; - else - storage = client->namespaces->storage; - - sep_chr = mail_storage_get_hierarchy_sep(storage); - if (sep_chr == '"' || sep_chr == '\\') { - sep[0] = '\\'; - sep[1] = sep_chr; - sep[2] = '\0'; - } else { - sep[0] = sep_chr; - sep[1] = '\0'; - } - if (*mask == '\0' && !lsub) { /* special request to return the hierarchy delimiter */ - client_send_line(client, t_strconcat( - "* LIST (\\Noselect) \"", sep, "\" \"\"", NULL)); - failed = FALSE; - } else { - if (*ref != '\0') { - /* join reference + mask */ - if (*mask == sep_chr && - ref[strlen(ref)-1] == sep_chr) { - /* LIST A. .B -> A.B */ - mask++; - } - if (*mask != sep_chr && - ref[strlen(ref)-1] != sep_chr) { - /* LIST A B -> A.B */ - mask = t_strconcat(ref, sep, mask, NULL); - } else { - mask = t_strconcat(ref, mask, NULL); - } + ns = namespace_find(client->namespaces, &ref); + if (ns == NULL) { + const char *empty = ""; + ns = namespace_find(client->namespaces, &empty); } - failed = mailbox_list(client, storage, mask, sep, - lsub ? "LSUB" : "LIST", list_flags) < 0; + if (ns != NULL) { + client_send_line(client, t_strconcat( + "* LIST (\\Noselect) \"", ns->sep_str, + "\" \"\"", NULL)); + } + } else { + if (list_mailboxes(client, ref, mask, list_flags) < 0) + return TRUE; } - if (failed) - client_send_storage_error(client, storage); - else { - client_send_tagline(client, lsub ? - "OK Lsub completed." : - "OK List completed."); - } + client_send_tagline(client, !lsub ? + "OK List completed." : + "OK Lsub completed."); return TRUE; } diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-namespace.c --- a/src/imap/cmd-namespace.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-namespace.c Fri Jul 23 00:20:00 2004 +0300 @@ -20,10 +20,7 @@ str_append_c(str, '('); imap_quote_append_string(str, ns->prefix, FALSE); str_append(str, " \""); - if (ns->hierarchy_sep == '"' || - ns->hierarchy_sep == '\\') - str_append_c(str, '\\'); - str_append_c(str, ns->hierarchy_sep); + str_append(str, ns->sep_str); str_append(str, "\")"); } diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-rename.c --- a/src/imap/cmd-rename.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-rename.c Fri Jul 23 00:20:00 2004 +0300 @@ -15,11 +15,11 @@ if (!client_verify_mailbox_name(client, newname, FALSE, TRUE)) return TRUE; - old_storage = client_find_storage(client, oldname); + old_storage = client_find_storage(client, &oldname); if (old_storage == NULL) return TRUE; - new_storage = client_find_storage(client, newname); + new_storage = client_find_storage(client, &newname); if (new_storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-select.c --- a/src/imap/cmd-select.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-select.c Fri Jul 23 00:20:00 2004 +0300 @@ -24,7 +24,7 @@ } } - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-status.c --- a/src/imap/cmd-status.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-status.c Fri Jul 23 00:20:00 2004 +0300 @@ -102,7 +102,7 @@ return TRUE; } - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return FALSE; diff -r b65456de1b49 -r 1371d41c375f src/imap/cmd-subscribe.c --- a/src/imap/cmd-subscribe.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/cmd-subscribe.c Fri Jul 23 00:20:00 2004 +0300 @@ -15,7 +15,7 @@ if (!client_verify_mailbox_name(client, mailbox, subscribe, FALSE)) return TRUE; - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return TRUE; diff -r b65456de1b49 -r 1371d41c375f src/imap/commands-util.c --- a/src/imap/commands-util.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/commands-util.c Fri Jul 23 00:20:00 2004 +0300 @@ -17,7 +17,7 @@ #define MAILBOX_MAX_NAME_LEN 512 struct mail_storage * -client_find_storage(struct client *client, const char *mailbox) +client_find_storage(struct client *client, const char **mailbox) { struct namespace *ns; @@ -37,7 +37,7 @@ const char *p; char sep; - storage = client_find_storage(client, mailbox); + storage = client_find_storage(client, &mailbox); if (storage == NULL) return FALSE; diff -r b65456de1b49 -r 1371d41c375f src/imap/commands-util.h --- a/src/imap/commands-util.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/commands-util.h Fri Jul 23 00:20:00 2004 +0300 @@ -11,7 +11,7 @@ /* Finds mail storage for given mailbox from namespaces. If not found, sends "Unknown namespace" error message to client. */ struct mail_storage * -client_find_storage(struct client *client, const char *mailbox); +client_find_storage(struct client *client, const char **mailbox); /* If should_exist is TRUE, this function returns TRUE if the mailbox exists. If it doesn't exist but would be a valid mailbox name, the diff -r b65456de1b49 -r 1371d41c375f src/imap/namespace.c --- a/src/imap/namespace.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/namespace.c Fri Jul 23 00:20:00 2004 +0300 @@ -6,13 +6,32 @@ #include +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; + } + + if (hook_mail_storage_created != NULL) + hook_mail_storage_created(&ns->storage); +} + static struct namespace * namespace_add_env(pool_t pool, const char *data, unsigned int num, const char *user) { struct namespace *ns; const char *sep, *type, *prefix; - int inbox, hidden; + int inbox, hidden, subscriptions; ns = p_new(pool, struct namespace, 1); @@ -21,6 +40,8 @@ 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; @@ -37,17 +58,16 @@ ns->prefix = p_strdup(pool, prefix); ns->inbox = inbox; ns->hidden = hidden; - ns->storage = mail_storage_create_with_data(data, user, ns->prefix, - sep != NULL ? *sep : '\0'); + ns->subscriptions = subscriptions; + ns->storage = mail_storage_create_with_data(data, user); if (ns->storage == NULL) { i_fatal("Failed to create storage for '%s' with data: %s", ns->prefix, data); } - if (hook_mail_storage_created != NULL) - hook_mail_storage_created(&ns->storage); - - ns->hierarchy_sep = mail_storage_get_hierarchy_sep(ns->storage); + if (sep != NULL) + ns->sep = *sep; + namespace_init_storage(ns); return ns; } @@ -88,7 +108,7 @@ } ns = p_new(pool, struct namespace, 1); - ns->storage = mail_storage_create_with_data(mail, user, NULL, '\0'); + ns->storage = mail_storage_create_with_data(mail, user); if (ns->storage == NULL) { if (mail != NULL && *mail != '\0') i_fatal("Failed to create storage with data: %s", mail); @@ -105,11 +125,9 @@ ns->type = NAMESPACE_PRIVATE; ns->inbox = TRUE; - ns->prefix = p_strdup(pool, ""); - ns->hierarchy_sep = mail_storage_get_hierarchy_sep(ns->storage); - if (hook_mail_storage_created != NULL) - hook_mail_storage_created(&ns->storage); - + ns->subscriptions = TRUE; + ns->prefix = ""; + namespace_init_storage(ns); return ns; } @@ -121,39 +139,61 @@ } } -struct namespace * -namespace_find(struct namespace *namespaces, const char *mailbox) +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; +} + +struct namespace * +namespace_find(struct namespace *namespaces, const char **mailbox) +{ + struct namespace *ns = namespaces; + const char *box = *mailbox; struct namespace *best = NULL; - size_t len, best_len = 0; + size_t best_len = 0; int inbox; - inbox = strncasecmp(mailbox, "INBOX", 5) == 0; - if (inbox && mailbox[5] == '\0') { + inbox = strncasecmp(box, "INBOX", 5) == 0; + if (inbox && box[5] == '\0') { /* find the INBOX namespace */ - while (namespaces != NULL) { - if (namespaces->inbox) - return namespaces; - if (namespaces->prefix == NULL) - best = namespaces; - namespaces = namespaces->next; + *mailbox = "INBOX"; + while (ns != NULL) { + if (ns->inbox) + return ns; + if (*ns->prefix == '\0') + best = ns; + ns = ns->next; } return best; } - while (namespaces != NULL) { - len = namespaces->prefix == NULL ? 0 : - strlen(namespaces->prefix); - if (len >= best_len && - (strncmp(namespaces->prefix, mailbox, len) == 0 || - (inbox && strncmp(namespaces->prefix, "INBOX", 5) == 0 && - mailbox[5] == namespaces->hierarchy_sep && - namespaces->prefix[5] == namespaces->hierarchy_sep && - strncmp(namespaces->prefix+6, mailbox+6, len-6) == 0))) { - best = namespaces; - best_len = len; + 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))) { + best = ns; + best_len = ns->prefix_len; } - namespaces = namespaces->next; + } + + 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; diff -r b65456de1b49 -r 1371d41c375f src/imap/namespace.h --- a/src/imap/namespace.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/imap/namespace.h Fri Jul 23 00:20:00 2004 +0300 @@ -11,16 +11,21 @@ struct namespace *next; enum namespace_type type; - char hierarchy_sep; + char sep, real_sep, sep_str[3]; + char *prefix; - int inbox, hidden; + size_t prefix_len; + + int 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); +namespace_find(struct namespace *namespaces, const char **mailbox); #endif diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/index-storage.c Fri Jul 23 00:20:00 2004 +0300 @@ -44,7 +44,6 @@ void index_storage_deinit(struct index_storage *storage) { - i_free(storage->storage.namespace); i_free(storage->storage.error); if (--index_storage_refcount > 0) diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/maildir/maildir-list.c --- a/src/lib-storage/index/maildir/maildir-list.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-list.c Fri Jul 23 00:20:00 2004 +0300 @@ -70,13 +70,6 @@ return FALSE; } - /* INBOX exists always */ - if (imap_match(glob, "INBOX") > 0 && !update_only) { - node = mailbox_tree_get(ctx->tree_ctx, "INBOX", NULL); - node->flags |= MAILBOX_FLAG_MATCHED | MAILBOX_NOCHILDREN; - node->flags &= ~(MAILBOX_PLACEHOLDER | MAILBOX_NONEXISTENT); - } - stat_dirs = getenv("MAILDIR_STAT_DIRS") != NULL; mailbox = t_str_new(PATH_MAX); @@ -139,9 +132,6 @@ match != IMAP_MATCH_PARENT) continue; - if (strcasecmp(fname, "INBOX") == 0) - continue; /* ignore inboxes */ - if (match == IMAP_MATCH_PARENT) { t_push(); while ((p = strrchr(mailbox_c, @@ -219,9 +209,8 @@ node = mailbox_tree_get(ctx->tree_ctx, name, NULL); node->flags = MAILBOX_FLAG_MATCHED; if ((ctx->flags & MAILBOX_LIST_FAST_FLAGS) == 0) { - if (strcasecmp(name, "INBOX") != 0) - node->flags |= MAILBOX_NONEXISTENT; - node->flags |= MAILBOX_NOCHILDREN; + node->flags |= MAILBOX_NONEXISTENT | + MAILBOX_NOCHILDREN; } break; case IMAP_MATCH_PARENT: @@ -249,7 +238,8 @@ struct mailbox_list_context * maildir_mailbox_list_init(struct mail_storage *storage, - const char *mask, enum mailbox_list_flags flags) + const char *ref, const char *mask, + enum mailbox_list_flags flags) { struct index_storage *istorage = (struct index_storage *)storage; struct maildir_list_context *ctx; @@ -266,29 +256,32 @@ ctx->flags = flags; ctx->tree_ctx = mailbox_tree_init(MAILDIR_FS_SEP); - if (storage->hierarchy_sep != MAILDIR_FS_SEP && - strchr(mask, MAILDIR_FS_SEP) != NULL) { - /* this will never match, return nothing */ - return &ctx->mailbox_ctx; + if (*ref != '\0') { + /* join reference + mask */ + if (*mask == MAILDIR_FS_SEP && + ref[strlen(ref)-1] == MAILDIR_FS_SEP) { + /* A. .B -> A.B */ + mask++; + } else if (*mask != MAILDIR_FS_SEP && + ref[strlen(ref)-1] != MAILDIR_FS_SEP) { + /* A B -> A.B */ + mask = t_strconcat(ref, MAILDIR_FS_SEP_S, mask, NULL); + } else { + mask = t_strconcat(ref, mask, NULL); + } } - mask = maildir_fix_mailbox_name(istorage, mask, FALSE); glob = imap_match_init(pool, mask, TRUE, MAILDIR_FS_SEP); ctx->dir = istorage->dir; - ctx->prefix = storage->namespace == NULL ? "" : - maildir_fix_mailbox_name(istorage, storage->namespace, FALSE); + ctx->prefix = ""; if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) { - if (!maildir_fill_subscribed(ctx, glob)) { - mailbox_tree_deinit(ctx->tree_ctx); - pool_unref(pool); - return NULL; - } + if (!maildir_fill_subscribed(ctx, glob)) + return &ctx->mailbox_ctx; } else if (full_filesystem_access && (p = strrchr(mask, '/')) != NULL) { dir = t_strdup_until(mask, p); - ctx->prefix = t_strconcat(ctx->prefix, - t_strdup_until(mask, p+1), NULL); + ctx->prefix = p_strdup_until(pool, mask, p+1); if (*mask != '/' && *mask != '~') dir = t_strconcat(istorage->dir, "/", dir, NULL); @@ -298,14 +291,10 @@ if ((flags & MAILBOX_LIST_SUBSCRIBED) == 0 || (ctx->flags & MAILBOX_LIST_FAST_FLAGS) == 0) { int update_only = (flags & MAILBOX_LIST_SUBSCRIBED) != 0; - if (!maildir_fill_readdir(ctx, glob, update_only)) { - mailbox_tree_deinit(ctx->tree_ctx); - pool_unref(pool); - return NULL; - } + if (!maildir_fill_readdir(ctx, glob, update_only)) + return &ctx->mailbox_ctx; } - ctx->prefix = p_strdup(pool, ctx->prefix); ctx->node_path = str_new(pool, 256); ctx->root = mailbox_tree_get(ctx->tree_ctx, NULL, NULL); ctx->mailbox_ctx.storage = storage; diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Fri Jul 23 00:20:00 2004 +0300 @@ -30,8 +30,7 @@ static int verify_inbox(struct index_storage *storage); static struct mail_storage * -maildir_create(const char *data, const char *user, - const char *namespace, char hierarchy_sep) +maildir_create(const char *data, const char *user) { struct index_storage *storage; const char *root_dir, *inbox_dir, *index_dir, *control_dir; @@ -91,10 +90,6 @@ storage = i_new(struct index_storage, 1); storage->storage = maildir_storage; - if (hierarchy_sep != '\0') - storage->storage.hierarchy_sep = hierarchy_sep; - storage->storage.namespace = i_strdup(namespace); - /* the default ".temp.xxx" prefix would be treated as directory */ storage->temp_prefix = i_strconcat("temp.", my_hostname, ".", my_pid, ".", NULL); @@ -184,48 +179,6 @@ MAILDIR_FS_SEP_S, p+1, NULL); } -const char *maildir_fix_mailbox_name(struct index_storage *storage, - const char *name, int remove_namespace) -{ - char *dup, *p, sep; - size_t len; - - if (strncasecmp(name, "INBOX", 5) == 0 && - (name[5] == '\0' || name[5] == storage->storage.hierarchy_sep)) { - /* use same case with all INBOX folders or we'll get - into trouble */ - name = t_strconcat("INBOX", name+5, NULL); - if (name[5] == '\0') { - /* don't check namespace with INBOX */ - return name; - } - } - - if (storage->storage.namespace != NULL && remove_namespace) { - len = strlen(storage->storage.namespace); - if (strncmp(storage->storage.namespace, name, len) != 0) { - i_panic("maildir: expecting namespace '%s' in name " - "'%s'", storage->storage.namespace, name); - } - name += len; - } - - if (full_filesystem_access && (*name == '/' || *name == '~')) - return name; - - sep = storage->storage.hierarchy_sep; - if (sep == MAILDIR_FS_SEP) - return name; - - dup = t_strdup_noconst(name); - for (p = dup; *p != '\0'; p++) { - if (*p == sep) - *p = MAILDIR_FS_SEP; - } - - return dup; -} - const char *maildir_get_path(struct index_storage *storage, const char *name) { if (full_filesystem_access && (*name == '/' || *name == '~')) @@ -455,7 +408,6 @@ mail_storage_clear_error(_storage); - name = maildir_fix_mailbox_name(storage, name, TRUE); if (strcmp(name, "INBOX") == 0) { if (verify_inbox(storage) < 0) return NULL; @@ -496,7 +448,6 @@ mail_storage_clear_error(_storage); - name = maildir_fix_mailbox_name(storage, name, TRUE); if (!maildir_is_valid_create_name(name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; @@ -524,7 +475,6 @@ mail_storage_clear_error(_storage); - name = maildir_fix_mailbox_name(storage, name, TRUE); if (strcmp(name, "INBOX") == 0) { mail_storage_set_error(_storage, "INBOX can't be deleted."); return -1; @@ -620,29 +570,23 @@ { struct mailbox_list_context *ctx; struct mailbox_list *list; - const char *oldpath, *newpath, *new_listname, *mask; + const char *oldpath, *newpath, *new_listname; size_t oldnamelen; int ret; ret = 0; oldnamelen = strlen(oldname); - mask = t_strdup_printf("%s%s%c*", storage->storage.namespace != NULL ? - storage->storage.namespace : "", oldname, - storage->storage.hierarchy_sep); - ctx = maildir_mailbox_list_init(&storage->storage, mask, + ctx = maildir_mailbox_list_init(&storage->storage, oldname, "*", MAILBOX_LIST_FAST_FLAGS); while ((list = maildir_mailbox_list_next(ctx)) != NULL) { - const char *list_name; - t_push(); - list_name = maildir_fix_mailbox_name(storage, list->name, TRUE); - i_assert(oldnamelen <= strlen(list_name)); + i_assert(oldnamelen <= strlen(list->name)); new_listname = t_strconcat(newname, - list_name + oldnamelen, NULL); - oldpath = maildir_get_path(storage, list_name); + list->name + oldnamelen, NULL); + oldpath = maildir_get_path(storage, list->name); newpath = maildir_get_path(storage, new_listname); /* FIXME: it's possible to merge two folders if either one of @@ -665,7 +609,7 @@ break; } - (void)rename_indexes(storage, list_name, new_listname); + (void)rename_indexes(storage, list->name, new_listname); t_pop(); } @@ -683,9 +627,6 @@ mail_storage_clear_error(_storage); - oldname = maildir_fix_mailbox_name(storage, oldname, TRUE); - newname = maildir_fix_mailbox_name(storage, newname, TRUE); - if (!maildir_is_valid_existing_name(oldname) || !maildir_is_valid_create_name(newname)) { mail_storage_set_error(_storage, "Invalid mailbox name"); @@ -741,7 +682,6 @@ storage->control_dir : storage->dir, "/" SUBSCRIPTION_FILE_NAME, NULL); - name = maildir_fix_mailbox_name(storage, name, FALSE); return subsfile_set_subscribed(_storage, path, storage->temp_prefix, name, set); } @@ -756,7 +696,6 @@ mail_storage_clear_error(_storage); - name = maildir_fix_mailbox_name(storage, name, TRUE); if (!maildir_is_valid_existing_name(name)) { *status = MAILBOX_NAME_INVALID; return 0; @@ -821,9 +760,8 @@ struct mail_storage maildir_storage = { "maildir", /* name */ - NULL, /* namespace */ - '.', /* default hierarchy separator */ + '.', /* hierarchy separator */ maildir_create, maildir_free, diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/maildir/maildir-storage.h --- a/src/lib-storage/index/maildir/maildir-storage.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Fri Jul 23 00:20:00 2004 +0300 @@ -33,7 +33,8 @@ struct mailbox_list_context * maildir_mailbox_list_init(struct mail_storage *storage, - const char *mask, enum mailbox_list_flags flags); + const char *ref, const char *mask, + enum mailbox_list_flags flags); int maildir_mailbox_list_deinit(struct mailbox_list_context *ctx); struct mailbox_list * maildir_mailbox_list_next(struct mailbox_list_context *ctx); @@ -60,8 +61,6 @@ int maildir_copy_commit(struct maildir_copy_context *ctx); void maildir_copy_rollback(struct maildir_copy_context *ctx); -const char *maildir_fix_mailbox_name(struct index_storage *storage, - const char *name, int remove_namespace); const char *maildir_get_path(struct index_storage *storage, const char *name); int maildir_sync_last_commit(struct index_mailbox *ibox); diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/mbox/mbox-list.c --- a/src/lib-storage/index/mbox/mbox-list.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-list.c Fri Jul 23 00:20:00 2004 +0300 @@ -31,7 +31,6 @@ enum mailbox_list_flags flags; - const char *prefix; struct imap_match_glob *glob; struct subsfile_list_context *subsfile_ctx; @@ -45,23 +44,12 @@ }; static struct mailbox_list *mbox_list_subs(struct mbox_list_context *ctx); -static struct mailbox_list *mbox_list_inbox(struct mbox_list_context *ctx); static struct mailbox_list *mbox_list_path(struct mbox_list_context *ctx); static struct mailbox_list *mbox_list_next(struct mbox_list_context *ctx); -static struct mailbox_list *mbox_list_none(struct mbox_list_context *ctx); -static const char *mask_get_dir(struct mail_storage *storage, const char *mask) +static const char *mask_get_dir(const char *mask) { const char *p, *last_dir; - size_t len; - - if (storage->namespace != NULL) { - len = strlen(storage->namespace); - if (strncmp(mask, storage->namespace, len) != 0) - return NULL; - - mask += len; - } last_dir = NULL; for (p = mask; *p != '\0' && *p != '%' && *p != '*'; p++) { @@ -110,7 +98,8 @@ } struct mailbox_list_context * -mbox_mailbox_list_init(struct mail_storage *storage, const char *mask, +mbox_mailbox_list_init(struct mail_storage *storage, + const char *ref, const char *mask, enum mailbox_list_flags flags) { struct index_storage *istorage = (struct index_storage *)storage; @@ -118,26 +107,32 @@ const char *path, *virtual_path; DIR *dirp; + ctx = i_new(struct mbox_list_context, 1); + ctx->mailbox_ctx.storage = storage; + ctx->istorage = istorage; + ctx->list_pool = pool_alloconly_create("mbox_list", 1024); + ctx->next = mbox_list_next; + mail_storage_clear_error(storage); - if (storage->hierarchy_sep != '/' && strchr(mask, '/') != NULL) { - /* this will never match, return nothing */ - ctx = i_new(struct mbox_list_context, 1); - ctx->mailbox_ctx.storage = storage; - ctx->next = mbox_list_none; + /* check that we're not trying to do any "../../" lists */ + if (!mbox_is_valid_mask(ref) || + !mbox_is_valid_mask(mask)) { + mail_storage_set_error(storage, "Invalid mask"); return &ctx->mailbox_ctx; } - mask = mbox_fix_mailbox_name(istorage, mask, FALSE); - - /* check that we're not trying to do any "../../" lists */ - if (!mbox_is_valid_mask(mask)) { - mail_storage_set_error(storage, "Invalid mask"); - return NULL; + if (*mask == '/' || *mask == '~') { + /* mask overrides reference */ + } else if (*ref != '\0') { + /* merge reference and mask */ + if (ref[strlen(ref)-1] == '/') + mask = t_strconcat(ref, mask, NULL); + else + mask = t_strconcat(ref, "/", mask, NULL); } if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) { - ctx = i_new(struct mbox_list_context, 1); ctx->mailbox_ctx.storage = storage; ctx->istorage = istorage; ctx->flags = flags; @@ -148,45 +143,33 @@ ctx->subsfile_ctx = subsfile_list_init(storage, path); if (ctx->subsfile_ctx == NULL) { - i_free(ctx); - return NULL; + ctx->next = mbox_list_next; + return &ctx->mailbox_ctx; } ctx->glob = imap_match_init(default_pool, mask, TRUE, '/'); - ctx->list_pool = pool_alloconly_create("mbox_list", 1024); return &ctx->mailbox_ctx; } /* if we're matching only subdirectories, don't bother scanning the parent directories */ - virtual_path = mask_get_dir(storage, mask); + virtual_path = mask_get_dir(mask); path = mbox_get_path(istorage, virtual_path); if (list_opendir(storage, path, TRUE, &dirp) < 0) - return NULL; + return &ctx->mailbox_ctx; /* if user gave invalid directory, we just don't show any results. */ - ctx = i_new(struct mbox_list_context, 1); - ctx->mailbox_ctx.storage = storage; - ctx->istorage = istorage; ctx->flags = flags; ctx->glob = imap_match_init(default_pool, mask, TRUE, '/'); - ctx->list_pool = pool_alloconly_create("mbox_list", 1024); - ctx->prefix = storage->namespace == NULL ? "" : - mbox_fix_mailbox_name(istorage, storage->namespace, FALSE); - if (virtual_path == NULL && imap_match(ctx->glob, "INBOX") > 0) - ctx->next = mbox_list_inbox; - else if (virtual_path != NULL && dirp != NULL) + if (virtual_path != NULL && dirp != NULL) ctx->next = mbox_list_path; - else - ctx->next = mbox_list_next; if (dirp != NULL) { ctx->dir = i_new(struct list_dir_context, 1); ctx->dir->dirp = dirp; ctx->dir->real_path = i_strdup(path); - ctx->dir->virtual_path = virtual_path == NULL ? NULL : - i_strconcat(ctx->prefix, virtual_path, NULL); + ctx->dir->virtual_path = i_strdup(virtual_path); } return &ctx->mailbox_ctx; } @@ -253,7 +236,7 @@ /* check the mask */ if (ctx->dir->virtual_path == NULL) - list_path = t_strconcat(ctx->prefix, fname, NULL); + list_path = fname; else { list_path = t_strconcat(ctx->dir->virtual_path, "/", fname, NULL); @@ -303,12 +286,7 @@ } else if (ret < 0) return -1; return match > 0 || match2 > 0; - } else if (match > 0 && - strcmp(real_path, ctx->istorage->inbox_path) != 0 && - strcasecmp(list_path, "INBOX") != 0) { - /* don't match any INBOX here, it's added separately. - we might also have ~/mail/inbox, ~/mail/Inbox etc. - Just ignore them for now. */ + } else if (match > 0) { ctx->list.flags = noselect ? MAILBOX_NOSELECT : (MAILBOX_NOINFERIORS | STAT_GET_MARKED(st)); ctx->list.name = p_strdup(ctx->list_pool, list_path); @@ -318,24 +296,6 @@ return 0; } -static struct mailbox_list *list_fix_name(struct mbox_list_context *ctx) -{ - char *p, *str, sep; - - if (strchr(ctx->list.name, '/') != NULL) { - str = p_strdup(ctx->list_pool, ctx->list.name); - ctx->list.name = str; - - sep = ctx->mailbox_ctx.storage->hierarchy_sep; - for (p = str; *p != '\0'; p++) { - if (*p == '/') - *p = sep; - } - } - - return &ctx->list; -} - static struct mailbox_list *mbox_list_subs(struct mbox_list_context *ctx) { struct stat st; @@ -362,19 +322,17 @@ if (imap_match(ctx->glob, name) > 0) { p_clear(ctx->list_pool); ctx->list.name = p_strdup(ctx->list_pool, name); - return list_fix_name(ctx); + return &ctx->list; } } i_unreached(); } - (void)list_fix_name(ctx); if ((ctx->flags & MAILBOX_LIST_FAST_FLAGS) != 0) return &ctx->list; t_push(); - name = mbox_fix_mailbox_name(ctx->istorage, ctx->list.name, TRUE); - path = mbox_get_path(ctx->istorage, name); + path = mbox_get_path(ctx->istorage, ctx->list.name); if (stat(path, &st) == 0) { if (S_ISDIR(st.st_mode)) ctx->list.flags = MAILBOX_NOSELECT | MAILBOX_CHILDREN; @@ -383,48 +341,22 @@ STAT_GET_MARKED(st); } } else { - if (strcasecmp(ctx->list.name, "INBOX") == 0) - ctx->list.flags = MAILBOX_UNMARKED; - else - ctx->list.flags = MAILBOX_NONEXISTENT; + ctx->list.flags = MAILBOX_NONEXISTENT; } t_pop(); return &ctx->list; } -static struct mailbox_list *mbox_list_inbox(struct mbox_list_context *ctx) -{ - struct stat st; - - if (ctx->dir != NULL && ctx->dir->virtual_path != NULL) - ctx->next = mbox_list_path; - else - ctx->next = mbox_list_next; - - /* INBOX exists always, even if the file doesn't. */ - ctx->list.flags = strncmp(ctx->prefix, "INBOX/", 6) == 0 ? - MAILBOX_CHILDREN : MAILBOX_NOINFERIORS; - if ((ctx->flags & MAILBOX_LIST_FAST_FLAGS) == 0) { - if (stat(ctx->istorage->inbox_path, &st) < 0) - ctx->list.flags |= MAILBOX_UNMARKED; - else - ctx->list.flags |= STAT_GET_MARKED(st); - } - - ctx->list.name = "INBOX"; - return &ctx->list; -} - static struct mailbox_list *mbox_list_path(struct mbox_list_context *ctx) { ctx->next = mbox_list_next; ctx->list.flags = MAILBOX_NOSELECT | MAILBOX_CHILDREN; - ctx->list.name = p_strconcat(ctx->list_pool, ctx->prefix, - ctx->dir->virtual_path, "/", NULL); + ctx->list.name = + p_strconcat(ctx->list_pool, ctx->dir->virtual_path, "/", NULL); if (imap_match(ctx->glob, ctx->list.name) > 0) - return list_fix_name(ctx); + return &ctx->list; else return ctx->next(ctx); } @@ -445,7 +377,7 @@ t_pop(); if (ret > 0) - return list_fix_name(ctx); + return &ctx->list; if (ret < 0) { ctx->failed = TRUE; return NULL; @@ -460,9 +392,3 @@ /* finished */ return NULL; } - -static struct mailbox_list * -mbox_list_none(struct mbox_list_context *ctx __attr_unused__) -{ - return NULL; -} diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Fri Jul 23 00:20:00 2004 +0300 @@ -150,9 +150,7 @@ return path; } -static struct mail_storage * -mbox_create(const char *data, const char *user, - const char *namespace, char hierarchy_sep) +static struct mail_storage *mbox_create(const char *data, const char *user) { struct index_storage *storage; const char *root_dir, *inbox_file, *index_dir, *p; @@ -224,10 +222,6 @@ storage = i_new(struct index_storage, 1); storage->storage = mbox_storage; - if (hierarchy_sep != '\0') - storage->storage.hierarchy_sep = hierarchy_sep; - storage->storage.namespace = i_strdup(namespace); - storage->dir = i_strdup(home_expand(root_dir)); storage->inbox_path = i_strdup(home_expand(inbox_file)); storage->index_dir = i_strdup(home_expand(index_dir)); @@ -251,47 +245,6 @@ i_free(storage); } -const char *mbox_fix_mailbox_name(struct index_storage *istorage, - const char *name, int remove_namespace) -{ - struct mail_storage *storage = &istorage->storage; - char *dup, *p, sep; - size_t len; - - if (strncasecmp(name, "INBOX", 5) == 0 && - (name[5] == '\0' || name[5] == storage->hierarchy_sep)) { - name = t_strconcat("INBOX", name+5, NULL); - if (name[5] == '\0') { - /* don't check namespace with INBOX */ - return name; - } - } - - if (storage->namespace != NULL && remove_namespace) { - len = strlen(storage->namespace); - if (strncmp(storage->namespace, name, len) != 0) { - i_panic("mbox: expecting namespace '%s' in name '%s'", - storage->namespace, name); - } - name += len; - } - - if (*name == '/' && full_filesystem_access) - return name; - - sep = storage->hierarchy_sep; - if (sep == '/') - return name; - - dup = t_strdup_noconst(name); - for (p = dup; *p != '\0'; p++) { - if (*p == sep) - *p = '/'; - } - - return dup; -} - int mbox_is_valid_mask(const char *mask) { const char *p; @@ -390,8 +343,8 @@ if (fd != -1) (void)close(fd); else if (errno != EEXIST) { - mail_storage_set_critical(storage, - "open(%s, O_CREAT) failed: %m", storage->inbox_file); + mail_storage_set_critical(&storage->storage, + "open(%s, O_CREAT) failed: %m", storage->inbox_path); } /* make sure the index directories exist */ @@ -404,7 +357,7 @@ static const char * mbox_get_path(struct index_storage *storage, const char *name) { - if (strcasecmp(name, "INBOX") == 0) + if (strcmp(name, "INBOX") == 0) return storage->inbox_path; if (full_filesystem_access && (*name == '/' || *name == '~')) return home_expand(name); @@ -434,7 +387,7 @@ const char *path, *index_dir; uint32_t mbox_extra_idx; - if (strcasecmp(name, "INBOX") == 0) { + if (strcmp(name, "INBOX") == 0) { /* name = "INBOX" path = "/INBOX" index_dir = "/mail/.imap/INBOX" */ @@ -487,11 +440,8 @@ mail_storage_clear_error(_storage); - name = mbox_fix_mailbox_name(storage, name, TRUE); - - /* INBOX is always case-insensitive */ - if (strcasecmp(name, "INBOX") == 0) { - /* make sure inbox exists */ + if (strcmp(name, "INBOX") == 0) { + /* make sure INBOX exists */ if (verify_inbox(storage) < 0) return NULL; return mbox_open(storage, "INBOX", flags); @@ -538,8 +488,6 @@ mail_storage_clear_error(_storage); - name = mbox_fix_mailbox_name(storage, name, TRUE); - if (!mbox_is_valid_create_name(name)) { mail_storage_set_error(_storage, "Invalid mailbox name"); return -1; @@ -607,9 +555,7 @@ mail_storage_clear_error(_storage); - name = mbox_fix_mailbox_name(storage, name, TRUE); - - if (strcasecmp(name, "INBOX") == 0) { + if (strcmp(name, "INBOX") == 0) { mail_storage_set_error(_storage, "INBOX can't be deleted."); return -1; } @@ -701,9 +647,6 @@ mail_storage_clear_error(_storage); - oldname = mbox_fix_mailbox_name(storage, oldname, TRUE); - newname = mbox_fix_mailbox_name(storage, newname, TRUE); - if (!mbox_is_valid_existing_name(oldname) || !mbox_is_valid_create_name(newname)) { mail_storage_set_error(_storage, "Invalid mailbox name"); @@ -780,7 +723,6 @@ const char *path; path = t_strconcat(storage->dir, "/" SUBSCRIPTION_FILE_NAME, NULL); - name = mbox_fix_mailbox_name(storage, name, FALSE); return subsfile_set_subscribed(_storage, path, storage->temp_prefix, name, set); } @@ -795,8 +737,6 @@ mail_storage_clear_error(_storage); - name = mbox_fix_mailbox_name(storage, name, TRUE); - if (!mbox_is_valid_existing_name(name)) { *status = MAILBOX_NAME_INVALID; return 0; @@ -853,9 +793,8 @@ struct mail_storage mbox_storage = { "mbox", /* name */ - NULL, /* namespace */ - '/', /* default hierarchy separator */ + '/', /* hierarchy separator */ mbox_create, mbox_free, diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/index/mbox/mbox-storage.h --- a/src/lib-storage/index/mbox/mbox-storage.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.h Fri Jul 23 00:20:00 2004 +0300 @@ -24,7 +24,8 @@ int mbox_set_syscall_error(struct index_mailbox *ibox, const char *function); struct mailbox_list_context * -mbox_mailbox_list_init(struct mail_storage *storage, const char *mask, +mbox_mailbox_list_init(struct mail_storage *storage, + const char *ref, const char *mask, enum mailbox_list_flags flags); int mbox_mailbox_list_deinit(struct mailbox_list_context *ctx); struct mailbox_list *mbox_mailbox_list_next(struct mailbox_list_context *ctx); @@ -45,8 +46,6 @@ int mbox_save_commit(struct mbox_save_context *ctx); void mbox_save_rollback(struct mbox_save_context *ctx); -const char *mbox_fix_mailbox_name(struct index_storage *istorage, - const char *name, int remove_namespace); int mbox_is_valid_mask(const char *mask); #endif diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/mail-storage-private.h Fri Jul 23 00:20:00 2004 +0300 @@ -5,12 +5,9 @@ struct mail_storage { char *name; - char *namespace; char hierarchy_sep; - struct mail_storage *(*create)(const char *data, const char *user, - const char *namespace, - char hierarchy_sep); + struct mail_storage *(*create)(const char *data, const char *user); void (*destroy)(struct mail_storage *storage); int (*autodetect)(const char *data); @@ -31,7 +28,7 @@ struct mailbox_list_context * (*mailbox_list_init)(struct mail_storage *storage, - const char *mask, + const char *ref, const char *mask, enum mailbox_list_flags flags); struct mailbox_list * (*mailbox_list_next)(struct mailbox_list_context *ctx); diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/mail-storage.c Fri Jul 23 00:20:00 2004 +0300 @@ -69,33 +69,28 @@ } struct mail_storage * -mail_storage_create(const char *name, const char *data, const char *user, - const char *namespace, char hierarchy_sep) +mail_storage_create(const char *name, const char *data, const char *user) { struct mail_storage_list *list; i_assert(name != NULL); for (list = storages; list != NULL; list = list->next) { - if (strcasecmp(list->storage->name, name) == 0) { - return list->storage->create(data, user, - namespace, hierarchy_sep); - } + if (strcasecmp(list->storage->name, name) == 0) + return list->storage->create(data, user); } return NULL; } struct mail_storage * -mail_storage_create_default(const char *user, - const char *namespace, char hierarchy_sep) +mail_storage_create_default(const char *user) { struct mail_storage_list *list; struct mail_storage *storage; for (list = storages; list != NULL; list = list->next) { - storage = list->storage->create(NULL, user, namespace, - hierarchy_sep); + storage = list->storage->create(NULL, user); if (storage != NULL) return storage; } @@ -116,16 +111,13 @@ } struct mail_storage * -mail_storage_create_with_data(const char *data, const char *user, - const char *namespace, char hierarchy_sep) +mail_storage_create_with_data(const char *data, const char *user) { struct mail_storage *storage; const char *p, *name; - if (data == NULL || *data == '\0') { - return mail_storage_create_default(user, namespace, - hierarchy_sep); - } + if (data == NULL || *data == '\0') + return mail_storage_create_default(user); /* check if we're in the form of mailformat:data (eg. maildir:Maildir) */ @@ -134,14 +126,11 @@ if (*p == ':') { name = t_strdup_until(data, p); - storage = mail_storage_create(name, p+1, user, - namespace, hierarchy_sep); + storage = mail_storage_create(name, p+1, user); } else { storage = mail_storage_autodetect(data); - if (storage != NULL) { - storage = storage->create(data, user, - namespace, hierarchy_sep); - } + if (storage != NULL) + storage = storage->create(data, user); } return storage; @@ -260,10 +249,10 @@ struct mailbox_list_context * mail_storage_mailbox_list_init(struct mail_storage *storage, - const char *mask, + const char *ref, const char *mask, enum mailbox_list_flags flags) { - return storage->mailbox_list_init(storage, mask, flags); + return storage->mailbox_list_init(storage, ref, mask, flags); } struct mailbox_list * diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/mail-storage.h Fri Jul 23 00:20:00 2004 +0300 @@ -167,16 +167,12 @@ 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, - const char *namespace, char hierarchy_sep); +mail_storage_create(const char *name, const char *data, const char *user); 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, - const char *namespace, char hierarchy_sep); -struct mail_storage * -mail_storage_create_with_data(const char *data, const char *user, - const char *namespace, char hierarchy_sep); +mail_storage_create_with_data(const char *data, const char *user); char mail_storage_get_hierarchy_sep(struct mail_storage *storage); @@ -205,11 +201,11 @@ const char *oldname, const char *newname); /* Initialize new mailbox list request. mask may contain '%' and '*' - wildcards as defined in RFC2060. Matching against "INBOX" is + wildcards as defined in RFC3501. Matching against "INBOX" is case-insensitive, but anything else is not. */ struct mailbox_list_context * mail_storage_mailbox_list_init(struct mail_storage *storage, - const char *mask, + const char *ref, const char *mask, enum mailbox_list_flags flags); /* Get next mailbox. Returns the mailbox name */ struct mailbox_list * @@ -259,8 +255,7 @@ int mailbox_allow_new_keywords(struct mailbox *box); /* Gets the mailbox status information. */ -int mailbox_get_status(struct mailbox *box, - enum mailbox_status_items items, +int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status); /* Synchronize the mailbox. */ diff -r b65456de1b49 -r 1371d41c375f src/lib-storage/proxy-mail-storage.c --- a/src/lib-storage/proxy-mail-storage.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/lib-storage/proxy-mail-storage.c Fri Jul 23 00:20:00 2004 +0300 @@ -52,12 +52,13 @@ } static struct mailbox_list_context * -_mailbox_list_init(struct mail_storage *storage, const char *mask, +_mailbox_list_init(struct mail_storage *storage, + const char *ref, const char *mask, enum mailbox_list_flags flags) { struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - return s->storage->mailbox_list_init(s->storage, mask, flags); + return s->storage->mailbox_list_init(s->storage, ref, mask, flags); } static int _set_subscribed(struct mail_storage *storage, diff -r b65456de1b49 -r 1371d41c375f src/pop3/main.c --- a/src/pop3/main.c Thu Jul 22 22:37:25 2004 +0300 +++ b/src/pop3/main.c Fri Jul 23 00:20:00 2004 +0300 @@ -130,8 +130,7 @@ } parse_workarounds(); - storage = mail_storage_create_with_data(mail, getenv("USER"), - NULL, '\0'); + storage = mail_storage_create_with_data(mail, getenv("USER")); if (storage == NULL) { /* failed */ if (mail != NULL && *mail != '\0')