dovecot-1.1: LIST X-STATUS: Don't return STATUS reply for mailbo...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jun 10 20:07:17 EEST 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/0d7ea59a0dfa
changeset: 7625:0d7ea59a0dfa
user: Timo Sirainen <tss at iki.fi>
date: Tue Jun 10 20:07:13 2008 +0300
description:
LIST X-STATUS: Don't return STATUS reply for mailboxes that don't match the
LIST-EXTENDED selection criteria. Handle failures better if we can't look up
STATUS information.
diffstat:
1 file changed, 54 insertions(+), 20 deletions(-)
src/imap/cmd-list.c | 74 +++++++++++++++++++++++++++++++++++++--------------
diffs (135 lines):
diff -r 30c40c820021 -r 0d7ea59a0dfa src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Tue Jun 10 07:26:58 2008 +0300
+++ b/src/imap/cmd-list.c Tue Jun 10 20:07:13 2008 +0300
@@ -22,6 +22,7 @@ struct cmd_list_context {
ARRAY_DEFINE(ns_prefixes_listed, struct mail_namespace *);
+ unsigned int status_failed:1;
unsigned int lsub:1;
unsigned int lsub_no_unsubscribed:1;
unsigned int inbox_found:1;
@@ -151,7 +152,6 @@ parse_return_flags(struct cmd_list_conte
list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN;
else if (strcasecmp(atom, "X-STATUS") == 0 &&
args[1].type == IMAP_ARG_LIST) {
- /* FIXME: this should probably be a plugin.. */
if (imap_status_parse_items(ctx->cmd,
IMAP_ARG_LIST_ARGS(&args[1]),
&ctx->status_items) < 0)
@@ -270,33 +270,54 @@ list_namespace_send_prefix(struct cmd_li
client_send_line(ctx->cmd->client, str_c(str));
}
-static void list_send_status(struct cmd_list_context *ctx, const char *name)
-{
- struct mailbox_status status;
+static bool list_want_status_reply(struct cmd_list_context *ctx,
+ enum mailbox_info_flags flags)
+{
+ if ((flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) != 0)
+ return FALSE;
+ if ((ctx->list_flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 &&
+ (flags & MAILBOX_SUBSCRIBED) == 0)
+ return FALSE;
+ return TRUE;
+}
+
+static bool list_get_status(struct cmd_list_context *ctx, const char *name,
+ struct mailbox_status *status_r)
+{
const char *storage_name;
size_t prefix_len = strlen(ctx->ns->prefix);
+ const char *error_string;
+ enum mail_error error;
storage_name = strncmp(name, ctx->ns->prefix, prefix_len) == 0 ?
name + prefix_len : name;
- if (!imap_status_get(ctx->cmd->client, ctx->ns->storage, storage_name,
- ctx->status_items, &status)) {
- client_send_untagged_storage_error(ctx->cmd->client,
- ctx->ns->storage);
- return;
- }
-
- imap_status_send(ctx->cmd->client, name, ctx->status_items, &status);
+ if (imap_status_get(ctx->cmd->client, ctx->ns->storage, storage_name,
+ ctx->status_items, status_r))
+ return 1;
+
+ /* failed */
+ error_string = mail_storage_get_last_error(ctx->ns->storage, &error);
+ if (error == MAIL_ERROR_TEMP) {
+ client_send_line(ctx->cmd->client,
+ t_strconcat("* NO ", error_string, NULL));
+ ctx->status_failed = TRUE;
+ return -1;
+ }
+ /* treat this mailbox as \NoSelect */
+ return 0;
}
static int
list_namespace_mailboxes(struct cmd_list_context *ctx)
{
+ struct mailbox_status status;
const struct mailbox_info *info;
struct mail_namespace *ns;
enum mailbox_info_flags flags;
string_t *str, *name_str;
const char *name;
+ bool status_send;
int ret = 0;
str = t_str_new(256);
@@ -340,6 +361,18 @@ list_namespace_mailboxes(struct cmd_list
continue;
}
+ status_send = FALSE;
+ if (ctx->status_items != 0 &&
+ list_want_status_reply(ctx, flags)) T_BEGIN {
+ ret = list_get_status(ctx, name, &status);
+ if (ret > 0)
+ status_send = TRUE;
+ else if (ret == 0) {
+ /* turned into \NoSelect */
+ flags |= MAILBOX_NOSELECT;
+ }
+ } T_END;
+
str_truncate(str, 0);
str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST");
mailbox_flags2str(ctx, str, flags);
@@ -348,11 +381,9 @@ list_namespace_mailboxes(struct cmd_list
mailbox_childinfo2str(ctx, str, flags);
ret = client_send_line(ctx->cmd->client, str_c(str));
- if (ctx->status_items != 0 &&
- (flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) == 0) {
- T_BEGIN {
- list_send_status(ctx, name);
- } T_END;
+ if (status_send) {
+ imap_status_send(ctx->cmd->client, name,
+ ctx->status_items, &status);
}
if (ret == 0) {
/* buffer is full, continue later */
@@ -683,9 +714,12 @@ static bool cmd_list_continue(struct cli
list_inbox(ctx);
}
- client_send_tagline(cmd, !ctx->lsub ?
- "OK List completed." :
- "OK Lsub completed.");
+ if (ctx->lsub)
+ client_send_tagline(cmd, "OK Lsub completed.");
+ else if (!ctx->status_failed)
+ client_send_tagline(cmd, "OK List completed.");
+ else
+ client_send_tagline(cmd, "NO Some STATUS replies failed.");
return TRUE;
}
More information about the dovecot-cvs
mailing list