/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "ioloop.h"
#include "unlink-directory.h"
#include "unichar.h"
#include "imap-match.h"
#include "imap-utf7.h"
#include "mailbox-tree.h"
#include "mailbox-list-delete.h"
#include "mailbox-list-subscriptions.h"
#include "mailbox-list-maildir.h"
#include <stdio.h>
#include <dirent.h>
struct maildir_list_iterate_context {
const char *dir;
char prefix_char;
};
{
/* Fix parent nodes' children states. also if we happened to create any
of the parents, we need to mark them nonexistent. */
}
}
static void
const char *vname)
{
const char *p;
bool created;
continue;
/* don't return matches to namespace prefix itself */
continue;
}
node = update_only ?
if (created) {
/* we haven't yet seen this mailbox,
but we might see it later */
}
if (!update_only)
}
}
}
const char *vname)
{
const char *p;
char hierarchy_sep;
/* mark the first existing parent as containing children */
break;
}
}
}
static int
bool update_only)
{
bool created;
int ret;
/* always show INBOX */
} else {
/* INBOX may be Maildir root or completely elsewhere.
show it only if it has already been created */
if (ret < 0)
return -1;
if ((flags & MAILBOX_NONEXISTENT) != 0)
update_only = TRUE;
}
if (update_only) {
return 0;
}
/* add the INBOX only if it matches the patterns */
if (match == IMAP_MATCH_PARENT)
else if (match == IMAP_MATCH_YES) {
if (created)
else
}
return 0;
}
static bool
enum mailbox_list_file_type *type_r,
enum mailbox_info_flags *flags)
{
const char *path;
/* just deleted? */
*flags |= MAILBOX_NONEXISTENT;
} else {
*flags |= MAILBOX_NOSELECT;
}
return FALSE;
}
return TRUE;
} else {
*flags |= MAILBOX_NONEXISTENT;
else
*flags |= MAILBOX_NOSELECT;
return FALSE;
}
}
enum mailbox_list_file_type type,
enum mailbox_info_flags *flags_r)
{
*flags_r = 0;
switch (type) {
break;
/* need to check with stat() to be sure */
/* just assume it's a valid mailbox */
return 1;
}
return 0;
break;
}
switch (type) {
*flags_r |= MAILBOX_NOSELECT;
return 0;
}
break;
*flags_r |= MAILBOX_NOSELECT;
return 0;
}
break;
*flags_r |= MAILBOX_NOSELECT;
return 0;
i_unreached();
}
if (*fname != '\0') {
/* this tells maildir storage code that it doesn't need to
see if cur/ exists, because just the existence of .dir/
assumes that the mailbox exists. */
*flags_r |= MAILBOX_SELECT;
}
return 1;
}
const char *fname)
{
return FALSE;
/* this directory is in the middle of being deleted, or the process
trying to delete it had died. delete it ourself if it's been there
longer than one hour. */
return TRUE;
}
static int
bool update_only)
{
bool created;
int ret;
else {
return 0;
}
/* skip . and .. */
if (fname[0] == '.' &&
return 0;
if (!uni_utf8_str_is_valid(vname)) {
/* the storage_name is completely invalid, rename it to
something more sensible. we could do this for all names that
aren't valid mUTF-7, but that might lead to accidents in
future when UTF-8 storage names are used */
(void)uni_utf8_get_valid_data((const void *)fname,
/* just skip this in this iteration, we'll see it on the
next list */
return 0;
}
/* make sure the pattern matches */
return 0;
/* check if this is an actual mailbox */
return 0;
if (ret != 0)
return ret < 0 ? -1 : 0;
}
T_BEGIN {
mailbox_list_get_file_type(d), &flags);
} T_END;
if (ret <= 0)
return ret;
/* we know the children flags ourself, so ignore if any of
them were set. */
if ((match & IMAP_MATCH_PARENT) != 0)
else {
node = update_only ?
if (created)
else
if (!update_only)
} else {
}
}
return 0;
}
static int
{
struct dirent *d;
const char *vname;
int ret = 0;
return -1;
}
return 0;
}
T_BEGIN {
} T_END;
if (ret < 0)
break;
}
return -1;
}
if (ret < 0)
return -1;
/* make sure INBOX is listed */
/* show shared INBOX. */
} else {
return 0;
}
}
struct mailbox_list_iterate_context *
enum mailbox_list_iter_flags flags)
{
(struct maildir_mailbox_list *)_list;
int ret;
else
if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
/* Listing only subscribed mailboxes.
Flags are set later if needed. */
bool default_nonexistent =
(flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0;
}
if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 ||
(flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) {
bool update_only =
(flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0;
T_BEGIN {
} T_END;
if (ret < 0) {
}
}
}
{
(struct maildir_list_iterate_context *)_ctx;
return ret;
}
const struct mailbox_info *
{
(struct maildir_list_iterate_context *)_ctx;
return NULL;
return mailbox_list_iter_default_next(_ctx);
}
/* we're listing all mailboxes but we want to know
\Subscribed flags */
}
}