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.