doveadm-dict.c revision 92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2014-2017 Dovecot authors, see the included COPYING file */
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include "lib.h"
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include "dict.h"
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include "doveadm.h"
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include "doveadm-print.h"
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include <stdio.h>
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen#include <unistd.h>
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void dict_cmd_help(doveadm_command_t *cmd);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomistatic int
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainencmd_dict_init_full(int *argc, char **argv[], int own_arg_count, int key_arg_idx,
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_command_t *cmd, enum dict_iterate_flags *iter_flags,
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi struct dict **dict_r)
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen const char *getopt_args = iter_flags == NULL ? "u:" : "1Ru:V";
20e04227229970d148801c507946666e2a9bd838Timo Sirainen struct dict_settings dict_set;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi const char *dict_uri, *error, *username = "";
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen int c;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen while ((c = getopt(*argc, *argv, getopt_args)) > 0) {
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen switch (c) {
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen case '1':
ac393b4b88ec0ce12172b240aaa39a3474ed7a7aTimo Sirainen i_assert(iter_flags != NULL);
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen *iter_flags |= DICT_ITERATE_FLAG_EXACT_KEY;
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen break;
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen case 'R':
ac393b4b88ec0ce12172b240aaa39a3474ed7a7aTimo Sirainen i_assert(iter_flags != NULL);
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen *iter_flags |= DICT_ITERATE_FLAG_RECURSE;
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen break;
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen case 'V':
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen i_assert(iter_flags != NULL);
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen *iter_flags |= DICT_ITERATE_FLAG_NO_VALUE;
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen break;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen case 'u':
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen username = optarg;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen break;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen default:
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_cmd_help(cmd);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen *argc -= optind;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen *argv += optind;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen if (*argc != 1 + own_arg_count)
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_cmd_help(cmd);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi dict_uri = (*argv)[0];
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen *argc += 1;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen *argv += 1;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen if (key_arg_idx >= 0) {
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen const char *key = (*argv)[key_arg_idx];
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen if (strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE)) != 0 &&
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) != 0) {
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi i_error("Key must begin with '"DICT_PATH_PRIVATE
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen "' or '"DICT_PATH_SHARED"': %s", key);
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_exit_code = EX_USAGE;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return -1;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen if (username[0] == '\0' &&
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE)) == 0) {
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi i_error("-u must be specified for "DICT_PATH_PRIVATE" keys");
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_exit_code = EX_USAGE;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return -1;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi dict_drivers_register_builtin();
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&dict_set);
20e04227229970d148801c507946666e2a9bd838Timo Sirainen dict_set.username = username;
20e04227229970d148801c507946666e2a9bd838Timo Sirainen dict_set.base_dir = doveadm_settings->base_dir;
20e04227229970d148801c507946666e2a9bd838Timo Sirainen if (dict_init(dict_uri, &dict_set, &dict, &error) < 0) {
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi i_error("dict_init(%s) failed: %s", dict_uri, error);
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_exit_code = EX_TEMPFAIL;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return -1;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi }
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi *dict_r = dict;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return 0;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomistatic int
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainencmd_dict_init(int *argc, char **argv[],
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen int own_arg_count, int key_arg_idx,
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_command_t *cmd, struct dict **dict_r)
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen{
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen return cmd_dict_init_full(argc, argv, own_arg_count,
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi key_arg_idx, cmd, NULL, dict_r);
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen}
8b03b93ea6e8d78e0299e32ea9a02950ce12b65bTimo Sirainen
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainenstruct doveadm_dict_ctx {
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen pool_t pool;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen int ret;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen const char *const *values;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen const char *error;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen};
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainenstatic void dict_lookup_callback(const struct dict_lookup_result *result,
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen void *context)
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen{
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen struct doveadm_dict_ctx *ctx = context;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen ctx->ret = result->ret;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen ctx->values = result->values == NULL ? NULL :
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen p_strarray_dup(ctx->pool, result->values);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen ctx->error = p_strdup(ctx->pool, result->error);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen}
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void cmd_dict_get(int argc, char *argv[])
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen struct doveadm_dict_ctx ctx;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (cmd_dict_init(&argc, &argv, 1, 0, cmd_dict_get, &dict) < 0)
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_print_header("value", "", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen i_zero(&ctx);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen ctx.pool = pool_alloconly_create("doveadm dict lookup", 512);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen ctx.ret = -2;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen dict_lookup_async(dict, argv[0], dict_lookup_callback, &ctx);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen while (ctx.ret == -2)
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen dict_wait(dict);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen if (ctx.ret < 0) {
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen i_error("dict_lookup(%s) failed: %s", argv[0], ctx.error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen } else if (ctx.ret == 0) {
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen i_error("%s doesn't exist", argv[0]);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = DOVEADM_EX_NOTFOUND;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen } else {
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen unsigned int i, values_count = str_array_length(ctx.values);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen for (i = 1; i < values_count; i++)
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen doveadm_print_header("value", "", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen for (i = 0; i < values_count; i++)
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen doveadm_print(ctx.values[i]);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
92b98c7ec5a2295ae96819e9b7b4e2be716a1fb2Timo Sirainen pool_unref(&ctx.pool);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_deinit(&dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void cmd_dict_set(int argc, char *argv[])
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict_transaction_context *trans;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen const char *error;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (cmd_dict_init(&argc, &argv, 2, 0, cmd_dict_set, &dict) < 0)
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen trans = dict_transaction_begin(dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_set(trans, argv[0], argv[1]);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen if (dict_transaction_commit(&trans, &error) <= 0) {
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_error("dict_transaction_commit() failed: %s", error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_deinit(&dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void cmd_dict_unset(int argc, char *argv[])
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict_transaction_context *trans;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen const char *error;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (cmd_dict_init(&argc, &argv, 1, 0, cmd_dict_unset, &dict) < 0)
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen trans = dict_transaction_begin(dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_unset(trans, argv[0]);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen if (dict_transaction_commit(&trans, &error) <= 0) {
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_error("dict_transaction_commit() failed: %s", error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_deinit(&dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void cmd_dict_inc(int argc, char *argv[])
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict_transaction_context *trans;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen const char *error;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen long long diff;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen int ret;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (cmd_dict_init(&argc, &argv, 2, 0, cmd_dict_inc, &dict) < 0)
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (str_to_llong(argv[1], &diff) < 0) {
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi i_error("Invalid diff: %s", argv[1]);
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi doveadm_exit_code = EX_USAGE;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi dict_deinit(&dict);
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen trans = dict_transaction_begin(dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_atomic_inc(trans, argv[0], diff);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen ret = dict_transaction_commit(&trans, &error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen if (ret < 0) {
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_error("dict_transaction_commit() failed: %s", error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen } else if (ret == 0) {
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen i_error("%s doesn't exist", argv[0]);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = DOVEADM_EX_NOTFOUND;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_deinit(&dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void cmd_dict_iter(int argc, char *argv[])
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict *dict;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen struct dict_iterate_context *iter;
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen enum dict_iterate_flags iter_flags = 0;
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen const char *key, *value, *error;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi if (cmd_dict_init_full(&argc, &argv, 1, 0, cmd_dict_iter, &iter_flags, &dict) < 0)
aea3116a9a5d4ba53ddcff460ba213d26058af81Aki Tuomi return;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_TAB);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_print_header_simple("key");
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen if ((iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen doveadm_print_header_simple("value");
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
90de1644a1c74411ec010319470b01a8b6e4f667Timo Sirainen iter = dict_iterate_init(dict, argv[0], iter_flags);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen while (dict_iterate(iter, &key, &value)) {
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_print(key);
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen if ((iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
efa1a91c5eb82e49edb00b4a194f6fc11de5641cTimo Sirainen doveadm_print(value);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen if (dict_iterate_deinit(&iter, &error) < 0) {
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen i_error("dict_iterate_deinit(%s) failed: %s", argv[0], error);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen dict_deinit(&dict);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomistatic struct doveadm_cmd_ver2 doveadm_cmd_dict[] = {
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi{
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .name = "dict get",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .old_cmd = cmd_dict_get,
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .usage = "[-u <user>] <dict uri> <key>",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_START
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "dict-uri", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_END
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi},
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi{
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .name = "dict set",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .old_cmd = cmd_dict_set,
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .usage = "[-u <user>] <dict uri> <key> <value>",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_START
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "dict-uri", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "value", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_END
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi},
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi{
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .name = "dict unset",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .old_cmd = cmd_dict_unset,
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .usage = "[-u <user>] <dict uri> <key>",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_START
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "dict-uri", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_END
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi},
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi{
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .name = "dict inc",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .old_cmd = cmd_dict_inc,
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .usage = "[-u <user>] <dict uri> <key> <diff>",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_START
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "dict-uri", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "difference", CMD_PARAM_INT64, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_END
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi},
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi{
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .name = "dict iter",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .old_cmd = cmd_dict_iter,
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi .usage = "[-u <user>] [-1RV] <dict uri> <prefix>",
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_START
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('1', "exact", CMD_PARAM_BOOL, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('R', "recurse", CMD_PARAM_BOOL, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('V', "no-value", CMD_PARAM_BOOL, 0)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "dict-uri", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAM('\0', "prefix", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki TuomiDOVEADM_CMD_PARAMS_END
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen};
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenstatic void dict_cmd_help(doveadm_command_t *cmd)
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen unsigned int i;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_dict); i++) {
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi if (doveadm_cmd_dict[i].old_cmd == cmd)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi help_ver2(&doveadm_cmd_dict[i]);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen }
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen i_unreached();
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainenvoid doveadm_register_dict_commands(void)
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen{
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen unsigned int i;
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_dict); i++)
19f03098ca92dbfbfd936059a94f37e8d077ee66Aki Tuomi doveadm_cmd_register_ver2(&doveadm_cmd_dict[i]);
26f14cde12faa09df2de399e2384fd3d955d8bb4Timo Sirainen}