cmd-list.c revision 6c462846d78e139fccfefb7c6ae0d3077b525c2d
/* Copyright (C) 2002-2004 Timo Sirainen */
#include "common.h"
#include "str.h"
#include "strescape.h"
#include "imap-quote.h"
#include "imap-match.h"
#include "commands.h"
#include "namespace.h"
enum {
_MAILBOX_LIST_HIDE_CHILDREN = 0x1000000,
_MAILBOX_LIST_LISTEXT = 0x0800000
};
struct cmd_list_context {
const char *ref;
const char *mask;
enum mailbox_list_flags list_flags;
struct mailbox_list_context *list_ctx;
struct imap_match_glob *glob;
unsigned int lsub:1;
unsigned int inbox_found:1;
unsigned int match_inbox:1;
};
static const char *
{
const char *str;
if (flags & MAILBOX_PLACEHOLDER) {
if ((list_flags & _MAILBOX_LIST_LISTEXT) == 0)
}
if ((flags & MAILBOX_NONEXISTENT) != 0 &&
(list_flags & _MAILBOX_LIST_LISTEXT) == 0) {
flags &= ~MAILBOX_NONEXISTENT;
}
if ((list_flags & _MAILBOX_LIST_HIDE_CHILDREN) != 0)
str = t_strconcat(
NULL);
}
static bool
enum mailbox_list_flags *list_flags)
{
const char *atom;
"List options contains non-atoms.");
return FALSE;
}
else {
return FALSE;
}
args++;
}
return TRUE;
}
static void
{
const char *str;
/* INBOX always exists */
}
}
static int
{
struct mailbox_list *list;
const char *name;
int ret;
return 1;
}
t_push();
str_truncate(name_str, 0);
/* when listing INBOX from inbox=yes namespace, don't insert
the namespace prefix */
char *p = str_c_modifiable(name_str);
for (; *p != '\0'; p++) {
}
}
/* With masks containing '*' we do the checks here
so prefix is included in matching */
continue;
}
continue;
name = "INBOX";
}
str_truncate(str, 0);
/* buffer is full, continue later */
t_pop();
return 0;
}
}
t_pop();
}
static bool list_mask_has_wildcards(const char *mask)
{
return TRUE;
}
return FALSE;
}
static void
bool inbox_check, char sep)
{
bool match;
if (mask_len < prefix_len) {
/* eg. namespace prefix = "INBOX.", mask = "INBOX" */
return;
}
if (!match && inbox_check) {
/* try INBOX check. */
}
if (match) {
*prefix += prefix_len;
*mask += prefix_len;
}
}
static void
struct cmd_list_context *ctx)
{
enum imap_match_result match;
enum mailbox_list_flags list_flags;
enum imap_match_result inbox_match;
struct imap_match_glob *inbox_glob;
unsigned int count;
/* reference argument given. skip namespace prefix using it.
cur_ref = foo/
-> cur_ns_prefix=bar/, cur_ref=""
-> cur_ns_prefix="", cur_ref="baz"
*/
/* reference parameter didn't match with
namespace prefix. skip this. */
return;
}
}
if (*cur_ns_prefix != '\0') {
/* no reference parameter. skip namespace prefix from mask. */
const char *old_ns_prefix = cur_ns_prefix;
/* trying to list the namespace prefix itself. */
}
}
/* if the original reference and mask combined produces something
that matches INBOX, the INBOX casing is on. */
(inbox_match == IMAP_MATCH_YES ||
inbox_match == IMAP_MATCH_PARENT) &&
if (*cur_ns_prefix != '\0') {
/* namespace prefix still wasn't completely skipped over.
for example cur_ns_prefix=INBOX/, mask=%/% or mask=IN%.
Check that mask matches namespace prefix. */
bool skip_trailing_sep = FALSE;
/* drop the trailing separator in namespace prefix.
don't do it if we're listing only the prefix itself. */
}
/* hidden namespaces should still be seen without wildcards.
some clients rely on this. */
if (match < 0)
return;
if (match == IMAP_MATCH_YES &&
/* The prefix itself matches */
enum mailbox_flags flags;
FALSE);
}
}
if (*cur_ns_prefix != '\0') {
/* We didn't skip over the whole namespace prefix. For example
cur_ns_prefix=INBOX/ and mask=%/% or IN*.
We have already verified that the mask matches the namespace
prefix, so we'll just have to skip over as many hierarchies
from mask as there exists in namespace prefix.
The "INBOX" namespace match reply was already sent. We're
only listing the actual mailboxes now. */
count++;
}
/* skip over one hierarchy */
cur_mask++;
if (*cur_mask == '*') {
/* we'll just request "*" and filter it
ourself. otherwise this gets too complex. */
cur_mask = "*";
break;
}
if (*cur_mask == '\0') {
/* mask ended too early. we won't be listing
any mailboxes. */
break;
}
cur_mask++;
}
}
/* a) we don't have '*' in mask
b) we want to display everything
we don't need to do separate filtering ourself */
}
}
{
int ret;
return TRUE;
}
if (ret == 0)
return FALSE;
}
"OK List completed." :
"OK Lsub completed.");
return TRUE;
}
{
enum mailbox_list_flags list_flags;
struct cmd_list_context *ctx;
/* [(<options>)] <reference> <mailbox wildcards> */
return FALSE;
if (lsub) {
/* LSUB - we don't care about flags */
/* LIST - allow children flags, but don't require them */
list_flags = 0;
} else {
&list_flags))
return TRUE;
args++;
/* don't show children flags unless explicitly specified */
if ((list_flags & MAILBOX_LIST_CHILDREN) == 0)
}
return TRUE;
}
/* special request to return the hierarchy delimiter and
mailbox root name. Mailbox root name is somewhat strange
concept which probably no other client uses than Pine.
Just try our best to emulate UW-IMAP behavior and hopefully
we're fine. */
const char *empty = "";
}
/* public namespace, use it as the root name */
FALSE);
} else {
/* private namespace, or empty namespace
prefix. use the mailbox name's first part
as the root. */
if (p == NULL)
else {
FALSE);
}
}
}
} else {
if (!cmd_list_continue(cmd)) {
/* unfinished */
return FALSE;
}
return TRUE;
}
return TRUE;
}
{
}