mailbox-list-fs-iter.c revision 5fb3bff645380804c9db2510940c41db6b8fdb01
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose/* Copyright (C) 2002-2006 Timo Sirainen */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose struct mailbox_info *(*next)(struct fs_list_iterate_context *ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic struct mailbox_info *fs_list_subs(struct fs_list_iterate_context *ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic struct mailbox_info *fs_list_path(struct fs_list_iterate_context *ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic struct mailbox_info *fs_list_next(struct fs_list_iterate_context *ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const char *p, *last_dir;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (p = mask; *p != '\0' && *p != '%' && *p != '*'; p++) {
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina if (*p == '/')
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return last_dir == NULL ? NULL : t_strdup_until(mask, last_dir);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic int list_opendir(struct mailbox_list *list,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* root) user gave invalid hiearchy, ignore
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose sub) probably just race condition with other client
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose deleting the mailbox. */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* subfolder, ignore */
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose mailbox_list_set_critical(list, "opendir(%s) failed: %m", path);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bosefs_list_iter_init(struct mailbox_list *_list, const char *mask,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ctx->info_pool = pool_alloconly_create("fs list", 1024);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose /* check that we're not trying to do any "../../" lists */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if ((flags & MAILBOX_LIST_ITER_SUBSCRIBED) != 0) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose path = t_strconcat(_list->set.control_dir != NULL ?
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ctx->subsfile_ctx = subsfile_list_init(_list, path);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ctx->glob = imap_match_init(default_pool, mask, TRUE, '/');
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* if we're matching only subdirectories, don't bother scanning the
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose parent directories */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose path = mailbox_list_get_path(_list, virtual_path,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* if user gave invalid directory, we just don't show any results. */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ctx->glob = imap_match_init(default_pool, mask, TRUE, '/');
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic void list_dir_context_free(struct list_dir_context *dir)
45726939a48e605b0166521f94300ae04981a3a7Sumit Boseint fs_list_iter_deinit(struct mailbox_list_iterate_context *_ctx)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bosefs_list_iter_next(struct mailbox_list_iterate_context *_ctx)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Boselist_file(struct fs_list_iterate_context *ctx, const struct dirent *d)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const char *list_path, *real_path, *path, *inbox_path;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose /* skip . and .. */
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose /* check the mask */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if ((match = imap_match(ctx->glob, list_path)) < 0)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* get the info.flags using callback */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = ctx->ctx.list->callback(ctx->dir->real_path, fname,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* make sure we give only one correct INBOX */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose real_path = t_strconcat(ctx->dir->real_path, "/", fname, NULL);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_INBOX) != 0) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose inbox_path = mailbox_list_get_path(ctx->ctx.list, "INBOX",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (ctx->inbox_found || strcmp(real_path, inbox_path) != 0)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if ((ctx->info.flags & MAILBOX_NOINFERIORS) == 0) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* subdirectory. scan inside it. */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ctx->info.name = p_strdup(ctx->info_pool, list_path);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose else if (match2 > 0)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose list_opendir(ctx->ctx.list, real_path, FALSE, &dirp);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else if (ret < 0)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else if (match > 0) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ctx->info.name = p_strdup(ctx->info_pool, list_path);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosepath_split(const char *path, const char **dir_r, const char **fname_r)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const char *p;
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bosestatic struct mailbox_info *fs_list_subs(struct fs_list_iterate_context *ctx)
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose while ((name = subsfile_list_next(ctx->subsfile_ctx)) != NULL) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (match == IMAP_MATCH_YES || match == IMAP_MATCH_PARENT)
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose /* placeholder */
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose ctx->info.flags = MAILBOX_NONEXISTENT | MAILBOX_CHILDREN;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if ((ctx->ctx.flags & MAILBOX_LIST_ITER_FAST_FLAGS) != 0)
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose path = mailbox_list_get_path(ctx->ctx.list, ctx->info.name,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic struct mailbox_info *fs_list_path(struct fs_list_iterate_context *ctx)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ctx->info.flags = MAILBOX_NOSELECT | MAILBOX_CHILDREN;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose p_strconcat(ctx->info_pool, ctx->dir->virtual_path, "/", NULL);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bosestatic struct mailbox_info *fs_list_inbox(struct fs_list_iterate_context *ctx)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose inbox_path = mailbox_list_get_path(ctx->ctx.list, "INBOX",
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bosestatic struct mailbox_info *fs_list_next(struct fs_list_iterate_context *ctx)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose /* NOTE: list_file() may change ctx->dir */
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_INBOX) != 0 &&
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose ctx->glob != NULL && imap_match(ctx->glob, "INBOX") > 0) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose /* show inbox */
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose /* finished */