Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/list/mailbox-list-maildir-iter.c @ 6573:c901bdf0db75 HEAD
Fixes for listing namespaces with prefixes and real != virtual separator.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 20 Oct 2007 22:58:54 +0300 |
parents | 65c69a53a7be |
children | 80419a82081f |
comparison
equal
deleted
inserted
replaced
6572:79836b3474f4 | 6573:c901bdf0db75 |
---|---|
43 { | 43 { |
44 struct mailbox_node *node; | 44 struct mailbox_node *node; |
45 const char *p; | 45 const char *p; |
46 char hierarchy_sep; | 46 char hierarchy_sep; |
47 bool created; | 47 bool created; |
48 | 48 const char *ns_prefix = ctx->ctx.list->ns->prefix; |
49 hierarchy_sep = ctx->ctx.list->hierarchy_sep; | 49 unsigned int ns_prefix_len = strlen(ns_prefix); |
50 | |
51 hierarchy_sep = ctx->ctx.list->ns->sep; | |
50 | 52 |
51 t_push(); | 53 t_push(); |
52 while ((p = strrchr(mailbox_c, hierarchy_sep)) != NULL) { | 54 while ((p = strrchr(mailbox_c, hierarchy_sep)) != NULL) { |
53 str_truncate(mailbox, (size_t) (p-mailbox_c)); | 55 str_truncate(mailbox, (size_t) (p-mailbox_c)); |
54 mailbox_c = str_c(mailbox); | 56 mailbox_c = str_c(mailbox); |
55 if (imap_match(glob, mailbox_c) == IMAP_MATCH_YES) { | 57 if (imap_match(glob, mailbox_c) != IMAP_MATCH_YES) |
56 created = FALSE; | 58 continue; |
57 node = update_only ? | 59 |
58 mailbox_tree_lookup(ctx->tree_ctx, mailbox_c) : | 60 if (*ns_prefix != '\0' && |
59 mailbox_tree_get(ctx->tree_ctx, | 61 strncmp(mailbox_c, ns_prefix, ns_prefix_len - 1) == 0) { |
60 mailbox_c, &created); | 62 /* don't return matches to namespace prefix itself */ |
61 if (node != NULL) { | 63 continue; |
62 if (created) { | 64 } |
63 /* we haven't yet seen this mailbox, | 65 |
64 but we might see it later */ | 66 created = FALSE; |
65 node->flags = MAILBOX_NONEXISTENT; | 67 node = update_only ? |
66 } | 68 mailbox_tree_lookup(ctx->tree_ctx, mailbox_c) : |
67 if (!update_only) | 69 mailbox_tree_get(ctx->tree_ctx, mailbox_c, &created); |
68 node->flags |= MAILBOX_MATCHED; | 70 if (node != NULL) { |
69 node->flags |= MAILBOX_CHILDREN | flags; | 71 if (created) { |
70 node->flags &= ~MAILBOX_NOCHILDREN; | 72 /* we haven't yet seen this mailbox, |
71 node_fix_parents(node); | 73 but we might see it later */ |
74 node->flags = MAILBOX_NONEXISTENT; | |
72 } | 75 } |
76 if (!update_only) | |
77 node->flags |= MAILBOX_MATCHED; | |
78 node->flags |= MAILBOX_CHILDREN | flags; | |
79 node->flags &= ~MAILBOX_NOCHILDREN; | |
80 node_fix_parents(node); | |
73 } | 81 } |
74 } | 82 } |
75 t_pop(); | 83 t_pop(); |
76 } | 84 } |
77 | 85 |
78 static int | 86 static int |
79 maildir_fill_readdir(struct maildir_list_iterate_context *ctx, | 87 maildir_fill_readdir(struct maildir_list_iterate_context *ctx, |
80 struct imap_match_glob *glob, bool update_only) | 88 struct imap_match_glob *glob, bool update_only) |
81 { | 89 { |
90 struct mail_namespace *ns = ctx->ctx.list->ns; | |
82 DIR *dirp; | 91 DIR *dirp; |
83 struct dirent *d; | 92 struct dirent *d; |
84 const char *mailbox_name, *mailbox_c; | 93 const char *mailbox_name; |
94 char *mailbox_c; | |
85 string_t *mailbox; | 95 string_t *mailbox; |
86 enum mailbox_info_flags flags; | 96 enum mailbox_info_flags flags; |
87 enum imap_match_result match; | 97 enum imap_match_result match; |
88 struct mailbox_node *node; | 98 struct mailbox_node *node; |
89 bool created; | 99 bool created; |
90 char prefix_char; | 100 char prefix_char; |
101 unsigned int pos; | |
91 int ret; | 102 int ret; |
92 | 103 |
93 dirp = opendir(ctx->dir); | 104 dirp = opendir(ctx->dir); |
94 if (dirp == NULL) { | 105 if (dirp == NULL) { |
95 if (errno != ENOENT) { | 106 if (errno != ENOENT) { |
122 (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0'))) | 133 (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0'))) |
123 continue; | 134 continue; |
124 | 135 |
125 /* make sure the pattern matches */ | 136 /* make sure the pattern matches */ |
126 str_truncate(mailbox, 0); | 137 str_truncate(mailbox, 0); |
127 if ((ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX) == 0 || | 138 if ((ns->flags & NAMESPACE_FLAG_INBOX) == 0 || |
128 strcasecmp(mailbox_name, "INBOX") != 0) | 139 strcasecmp(mailbox_name, "INBOX") != 0) |
129 str_append(mailbox, ctx->ctx.list->ns->prefix); | 140 str_append(mailbox, ns->prefix); |
141 | |
142 pos = str_len(mailbox); | |
130 str_append(mailbox, mailbox_name); | 143 str_append(mailbox, mailbox_name); |
131 mailbox_c = str_c(mailbox); | 144 mailbox_c = str_c_modifiable(mailbox); |
145 while (mailbox_c[pos] != '\0') { | |
146 if (mailbox_c[pos] == ns->real_sep) | |
147 mailbox_c[pos] = ns->sep; | |
148 pos++; | |
149 } | |
132 | 150 |
133 match = imap_match(glob, mailbox_c); | 151 match = imap_match(glob, mailbox_c); |
134 if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) == 0) | 152 if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) == 0) |
135 continue; | 153 continue; |
136 | 154 |
179 mailbox_list_set_critical(ctx->ctx.list, | 197 mailbox_list_set_critical(ctx->ctx.list, |
180 "readdir(%s) failed: %m", ctx->dir); | 198 "readdir(%s) failed: %m", ctx->dir); |
181 return -1; | 199 return -1; |
182 } | 200 } |
183 | 201 |
184 if ((ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) { | 202 if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0) { |
185 /* make sure INBOX is there */ | 203 /* make sure INBOX is there */ |
186 created = FALSE; | 204 created = FALSE; |
187 node = update_only ? | 205 node = update_only ? |
188 mailbox_tree_lookup(ctx->tree_ctx, "INBOX") : | 206 mailbox_tree_lookup(ctx->tree_ctx, "INBOX") : |
189 mailbox_tree_get(ctx->tree_ctx, "INBOX", &created); | 207 mailbox_tree_get(ctx->tree_ctx, "INBOX", &created); |
196 if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) != 0) { | 214 if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) != 0) { |
197 if (!update_only) | 215 if (!update_only) |
198 node->flags |= MAILBOX_MATCHED; | 216 node->flags |= MAILBOX_MATCHED; |
199 } | 217 } |
200 } else if (mailbox_tree_lookup(ctx->tree_ctx, "INBOX") == NULL && | 218 } else if (mailbox_tree_lookup(ctx->tree_ctx, "INBOX") == NULL && |
201 imap_match(glob, "INBOX")) { | 219 imap_match(glob, "INBOX") == IMAP_MATCH_YES) { |
202 /* see if INBOX exists. */ | 220 /* see if INBOX exists. */ |
203 ret = ctx->ctx.list->v. | 221 ret = ctx->ctx.list->v. |
204 iter_is_mailbox(&ctx->ctx, ctx->dir, "", | 222 iter_is_mailbox(&ctx->ctx, ctx->dir, "", |
205 MAILBOX_LIST_FILE_TYPE_UNKNOWN, &flags); | 223 MAILBOX_LIST_FILE_TYPE_UNKNOWN, &flags); |
206 if (ret > 0) { | 224 if (ret > 0) { |
207 mailbox_c = t_strconcat(ctx->ctx.list->ns->prefix, | 225 node = mailbox_tree_get(ctx->tree_ctx, |
208 "INBOX", NULL); | 226 t_strconcat(ns->prefix, "INBOX", NULL), NULL); |
209 node = mailbox_tree_get(ctx->tree_ctx, mailbox_c, NULL); | |
210 node->flags = MAILBOX_NOCHILDREN | MAILBOX_MATCHED; | 227 node->flags = MAILBOX_NOCHILDREN | MAILBOX_MATCHED; |
211 } | 228 } |
212 } | 229 } |
213 return 0; | 230 return 0; |
214 } | 231 } |
224 pool = pool_alloconly_create("maildir_list", 1024); | 241 pool = pool_alloconly_create("maildir_list", 1024); |
225 ctx = p_new(pool, struct maildir_list_iterate_context, 1); | 242 ctx = p_new(pool, struct maildir_list_iterate_context, 1); |
226 ctx->ctx.list = _list; | 243 ctx->ctx.list = _list; |
227 ctx->ctx.flags = flags; | 244 ctx->ctx.flags = flags; |
228 ctx->pool = pool; | 245 ctx->pool = pool; |
229 ctx->tree_ctx = mailbox_tree_init(_list->hierarchy_sep); | 246 ctx->tree_ctx = mailbox_tree_init(_list->ns->sep); |
230 | 247 |
231 glob = imap_match_init_multiple(pool, patterns, TRUE, | 248 glob = imap_match_init_multiple(pool, patterns, TRUE, _list->ns->sep); |
232 _list->hierarchy_sep); | |
233 | 249 |
234 ctx->dir = _list->set.root_dir; | 250 ctx->dir = _list->set.root_dir; |
235 | 251 |
236 if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) { | 252 if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) { |
237 /* Listing only subscribed mailboxes. | 253 /* Listing only subscribed mailboxes. |