doveadm-mail-mailbox-status.c revision d6e8c83d08991f05f9cd4064bca5c76854d68657
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "lib.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "str.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "mail-namespace.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "mail-storage.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "doveadm-print.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "doveadm-mail.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "doveadm-mailbox-list-iter.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define ALL_STATUS_ITEMS \
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (STATUS_MESSAGES | STATUS_RECENT | \
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen STATUS_UIDNEXT | STATUS_UIDVALIDITY | \
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen STATUS_UNSEEN | STATUS_HIGHESTMODSEQ)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define ALL_METADATA_ITEMS \
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen (MAILBOX_METADATA_VIRTUAL_SIZE | MAILBOX_METADATA_GUID)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define TOTAL_STATUS_ITEMS \
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen (STATUS_MESSAGES | STATUS_RECENT | STATUS_UNSEEN)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define TOTAL_METADATA_ITEMS \
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen (MAILBOX_METADATA_VIRTUAL_SIZE)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstruct status_cmd_context {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct doveadm_mail_cmd_context ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mail_search_args *search_args;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen enum mailbox_status_items status_items;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen enum mailbox_metadata_items metadata_items;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_status total_status;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen struct mailbox_metadata total_metadata;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen unsigned int total_sum:1;
737561538a2dcdcda948a1da2830a612d8263a23Timo Sirainen};
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic void status_parse_fields(struct status_cmd_context *ctx,
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen const char *const *fields)
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen{
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen if (*fields == NULL)
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen i_fatal_status(EX_USAGE, "No status fields");
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen for (; *fields != NULL; fields++) {
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen const char *field = *fields;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen if (strcmp(field, "all") == 0) {
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen if (ctx->total_sum) {
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen ctx->status_items |= TOTAL_STATUS_ITEMS;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen ctx->metadata_items |= TOTAL_METADATA_ITEMS;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen } else {
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen ctx->status_items |= ALL_STATUS_ITEMS;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen ctx->metadata_items |= ALL_METADATA_ITEMS;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen } else if (strcmp(field, "messages") == 0)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen ctx->status_items |= STATUS_MESSAGES;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen else if (strcmp(field, "recent") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->status_items |= STATUS_RECENT;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(field, "uidnext") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->status_items |= STATUS_UIDNEXT;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(field, "uidvalidity") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->status_items |= STATUS_UIDVALIDITY;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(field, "unseen") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->status_items |= STATUS_UNSEEN;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(field, "highestmodseq") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->status_items |= STATUS_HIGHESTMODSEQ;
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen else if (strcmp(field, "vsize") == 0)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen ctx->metadata_items |= MAILBOX_METADATA_VIRTUAL_SIZE;
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen else if (strcmp(field, "guid") == 0)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen ctx->metadata_items |= MAILBOX_METADATA_GUID;
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen else {
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen i_fatal_status(EX_USAGE,
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen "Unknown status field: %s", field);
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen }
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen if (ctx->total_sum &&
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen ((ctx->status_items & ~TOTAL_STATUS_ITEMS) != 0 ||
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen (ctx->metadata_items & ~TOTAL_METADATA_ITEMS) != 0)) {
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen i_fatal_status(EX_USAGE,
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen "Status field %s can't be used with -t", field);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen}
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainenstatic void status_output(struct status_cmd_context *ctx, struct mailbox *box,
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen const struct mailbox_status *status,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen const struct mailbox_metadata *metadata)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (box != NULL)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print(mailbox_get_vname(box));
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if ((ctx->status_items & STATUS_MESSAGES) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->messages);
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen if ((ctx->status_items & STATUS_RECENT) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->recent);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if ((ctx->status_items & STATUS_UIDNEXT) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->uidnext);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if ((ctx->status_items & STATUS_UIDVALIDITY) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->uidvalidity);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((ctx->status_items & STATUS_UNSEEN) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->unseen);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_num(status->highest_modseq);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_print_num(metadata->virtual_size);
737561538a2dcdcda948a1da2830a612d8263a23Timo Sirainen if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_print(guid_128_to_string(metadata->guid));
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic void
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatus_sum(struct status_cmd_context *ctx,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const struct mailbox_status *status,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen const struct mailbox_metadata *metadata)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mailbox_status *dest = &ctx->total_status;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen dest->messages += status->messages;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen dest->recent += status->recent;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen dest->unseen += status->unseen;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->total_metadata.virtual_size += metadata->virtual_size;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic int
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatus_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox *box;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mailbox_status status;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mailbox_metadata metadata;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, info->name);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mailbox_get_status(box, ctx->status_items, &status) < 0 ||
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_free(&box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return -1;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (!ctx->total_sum)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen status_output(ctx, box, &status, &metadata);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen status_sum(ctx, &status, &metadata);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen mailbox_free(&box);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen return 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic int
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainencmd_mailbox_status_run(struct doveadm_mail_cmd_context *_ctx,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mail_user *user)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct status_cmd_context *ctx = (struct status_cmd_context *)_ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen enum mailbox_list_iter_flags iter_flags =
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen MAILBOX_LIST_ITER_RAW_LIST |
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct doveadm_mailbox_list_iter *iter;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen const struct mailbox_info *info;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen int ret = 0;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen memset(&ctx->total_status, 0, sizeof(ctx->total_status));
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen iter = doveadm_mailbox_list_iter_init(_ctx, user, ctx->search_args,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen iter_flags);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen T_BEGIN {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (status_mailbox(ctx, info) < 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ret = -1;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen } T_END;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ret = -1;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (ctx->total_sum) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen status_output(ctx, NULL, &ctx->total_status,
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen &ctx->total_metadata);
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen }
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen return ret;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen}
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic void cmd_mailbox_status_init(struct doveadm_mail_cmd_context *_ctx,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen const char *const args[])
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct status_cmd_context *ctx = (struct status_cmd_context *)_ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *fields = args[0];
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (fields == NULL || args[1] == NULL)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_mail_help_name("mailbox status");
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen status_parse_fields(ctx, t_strsplit_spaces(fields, " "));
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->search_args = doveadm_mail_mailbox_search_args_build(args+1);
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (!ctx->total_sum) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen doveadm_print_header("mailbox", "mailbox",
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if ((ctx->status_items & STATUS_MESSAGES) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_print_header_simple("messages");
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((ctx->status_items & STATUS_RECENT) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_print_header_simple("recent");
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen if ((ctx->status_items & STATUS_UIDNEXT) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_print_header_simple("uidnext");
if ((ctx->status_items & STATUS_UIDVALIDITY) != 0)
doveadm_print_header_simple("uidvalidity");
if ((ctx->status_items & STATUS_UNSEEN) != 0)
doveadm_print_header_simple("unseen");
if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0)
doveadm_print_header_simple("highestmodseq");
if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0)
doveadm_print_header_simple("vsize");
if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0)
doveadm_print_header_simple("guid");
}
static bool
cmd_mailbox_status_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
{
struct status_cmd_context *ctx = (struct status_cmd_context *)_ctx;
switch (c) {
case 't':
ctx->total_sum = TRUE;
break;
default:
return FALSE;
}
return TRUE;
}
static struct doveadm_mail_cmd_context *cmd_mailbox_status_alloc(void)
{
struct status_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct status_cmd_context);
ctx->ctx.getopt_args = "t";
ctx->ctx.v.parse_arg = cmd_mailbox_status_parse_arg;
ctx->ctx.v.init = cmd_mailbox_status_init;
ctx->ctx.v.run = cmd_mailbox_status_run;
doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
return &ctx->ctx;
}
struct doveadm_mail_cmd cmd_mailbox_status = {
cmd_mailbox_status_alloc, "mailbox status",
"[-t] <fields> <mailbox mask> [...]"
};