cmd-status.c revision 4525c4a8f8d1a6365e4469c0c8f46575400a9a67
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (C) 2002 Timo Sirainen */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen#include "common.h"
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen#include "str.h"
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen#include "commands.h"
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen/* Returns status items, or -1 if error */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainenstatic MailboxStatusItems get_status_items(Client *client, ImapArg *args)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen{
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen const char *item;
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi MailboxStatusItems items;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items = 0;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen for (; args->type != IMAP_ARG_EOL; args++) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (args->type != IMAP_ARG_ATOM) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* list may contain only atoms */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen client_send_command_error(client,
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen "Status list contains non-atoms.");
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch return -1;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen item = str_ucase(IMAP_ARG_STR(args));
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (strcmp(item, "MESSAGES") == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items |= STATUS_MESSAGES;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen else if (strcmp(item, "RECENT") == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items |= STATUS_RECENT;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen else if (strcmp(item, "UIDNEXT") == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items |= STATUS_UIDNEXT;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen else if (strcmp(item, "UIDVALIDITY") == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items |= STATUS_UIDVALIDITY;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen else if (strcmp(item, "UNSEEN") == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items |= STATUS_UNSEEN;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen else {
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen client_send_tagline(client, t_strconcat(
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen "BAD Invalid status item ", item, NULL));
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return -1;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return items;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen}
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainenstatic int mailbox_name_equals(const char *box1, const char *box2)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen{
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (strcmp(box1, box2) == 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return TRUE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return strcasecmp(box1, "INBOX") == 0 && strcasecmp(box2, "INBOX") == 0;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen}
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomistatic int get_mailbox_status(Client *client, const char *mailbox,
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi MailboxStatusItems items, MailboxStatus *status)
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi{
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi Mailbox *box;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen int failed;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (client->mailbox != NULL &&
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen mailbox_name_equals(client->mailbox->name, mailbox)) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* this mailbox is selected */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen box = client->mailbox;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen } else {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* open the mailbox */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen box = client->storage->open_mailbox(client->storage,
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen mailbox, FALSE, TRUE);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (box == NULL)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return FALSE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen failed = !box->get_status(box, items, status);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (box != client->mailbox)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen box->close(box);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen return !failed;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen}
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainenint cmd_status(Client *client)
9644b7914445f0fb1098038218bfcb7d135a8698Timo Sirainen{
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen ImapArg *args;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen MailboxStatus status;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen MailboxStatusItems items;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen const char *mailbox;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen String *str;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* <mailbox> <status items> */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (!client_read_args(client, 2, 0, &args))
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return FALSE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen mailbox = imap_arg_string(&args[0]);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (mailbox == NULL || args[1].type != IMAP_ARG_LIST) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen client_send_command_error(client, "Status items must be list.");
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return TRUE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* get the items client wants */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen items = get_status_items(client, IMAP_ARG_LIST(&args[1])->args);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items == (MailboxStatusItems)-1) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* error */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return TRUE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen /* get status */
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (!get_mailbox_status(client, mailbox, items, &status)) {
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen client_send_storage_error(client);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return TRUE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen }
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str = t_str_new(128);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "* STATUS %s (", mailbox);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items & STATUS_MESSAGES)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "MESSAGES %u ", status.messages);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items & STATUS_RECENT)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "RECENT %u ", status.recent);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items & STATUS_UIDNEXT)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "UIDNEXT %u ", status.uidnext);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items & STATUS_UIDVALIDITY)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "UIDVALIDITY %u ", status.uidvalidity);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items & STATUS_UNSEEN)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_printfa(str, "UNSEEN %u ", status.unseen);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen if (items != 0)
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_truncate(str, str_len(str)-1);
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen str_append_c(str, ')');
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen client_send_line(client, str_c(str));
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen client_send_tagline(client, "OK Status completed.");
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen return TRUE;
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen}
7a896d960824c93e2f04ac21e8eae0f892bf8d20Timo Sirainen