i_zero(&items);
if (client_has_enabled(client, imap_feature_condstore))
- items.status |= STATUS_HIGHESTMODSEQ;
+ items.flags |= IMAP_STATUS_ITEM_HIGHESTMODSEQ;
box = mailbox_alloc(notify_ns->ns->list, rec->vname, 0);
mailbox_set_reason(box, "NOTIFY STATUS");
if ((rec->events & MAILBOX_LIST_NOTIFY_UIDVALIDITY) != 0) {
- items.status |= STATUS_UIDVALIDITY | STATUS_UIDNEXT |
- STATUS_MESSAGES | STATUS_UNSEEN;
+ items.flags |= IMAP_STATUS_ITEM_UIDVALIDITY |
+ IMAP_STATUS_ITEM_UIDNEXT | IMAP_STATUS_ITEM_MESSAGES |
+ IMAP_STATUS_ITEM_UNSEEN;
}
if ((rec->events & (MAILBOX_LIST_NOTIFY_APPENDS |
MAILBOX_LIST_NOTIFY_EXPUNGES)) != 0)
- items.status |= STATUS_UIDNEXT | STATUS_MESSAGES | STATUS_UNSEEN;
+ items.flags |= IMAP_STATUS_ITEM_UIDNEXT |
+ IMAP_STATUS_ITEM_MESSAGES | IMAP_STATUS_ITEM_UNSEEN;
if ((rec->events & MAILBOX_LIST_NOTIFY_SEEN_CHANGES) != 0)
- items.status |= STATUS_UNSEEN;
+ items.flags |= IMAP_STATUS_ITEM_UNSEEN;
if ((rec->events & MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES) != 0) {
/* if HIGHESTMODSEQ isn't being sent, don't send anything */
}
- if (items.status == 0) {
+ if (imap_status_items_is_empty(&items)) {
/* don't send anything */
- } else if (mailbox_get_status(box, items.status, &result.status) < 0) {
+ } else if (imap_status_get_result(client, box, &items, &result) < 0) {
/* hide permission errors from client. we don't want to leak
information about existence of mailboxes where user doesn't
have access to */
const struct imap_arg *args,
struct imap_status_items *items_r)
{
+ enum imap_status_item_flags flags = 0;
const char *item;
- enum mailbox_status_items status = 0;
- enum mailbox_metadata_items metadata = 0;
if (IMAP_ARG_IS_EOL(args)) {
client_send_command_error(cmd, "Empty status list.");
item = t_str_ucase(item);
if (strcmp(item, "MESSAGES") == 0)
- status |= STATUS_MESSAGES;
+ flags |= IMAP_STATUS_ITEM_MESSAGES;
else if (strcmp(item, "RECENT") == 0)
- status |= STATUS_RECENT;
+ flags |= IMAP_STATUS_ITEM_RECENT;
else if (strcmp(item, "UIDNEXT") == 0)
- status |= STATUS_UIDNEXT;
+ flags |= IMAP_STATUS_ITEM_UIDNEXT;
else if (strcmp(item, "UIDVALIDITY") == 0)
- status |= STATUS_UIDVALIDITY;
+ flags |= IMAP_STATUS_ITEM_UIDVALIDITY;
else if (strcmp(item, "UNSEEN") == 0)
- status |= STATUS_UNSEEN;
+ flags |= IMAP_STATUS_ITEM_UNSEEN;
else if (strcmp(item, "HIGHESTMODSEQ") == 0)
- status |= STATUS_HIGHESTMODSEQ;
+ flags |= IMAP_STATUS_ITEM_HIGHESTMODSEQ;
else if (strcmp(item, "X-SIZE") == 0)
- metadata |= MAILBOX_METADATA_VIRTUAL_SIZE;
+ flags |= IMAP_STATUS_ITEM_X_SIZE;
else if (strcmp(item, "X-GUID") == 0)
- metadata |= MAILBOX_METADATA_GUID;
+ flags |= IMAP_STATUS_ITEM_X_GUID;
else {
client_send_command_error(cmd, t_strconcat(
"Invalid status item ", item, NULL));
}
}
- items_r->status = status;
- items_r->metadata = metadata;
+ items_r->flags = flags;
return 0;
}
+int imap_status_get_result(struct client *client, struct mailbox *box,
+ const struct imap_status_items *items,
+ struct imap_status_result *result_r)
+{
+ enum mailbox_status_items status = 0;
+ enum mailbox_metadata_items metadata = 0;
+ int ret;
+
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_MESSAGES))
+ status |= STATUS_MESSAGES;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_RECENT))
+ status |= STATUS_RECENT;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UIDNEXT))
+ status |= STATUS_UIDNEXT;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UIDVALIDITY))
+ status |= STATUS_UIDVALIDITY;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UNSEEN))
+ status |= STATUS_UNSEEN;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_HIGHESTMODSEQ)) {
+ client_enable(client, imap_feature_condstore);
+ status |= STATUS_HIGHESTMODSEQ;
+ }
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_X_SIZE))
+ metadata |= MAILBOX_METADATA_VIRTUAL_SIZE;
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_X_GUID))
+ metadata |= MAILBOX_METADATA_GUID;
+
+ ret = mailbox_get_status(box, status, &result_r->status);
+ if (metadata != 0 && ret == 0)
+ ret = mailbox_get_metadata(box, metadata, &result_r->metadata);
+
+ return ret;
+}
+
int imap_status_get(struct client_command_context *cmd,
struct mail_namespace *ns, const char *mailbox,
const struct imap_status_items *items,
(void)mailbox_enable(box, client_enabled_mailbox_features(client));
}
- if ((items->status & STATUS_HIGHESTMODSEQ) != 0)
- client_enable(client, imap_feature_condstore);
-
- ret = mailbox_get_status(box, items->status, &result_r->status);
- if (items->metadata != 0 && ret == 0) {
- ret = mailbox_get_metadata(box, items->metadata,
- &result_r->metadata);
- }
-
+ ret = imap_status_get_result(client, box, items, result_r);
if (ret < 0) {
errstr = mailbox_get_last_error(box, &result_r->error);
result_r->errstr = imap_get_error_string(cmd, errstr,
str_append(str, " (");
prefix_len = str_len(str);
- if ((items->status & STATUS_MESSAGES) != 0)
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_MESSAGES))
str_printfa(str, "MESSAGES %u ", status->messages);
- if ((items->status & STATUS_RECENT) != 0)
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_RECENT))
str_printfa(str, "RECENT %u ", status->recent);
- if ((items->status & STATUS_UIDNEXT) != 0)
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UIDNEXT))
str_printfa(str, "UIDNEXT %u ", status->uidnext);
- if ((items->status & STATUS_UIDVALIDITY) != 0)
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UIDVALIDITY))
str_printfa(str, "UIDVALIDITY %u ", status->uidvalidity);
- if ((items->status & STATUS_UNSEEN) != 0)
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_UNSEEN))
str_printfa(str, "UNSEEN %u ", status->unseen);
- if ((items->status & STATUS_HIGHESTMODSEQ) != 0) {
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_HIGHESTMODSEQ)) {
str_printfa(str, "HIGHESTMODSEQ %"PRIu64" ",
status->highest_modseq);
}
- if ((items->metadata & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) {
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_X_SIZE)) {
str_printfa(str, "X-SIZE %"PRIu64" ",
result->metadata.virtual_size);
}
- if ((items->metadata & MAILBOX_METADATA_GUID) != 0) {
+ if (HAS_ALL_BITS(items->flags, IMAP_STATUS_ITEM_X_GUID)) {
str_printfa(str, "X-GUID %s ",
guid_128_to_string(result->metadata.guid));
}
#ifndef IMAP_STATUS_H
#define IMAP_STATUS_H
+enum imap_status_item_flags {
+ IMAP_STATUS_ITEM_MESSAGES = BIT(0),
+ IMAP_STATUS_ITEM_RECENT = BIT(1),
+ IMAP_STATUS_ITEM_UIDNEXT = BIT(2),
+ IMAP_STATUS_ITEM_UIDVALIDITY = BIT(3),
+ IMAP_STATUS_ITEM_UNSEEN = BIT(4),
+ IMAP_STATUS_ITEM_HIGHESTMODSEQ = BIT(5),
+
+ IMAP_STATUS_ITEM_X_SIZE = BIT(16),
+ IMAP_STATUS_ITEM_X_GUID = BIT(17),
+};
+
struct imap_status_items {
- enum mailbox_status_items status;
- enum mailbox_metadata_items metadata;
+ enum imap_status_item_flags flags;
};
struct imap_status_result {
const char *errstr;
};
+static inline bool
+imap_status_items_is_empty(const struct imap_status_items *items)
+{
+ return (items->flags == 0);
+}
+
int imap_status_parse_items(struct client_command_context *cmd,
const struct imap_arg *args,
struct imap_status_items *items_r);
+
+int imap_status_get_result(struct client *client, struct mailbox *box,
+ const struct imap_status_items *items,
+ struct imap_status_result *result_r);
int imap_status_get(struct client_command_context *cmd,
struct mail_namespace *ns, const char *mailbox,
const struct imap_status_items *items,
struct imap_status_result *result_r);
+
int imap_status_send(struct client *client, const char *mailbox_mutf7,
const struct imap_status_items *items,
const struct imap_status_result *result)