/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "array.h"
#include "str.h"
#include "strescape.h"
#include "mailbox-list-iter.h"
#include "imap-utf7.h"
#include "imap-quote.h"
#include "imap-match.h"
#include "imap-status.h"
#include "imap-commands.h"
#include "imap-list.h"
struct cmd_list_context {
};
static void
{
flags &= ~MAILBOX_NONEXISTENT;
}
if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 &&
/* LSUB uses \Noselect for this */
flags &= ~MAILBOX_SUBSCRIBED;
special_use != NULL) {
}
}
static void
enum mailbox_info_flags flags)
{
if (!ctx->used_listext)
return;
if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 &&
if ((flags & MAILBOX_CHILD_SPECIALUSE) != 0 &&
}
static bool
{
const char *str;
while (!IMAP_ARG_IS_EOL(args)) {
"List options contains non-atoms.");
return FALSE;
}
/* not supported, ignore */
} else {
/* skip also optional list value */
"Unknown select options");
return FALSE;
}
args++;
}
if ((list_flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0 &&
MAILBOX_LIST_ITER_SELECT_SPECIALUSE)) == 0) {
"RECURSIVEMATCH must not be the only selection.");
return FALSE;
}
return TRUE;
}
static bool
{
const char *str;
while (!IMAP_ARG_IS_EOL(args)) {
"List options contains non-atoms.");
return FALSE;
}
&ctx->status_items) < 0)
return FALSE;
args++;
} else {
/* skip also optional list value */
"Unknown return options");
return FALSE;
}
args++;
}
return TRUE;
}
{
return "";
}
{
if (sep == '\\')
else
}
static void
{
/* doesn't exist, don't even try to get STATUS */
return;
}
if ((flags & MAILBOX_SUBSCRIBED) == 0 &&
(flags & MAILBOX_CHILD_SUBSCRIBED) != 0) {
/* listing subscriptions, but only child is subscribed */
return;
}
/* if we're listing subscriptions and there are subscriptions=no
namespaces, ctx->ns may not point to correct one */
return;
}
}
{
const char *name;
int ret = 0;
return TRUE;
}
if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 &&
(flags & MAILBOX_SUBSCRIBED) == 0 &&
/* mask doesn't end with %. we don't want to show
any extra mailboxes. */
continue;
}
str_truncate(mutf7_name, 0);
str_truncate(str, 0);
} T_END;
if (ret == 0) {
/* buffer is full, continue later */
return FALSE;
}
}
return TRUE;
}
"OK List completed." :
"OK Lsub completed.");
return TRUE;
}
static const char *const *
const char *const *patterns)
{
ARRAY(const char *) full_patterns;
if (*ref == '\0')
return patterns;
}
return array_idx(&full_patterns, 0);
}
const char *const *patterns)
{
ctx->list_flags);
}
{
const char *ns_prefix;
char ns_sep;
/* Special request to return the hierarchy delimiter and mailbox root
name. If namespace has a prefix, it's returned as the mailbox root.
Otherwise we'll emulate UW-IMAP behavior. */
} else {
ns_prefix = "";
}
if (*ns_prefix != '\0') {
/* non-hidden namespace, use it as the root name */
} else {
/* Hidden namespace or empty namespace prefix. We could just
return an empty root name, but it's safer to emulate what
UW-IMAP does. With full filesystem access this might even
if (p == NULL)
else
}
}
{
unsigned int arg_count;
/* [(<selection options>)] <reference> <pattern>|(<pattern list>)
[RETURN (<return options>)] */
return FALSE;
/* LIST-EXTENDED selection options */
return TRUE;
args++;
}
return TRUE;
}
str_truncate(str, 0);
/* convert pattern list to string array */
"Invalid pattern list.");
return TRUE;
}
str_truncate(str, 0);
}
args += 2;
} else {
return TRUE;
}
args += 2;
if (lsub) {
}
}
/* LIST-EXTENDED return options */
return TRUE;
args += 2;
}
if (lsub) {
/* LSUB - we don't care about flags except if
tb-lsub-flags workaround is explicitly set */
/* Return SPECIAL-USE flags for LSUB anyway. Outlook 2013
does this and since it's not expensive for us to return
them, it's not worth the trouble of adding an explicit
workaround setting. */
WORKAROUND_TB_LSUB_FLAGS) == 0)
} else if (!ctx->used_listext) {
/* non-extended LIST: use default flags */
}
if (!IMAP_ARG_IS_EOL(args)) {
return TRUE;
}
/* Only LIST ref "" gets us here */
} else {
if (!cmd_list_continue(cmd)) {
/* unfinished */
return FALSE;
}
return TRUE;
}
return TRUE;
}
{
}