doveadm-print.c revision 09304bdc1e5e416aa343802732a15064f49495cc
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "lib.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "array.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "doveadm-print-private.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include <stdio.h>
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstruct doveadm_print_header_context {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *key;
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen char *sticky_value;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch bool sticky;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch};
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstruct doveadm_print_context {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool_t pool;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ARRAY_DEFINE(headers, struct doveadm_print_header_context);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const struct doveadm_print_vfuncs *v;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int header_idx;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch};
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct doveadm_print_context *ctx;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic const struct doveadm_print_vfuncs *doveadm_print_vfuncs_all[] = {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch &doveadm_print_flow_vfuncs,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch &doveadm_print_tab_vfuncs,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch &doveadm_print_table_vfuncs
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch};
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool doveadm_print_is_initialized(void)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return ctx != NULL;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_header(const char *key, const char *title,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch enum doveadm_print_header_flags flags)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct doveadm_print_header hdr;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct doveadm_print_header_context *hdr_ctx;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (title == NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch flags |= DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch memset(&hdr, 0, sizeof(hdr));
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen hdr.key = key;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr.title = title;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr.flags = flags;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->header(&hdr);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr_ctx = array_append_space(&ctx->headers);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr_ctx->key = p_strdup(ctx->pool, key);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr_ctx->sticky = (flags & DOVEADM_PRINT_HEADER_FLAG_STICKY) != 0;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_header_simple(const char *key_title)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch doveadm_print_header(key_title, key_title, 0);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print(const char *value)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const struct doveadm_print_header_context *headers;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int count;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch headers = array_get(&ctx->headers, &count);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (;;) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx->header_idx == count)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->header_idx = 0;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch else if (headers[ctx->header_idx].sticky) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->print(headers[ctx->header_idx].sticky_value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->header_idx++;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } else {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->print(value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->header_idx++;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_num(uintmax_t value)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch T_BEGIN {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch doveadm_print(dec2str(value));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } T_END;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_sticky(const char *key, const char *value)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct doveadm_print_header_context *hdr;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx == NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* command doesn't really print anything */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch array_foreach_modifiable(&ctx->headers, hdr) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (strcmp(hdr->key, key) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_free(hdr->sticky_value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch hdr->sticky_value = i_strdup(value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_unreached();
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_flush(void)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx != NULL && ctx->v->flush != NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->flush();
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch fflush(stdout);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_init(const char *name)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool_t pool;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int i;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx != NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* already forced the type */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool = pool_alloconly_create("doveadm print", 1024);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx = p_new(pool, struct doveadm_print_context, 1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->pool = pool;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch p_array_init(&ctx->headers, pool, 16);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (i = 0; i < N_ELEMENTS(doveadm_print_vfuncs_all); i++) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (strcmp(doveadm_print_vfuncs_all[i]->name, name) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v = doveadm_print_vfuncs_all[i];
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx->v == NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_fatal("Unknown print formatter: %s", name);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx->v->init != NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->init();
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid doveadm_print_deinit(void)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct doveadm_print_header_context *hdr;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx == NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (ctx->v->flush != NULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->flush();
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->v->deinit();
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch array_foreach_modifiable(&ctx->headers, hdr)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_free(hdr->sticky_value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool_unref(&ctx->pool);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx = NULL;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch