doveadm-mail-mailbox-metadata.c revision 9384ef699a57687ce6dbdae7d686181f4791b1e5
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2014-2017 Dovecot authors, see the included COPYING file */
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen#include "lib.h"
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen#include "str.h"
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen#include "mail-namespace.h"
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen#include "mail-storage.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "doveadm-print.h"
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen#include "doveadm-mail.h"
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen#include "doveadm-mailbox-list-iter.h"
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainenstruct metadata_cmd_context {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen struct doveadm_mail_cmd_context ctx;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen const char *mailbox;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen enum mail_attribute_type key_type;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen const char *key;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen struct mail_attribute_value value;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen bool empty_mailbox_name;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen bool allow_empty_mailbox_name;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen};
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainenstatic int
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainencmd_mailbox_metadata_open_mailbox(struct metadata_cmd_context *mctx,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct mail_user *user,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen const char *op,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct mail_namespace **ns_r,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct mailbox **box_r)
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen{
a96307ca3944c434f2c50f47c12985bcd34445b5Timo Sirainen mctx->empty_mailbox_name = mctx->mailbox[0] == '\0';
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen
a96307ca3944c434f2c50f47c12985bcd34445b5Timo Sirainen if (mctx->empty_mailbox_name) {
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen if (!mctx->allow_empty_mailbox_name) {
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen i_error("Failed to %s: %s", op,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen "mailbox name cannot be empty");
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen mctx->ctx.exit_code = EX_USAGE;
b710c5119d3b66572eb87a15ac6d8dcd192f7cc5Timo Sirainen return -1;
b710c5119d3b66572eb87a15ac6d8dcd192f7cc5Timo Sirainen }
b710c5119d3b66572eb87a15ac6d8dcd192f7cc5Timo Sirainen
b710c5119d3b66572eb87a15ac6d8dcd192f7cc5Timo Sirainen /* server attribute */
b710c5119d3b66572eb87a15ac6d8dcd192f7cc5Timo Sirainen *ns_r = mail_namespace_find_inbox(user->namespaces);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *box_r = mailbox_alloc((*ns_r)->list, "INBOX", 0);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mctx->key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mctx->key, NULL);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen } else {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen /* mailbox attributes */
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *ns_r = mail_namespace_find(user->namespaces, mctx->mailbox);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *box_r = mailbox_alloc((*ns_r)->list, mctx->mailbox, 0);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen }
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (mailbox_open(*box_r) < 0) {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_error("Failed to open mailbox: %s",
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mailbox_get_last_error(*box_r, NULL));
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen doveadm_mail_failed_mailbox(&mctx->ctx, *box_r);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mailbox_free(box_r);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen return -1;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen }
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen return 0;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen}
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic int
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainencmd_mailbox_metadata_set_run(struct doveadm_mail_cmd_context *_ctx,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen struct mail_user *user)
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen{
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
a96307ca3944c434f2c50f47c12985bcd34445b5Timo Sirainen struct mail_namespace *ns;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct mailbox *box;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct mailbox_transaction_context *trans;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen int ret;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen ret = cmd_mailbox_metadata_open_mailbox(ctx, user, "set attribute",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen &ns, &box);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen if (ret != 0)
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen return ret;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen trans = mailbox_transaction_begin(box, ctx->empty_mailbox_name ?
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen MAILBOX_TRANSACTION_FLAG_EXTERNAL : 0);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen ret = ctx->value.value == NULL ?
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mailbox_attribute_unset(trans, ctx->key_type, ctx->key) :
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mailbox_attribute_set(trans, ctx->key_type, ctx->key, &ctx->value);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen if (ret < 0) {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_error("Failed to set attribute: %s",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mailbox_get_last_error(box, NULL));
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen doveadm_mail_failed_mailbox(_ctx, box);
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen mailbox_transaction_rollback(&trans);
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen } else if (mailbox_transaction_commit(&trans) < 0) {
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen i_error("Failed to commit transaction: %s",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mailbox_get_last_error(box, NULL));
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen doveadm_mail_failed_mailbox(_ctx, box);
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen ret = -1;
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen }
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen mailbox_free(&box);
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen return ret;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen}
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainenstatic void
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainencmd_mailbox_metadata_parse_key(const char *arg,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen enum mail_attribute_type *type_r,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen const char **key_r)
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen{
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen arg = t_str_lcase(arg);
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen if (strncmp(arg, "/private/", 9) == 0) {
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen *type_r = MAIL_ATTRIBUTE_TYPE_PRIVATE;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *key_r = arg + 9;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen } else if (strncmp(arg, "/shared/", 8) == 0) {
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen *type_r = MAIL_ATTRIBUTE_TYPE_SHARED;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen *key_r = arg + 8;
53b32ab10cd22d7e762db4d813298ff72bff4b3dTimo Sirainen } else if (strcmp(arg, "/private") == 0) {
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen *type_r = MAIL_ATTRIBUTE_TYPE_PRIVATE;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *key_r = "";
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen } else if (strcmp(arg, "/shared") == 0) {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *type_r = MAIL_ATTRIBUTE_TYPE_SHARED;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen *key_r = "";
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen } else {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_fatal_status(EX_USAGE, "Invalid metadata key '%s': "
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen "Must begin with /private or /shared", arg);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen }
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen}
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenstatic void
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainencmd_mailbox_metadata_set_init(struct doveadm_mail_cmd_context *_ctx,
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen const char *const args[])
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen{
6f9560d31a6fffeed234dc3b841169c40db1c5e1Timo Sirainen struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen const char *key;
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen if (str_array_length(args) != 3)
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen doveadm_mail_help_name("mailbox metadata set");
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key);
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen ctx->mailbox = p_strdup(_ctx->pool, args[0]);
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen ctx->key = p_strdup(_ctx->pool, key);
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen ctx->value.value = p_strdup(_ctx->pool, args[2]);
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen}
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainenstatic bool
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainencmd_mailbox_metadata_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen{
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen struct metadata_cmd_context *ctx =
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen (struct metadata_cmd_context *)_ctx;
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen switch (c) {
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen case 's':
766814de3fbfeb8ca7c4d6b592f6ca09f14d5690Timo Sirainen ctx->allow_empty_mailbox_name = TRUE;
break;
default:
return FALSE;
}
return TRUE;
}
static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_set_alloc(void)
{
struct metadata_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context);
ctx->ctx.v.init = cmd_mailbox_metadata_set_init;
ctx->ctx.v.parse_arg = cmd_mailbox_metadata_parse_arg;
ctx->ctx.v.run = cmd_mailbox_metadata_set_run;
return &ctx->ctx;
}
static void
cmd_mailbox_metadata_unset_init(struct doveadm_mail_cmd_context *_ctx,
const char *const args[])
{
struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
const char *key;
if (str_array_length(args) != 2)
doveadm_mail_help_name("mailbox metadata unset");
cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key);
ctx->mailbox = p_strdup(_ctx->pool, args[0]);
ctx->key = p_strdup(_ctx->pool, key);
}
static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_unset_alloc(void)
{
struct metadata_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context);
ctx->ctx.v.init = cmd_mailbox_metadata_unset_init;
ctx->ctx.v.parse_arg = cmd_mailbox_metadata_parse_arg;
ctx->ctx.v.run = cmd_mailbox_metadata_set_run;
return &ctx->ctx;
}
static int
cmd_mailbox_metadata_get_run(struct doveadm_mail_cmd_context *_ctx,
struct mail_user *user)
{
struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
struct mail_namespace *ns;
struct mailbox *box;
struct mail_attribute_value value;
int ret;
ret = cmd_mailbox_metadata_open_mailbox(ctx, user, "get attribute",
&ns, &box);
if (ret != 0)
return ret;
ret = mailbox_attribute_get_stream(box, ctx->key_type, ctx->key, &value);
if (ret < 0) {
i_error("Failed to get attribute: %s",
mailbox_get_last_error(box, NULL));
doveadm_mail_failed_mailbox(_ctx, box);
} else if (ret == 0) {
/* not found, print as empty */
doveadm_print("");
} else if (value.value_stream != NULL) {
doveadm_print_istream(value.value_stream);
} else {
doveadm_print(value.value);
}
mailbox_free(&box);
return ret;
}
static void
cmd_mailbox_metadata_get_init(struct doveadm_mail_cmd_context *_ctx,
const char *const args[])
{
struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
const char *key;
if (str_array_length(args) != 2)
doveadm_mail_help_name("mailbox metadata get");
cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key);
ctx->mailbox = p_strdup(_ctx->pool, args[0]);
ctx->key = p_strdup(_ctx->pool, key);
doveadm_print_header("value", "value",
DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
}
static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_get_alloc(void)
{
struct metadata_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context);
ctx->ctx.v.init = cmd_mailbox_metadata_get_init;
ctx->ctx.v.parse_arg = cmd_mailbox_metadata_parse_arg;
ctx->ctx.v.run = cmd_mailbox_metadata_get_run;
doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
return &ctx->ctx;
}
static int
cmd_mailbox_metadata_list_run_iter(struct metadata_cmd_context *ctx,
struct mailbox *box,
enum mail_attribute_type type)
{
struct mailbox_attribute_iter *iter;
const char *key;
iter = mailbox_attribute_iter_init(box, type, ctx->key);
while ((key = mailbox_attribute_iter_next(iter)) != NULL)
doveadm_print(key);
if (mailbox_attribute_iter_deinit(&iter) < 0) {
i_error("Mailbox %s: Failed to iterate mailbox attributes: %s",
mailbox_get_vname(box),
mailbox_get_last_error(box, NULL));
return -1;
}
return 0;
}
static int
cmd_mailbox_metadata_list_run(struct doveadm_mail_cmd_context *_ctx,
struct mail_user *user)
{
struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
struct mail_namespace *ns;
struct mailbox *box;
int ret = 0;
ret = cmd_mailbox_metadata_open_mailbox(ctx, user, "list attributes",
&ns, &box);
if (ret != 0)
return ret;
if (ctx->key[0] == '\0' || ctx->key_type == MAIL_ATTRIBUTE_TYPE_PRIVATE) {
if (cmd_mailbox_metadata_list_run_iter(ctx, box, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0) {
doveadm_mail_failed_mailbox(_ctx, box);
ret = -1;
}
}
if (ctx->key[0] == '\0' || ctx->key_type == MAIL_ATTRIBUTE_TYPE_SHARED) {
if (cmd_mailbox_metadata_list_run_iter(ctx, box, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) {
doveadm_mail_failed_mailbox(_ctx, box);
ret = -1;
}
}
mailbox_free(&box);
return ret;
}
static void
cmd_mailbox_metadata_list_init(struct doveadm_mail_cmd_context *_ctx,
const char *const args[])
{
struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
const char *key = NULL;
if (args[0] == NULL)
doveadm_mail_help_name("mailbox metadata list");
if (args[1] != NULL)
cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key);
ctx->mailbox = p_strdup(_ctx->pool, args[0]);
ctx->key = key == NULL ? "" : p_strdup(_ctx->pool, key);
doveadm_print_header("key", "key",
DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
}
static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_list_alloc(void)
{
struct metadata_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct metadata_cmd_context);
ctx->ctx.v.init = cmd_mailbox_metadata_list_init;
ctx->ctx.v.parse_arg = cmd_mailbox_metadata_parse_arg;
ctx->ctx.v.run = cmd_mailbox_metadata_list_run;
doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
return &ctx->ctx;
}
struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_set_ver2 = {
.name = "mailbox metadata set",
.mail_cmd = cmd_mailbox_metadata_set_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key> <value>",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAM('\0', "value", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};
struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_unset_ver2 = {
.name = "mailbox metadata unset",
.mail_cmd = cmd_mailbox_metadata_unset_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key>",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};
struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_get_ver2 = {
.name = "mailbox metadata get",
.mail_cmd = cmd_mailbox_metadata_get_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key>",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};
struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_list_ver2 = {
.name = "mailbox metadata list",
.mail_cmd = cmd_mailbox_metadata_list_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> [<key prefix>]",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAM('\0', "key-prefix", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};