doveadm-mail-list-iter.c revision 013a0e03309a4a77552f6e8dd46d06c3d3f60f53
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Copyright (c) 2010-2011 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "array.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "str.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "mail-search.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "mail-namespace.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "mailbox-list.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "doveadm-mail-list-iter.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct doveadm_mail_list_iter {
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen struct mail_search_args *search_args;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mailbox_list_iter_flags iter_flags;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox_list_iterate_context *iter;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bool only_selectable;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int
7384b4e78eaab44693c985192276e31322155e32Stephan Boschsearch_args_get_mailbox_patterns(const struct mail_search_arg *args,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ARRAY_TYPE(const_string) *patterns,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bool *have_guid_r)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const struct mail_search_arg *subargs;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (; args != NULL; args = args->next) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch switch (args->type) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_OR:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_SUB:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_INTHREAD:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch subargs = args->value.subargs;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (; subargs != NULL; subargs = subargs->next) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (!search_args_get_mailbox_patterns(subargs,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch patterns, have_guid_r))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return 0;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_MAILBOX:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_MAILBOX_GLOB:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (args->match_not) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch array_clear(patterns);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return 0;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch array_append(patterns, &args->value.str, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SEARCH_MAILBOX_GUID:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch *have_guid_r = TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch default:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return 1;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct doveadm_mail_list_iter *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschdoveadm_mail_list_iter_init(struct mail_user *user,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_search_args *search_args,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mailbox_list_iter_flags iter_flags)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch static const char *all_pattern = "*";
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct doveadm_mail_list_iter *iter;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ARRAY_TYPE(const_string) patterns;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum namespace_type ns_mask = NAMESPACE_PRIVATE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bool have_guid = FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter = i_new(struct doveadm_mail_list_iter, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter->search_args = search_args;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch t_array_init(&patterns, 16);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch search_args_get_mailbox_patterns(search_args->args, &patterns,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch &have_guid);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (array_count(&patterns) == 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter_flags |= MAILBOX_LIST_ITER_SKIP_ALIASES;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (have_guid)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ns_mask |= NAMESPACE_SHARED | NAMESPACE_PUBLIC;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch array_append(&patterns, &all_pattern, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch } else {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter_flags |= MAILBOX_LIST_ITER_STAR_WITHIN_NS;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ns_mask |= NAMESPACE_SHARED | NAMESPACE_PUBLIC;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (void)array_append_space(&patterns);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter->only_selectable = TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter->iter_flags = iter_flags;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter->iter = mailbox_list_iter_init_namespaces(user->namespaces,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch array_idx(&patterns, 0),
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ns_mask, iter_flags);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return iter;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen}
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainenstruct doveadm_mail_list_iter *
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainendoveadm_mail_list_iter_full_init(struct mail_user *user,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_search_args *search_args,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mailbox_list_iter_flags iter_flags)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct doveadm_mail_list_iter *iter;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter = doveadm_mail_list_iter_init(user, search_args, iter_flags);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch iter->only_selectable = FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return iter;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid doveadm_mail_list_iter_deinit(struct doveadm_mail_list_iter **_iter)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct doveadm_mail_list_iter *iter = *_iter;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch *_iter = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mailbox_list_iter_deinit(&iter->iter) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_error("Listing mailboxes failed");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_free(iter);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschconst struct mailbox_info *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschdoveadm_mail_list_iter_next(struct doveadm_mail_list_iter *iter)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const struct mailbox_info *info;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int len;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch while ((info = mailbox_list_iter_next(iter->iter)) != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch char sep = mail_namespace_get_sep(info->ns);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if ((info->flags & (MAILBOX_NOSELECT |
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MAILBOX_NONEXISTENT)) != 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (iter->only_selectable)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch continue;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch len = strlen(info->name);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (len > 0 &&
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch info->name[len-1] == sep) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* when listing "foo/%" it lists "foo/". skip it. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch continue;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_search_args_match_mailbox(iter->search_args,
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen info->name, sep))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen return info;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen}
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen