Currently implemented 3 formatters: flow, tab and table.
--HG--
branch : HEAD
doveadm-mail-list-iter.c \
doveadm-mail-search.c \
doveadm-penalty.c \
+ doveadm-print.c \
+ doveadm-print-flow.c \
+ doveadm-print-tab.c \
+ doveadm-print-table.c \
doveadm-pw.c \
doveadm-settings.c \
doveadm-who.c
doveadm-mail.h \
doveadm-mail-iter.h \
doveadm-mail-list-iter.h \
+ doveadm-print.h \
+ doveadm-print-private.h \
doveadm-settings.h \
doveadm-who.h
#include "str.h"
#include "mail-namespace.h"
#include "mail-storage.h"
+#include "doveadm-print.h"
#include "doveadm-mail.h"
#include "doveadm-mail-list-iter.h"
const struct mailbox_status *status,
uint8_t mailbox_guid[MAIL_GUID_128_SIZE])
{
- string_t *str = t_str_new(128);
-
if (box != NULL)
- str_printfa(str, "%s: ", mailbox_get_vname(box));
+ doveadm_print(mailbox_get_vname(box));
if ((ctx->items & STATUS_MESSAGES) != 0)
- str_printfa(str, "messages=%u ", status->messages);
+ doveadm_print_num(status->messages);
if ((ctx->items & STATUS_RECENT) != 0)
- str_printfa(str, "recent=%u ", status->recent);
+ doveadm_print_num(status->recent);
if ((ctx->items & STATUS_UIDNEXT) != 0)
- str_printfa(str, "uidnext=%u ", status->uidnext);
+ doveadm_print_num(status->uidnext);
if ((ctx->items & STATUS_UIDVALIDITY) != 0)
- str_printfa(str, "uidvalidity=%u ", status->uidvalidity);
+ doveadm_print_num(status->uidvalidity);
if ((ctx->items & STATUS_UNSEEN) != 0)
- str_printfa(str, "unseen=%u ", status->unseen);
- if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0) {
- str_printfa(str, "highestmodseq=%llu ",
- (unsigned long long)status->highest_modseq);
- }
- if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0) {
- str_printfa(str, "vsize=%llu ",
- (unsigned long long)status->virtual_size);
- }
- if (ctx->guid) {
- str_printfa(str, "guid=%s ",
- mail_guid_128_to_string(mailbox_guid));
- }
-
- str_truncate(str, str_len(str)-1);
- dm_printf(&ctx->ctx, "%s\n", str_c(str));
+ doveadm_print_num(status->unseen);
+ if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0)
+ doveadm_print_num(status->highest_modseq);
+ if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0)
+ doveadm_print_num(status->virtual_size);
+ if (ctx->guid)
+ doveadm_print(mail_guid_128_to_string(mailbox_guid));
}
static void
status_parse_fields(ctx, t_strsplit_spaces(fields, " "));
ctx->search_args = doveadm_mail_mailbox_search_args_build(args);
+
+ if (!ctx->total_sum) {
+ doveadm_print_header("mailbox", "mailbox",
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+ }
+ if ((ctx->items & STATUS_MESSAGES) != 0)
+ doveadm_print_header_simple("messages");
+ if ((ctx->items & STATUS_RECENT) != 0)
+ doveadm_print_header_simple("recent");
+ if ((ctx->items & STATUS_UIDNEXT) != 0)
+ doveadm_print_header_simple("uidnext");
+ if ((ctx->items & STATUS_UIDVALIDITY) != 0)
+ doveadm_print_header_simple("uidvalidity");
+ if ((ctx->items & STATUS_UNSEEN) != 0)
+ doveadm_print_header_simple("unseen");
+ if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0)
+ doveadm_print_header_simple("highestmodseq");
+ if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0)
+ doveadm_print_header_simple("vsize");
+ if (ctx->guid)
+ doveadm_print_header_simple("guid");
}
static bool
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;
}
#include "mail-namespace.h"
#include "mail-storage.h"
#include "mail-search-build.h"
+#include "doveadm-print.h"
#include "doveadm-mail-list-iter.h"
#include "doveadm-mail.h"
while ((info = doveadm_mail_list_iter_next(iter)) != NULL) {
str_truncate(str, 0);
if (ctx->mutf7 || imap_utf7_to_utf8(info->name, str) < 0)
- dm_printf(_ctx, "%s\n", info->name);
+ doveadm_print(info->name);
else
- dm_printf(_ctx, "%s\n", str_c(str));
+ doveadm_print(str_c(str));
}
doveadm_mail_list_iter_deinit(&iter);
}
{
struct list_cmd_context *ctx = (struct list_cmd_context *)_ctx;
+ doveadm_print_header("mailbox", "mailbox",
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
ctx->search_args = doveadm_mail_mailbox_search_args_build(args);
}
ctx->ctx.ctx.v.run = cmd_mailbox_list_run;
ctx->ctx.ctx.v.parse_arg = cmd_mailbox_list_parse_arg;
ctx->ctx.ctx.getopt_args = "78s";
+ doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
return &ctx->ctx.ctx;
}
#include "lib.h"
#include "mail-storage.h"
+#include "doveadm-print.h"
#include "doveadm-mail-list-iter.h"
#include "doveadm-mail-iter.h"
#include "doveadm-mail.h"
ret = -1;
else {
guid_str = mail_guid_128_to_string(guid);
- while (doveadm_mail_iter_next(iter, mail))
- dm_printf(ctx, "%s %u\n", guid_str, mail->uid);
+ while (doveadm_mail_iter_next(iter, mail)) {
+ doveadm_print(guid_str);
+ T_BEGIN {
+ doveadm_print(dec2str(mail->uid));
+ } T_END;
+ }
}
mail_free(&mail);
if (doveadm_mail_iter_deinit(&iter) < 0)
if (args[0] == NULL)
doveadm_mail_help_name("search");
+ doveadm_print_header("mailbox-guid", "mailbox-guid",
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+ doveadm_print_header("uid", "uid",
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+
ctx->search_args = doveadm_mail_build_search_args(args);
}
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
ctx->v.init = cmd_search_init;
ctx->v.run = cmd_search_run;
+ doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
return ctx;
}
#include "mail-search-parser.h"
#include "doveadm.h"
#include "doveadm-settings.h"
+#include "doveadm-print.h"
#include "doveadm-mail.h"
#include <stdio.h>
pool = pool_alloconly_create("doveadm mail cmd", 1024);
ctx = p_malloc(pool, size);
ctx->pool = pool;
- ctx->dm_printf_last_lf = TRUE;
return ctx;
}
n = user_count / 10000;
for (interval = 10; n > 0 && interval < 1000; interval *= 10)
n /= 10;
-
+
user_idx = 0;
while ((ret = ctx->v.get_next_user(ctx, &user)) > 0) {
if (wildcard_user != NULL) {
continue;
}
input.username = user;
+ doveadm_print_sticky("username", user);
T_BEGIN {
ret = doveadm_mail_next_user(ctx, &input, &error);
if (ret < 0)
switch (c) {
case 'A':
ctx->iterate_all_users = TRUE;
+ doveadm_print_header("username", "Username",
+ DOVEADM_PRINT_HEADER_FLAG_STICKY |
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
break;
case 'u':
service_flags |=
exit(FATAL_DEFAULT);
}
-void dm_printf(struct doveadm_mail_cmd_context *ctx, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- if (!ctx->iterate_all_users)
- vprintf(format, args);
- else T_BEGIN {
- const char *str = t_strdup_vprintf(format, args);
- bool prev_lf = ctx->dm_printf_last_lf;
-
- for (; *str != '\0'; str++) {
- if (prev_lf)
- printf("%s: ", ctx->cur_mail_user->username);
- putchar(*str);
- prev_lf = *str == '\n';
- }
- ctx->dm_printf_last_lf = prev_lf;
-
- } T_END;
- va_end(args);
-}
-
static bool
doveadm_mail_try_run_multi_word(const struct doveadm_mail_cmd *cmd,
const char *cmdname, int argc, char *argv[])
ARRAY_DEFINE(module_contexts, union doveadm_mail_cmd_module_context *);
unsigned int iterate_all_users:1;
- unsigned int dm_printf_last_lf:1;
unsigned int failed:1;
};
#define doveadm_mail_cmd_alloc(type) \
(type *)doveadm_mail_cmd_alloc_size(sizeof(type))
-/* same as printf(), but when running with -A parameter,
- prefix each line with username. */
-void dm_printf(struct doveadm_mail_cmd_context *ctx, const char *format, ...)
- ATTR_FORMAT(2, 3);
-
struct doveadm_mail_cmd cmd_expunge;
struct doveadm_mail_cmd cmd_search;
struct doveadm_mail_cmd cmd_fetch;
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "doveadm-print-private.h"
+
+#include <stdio.h>
+
+struct doveadm_print_flow_header {
+ const char *title;
+ enum doveadm_print_header_flags flags;
+};
+
+struct doveadm_print_flow_context {
+ pool_t pool;
+ ARRAY_DEFINE(headers, struct doveadm_print_flow_header);
+ unsigned int header_idx;
+};
+
+static struct doveadm_print_flow_context *ctx;
+
+static void
+doveadm_print_flow_header(const struct doveadm_print_header *hdr)
+{
+ struct doveadm_print_flow_header *fhdr;
+
+ fhdr = array_append_space(&ctx->headers);
+ fhdr->title = p_strdup(ctx->pool, hdr->title);
+ fhdr->flags = hdr->flags;
+}
+
+static void doveadm_print_flow_print(const char *value)
+{
+ const struct doveadm_print_flow_header *hdr =
+ array_idx(&ctx->headers, ctx->header_idx);
+
+ if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE) == 0)
+ printf("%s=", hdr->title);
+ printf("%s", value);
+
+ if (++ctx->header_idx < array_count(&ctx->headers))
+ printf(" ");
+ else {
+ ctx->header_idx = 0;
+ printf("\n");
+ }
+}
+
+static void doveadm_print_flow_init(void)
+{
+ pool_t pool;
+
+ pool = pool_alloconly_create("doveadm print flow", 1024);
+ ctx = p_new(pool, struct doveadm_print_flow_context, 1);
+ ctx->pool = pool;
+ p_array_init(&ctx->headers, pool, 16);
+}
+
+static void doveadm_print_flow_deinit(void)
+{
+ if (ctx->header_idx != 0)
+ printf("\n");
+
+ pool_unref(&ctx->pool);
+ ctx = NULL;
+}
+
+struct doveadm_print_vfuncs doveadm_print_flow_vfuncs = {
+ "flow",
+
+ doveadm_print_flow_init,
+ doveadm_print_flow_deinit,
+ doveadm_print_flow_header,
+ doveadm_print_flow_print
+};
--- /dev/null
+#ifndef DOVEADM_PRINT_PRIVATE_H
+#define DOVEADM_PRINT_PRIVATE_H
+
+#include "doveadm-print.h"
+
+struct doveadm_print_header {
+ const char *key;
+ const char *title;
+ enum doveadm_print_header_flags flags;
+};
+
+struct doveadm_print_vfuncs {
+ const char *name;
+
+ void (*init)(void);
+ void (*deinit)(void);
+
+ void (*header)(const struct doveadm_print_header *hdr);
+ void (*print)(const char *value);
+};
+
+extern struct doveadm_print_vfuncs doveadm_print_flow_vfuncs;
+extern struct doveadm_print_vfuncs doveadm_print_tab_vfuncs;
+extern struct doveadm_print_vfuncs doveadm_print_table_vfuncs;
+
+#endif
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "doveadm-print-private.h"
+
+#include <stdio.h>
+
+struct doveadm_print_tab_context {
+ unsigned int header_idx, header_count;
+
+ unsigned int header_written:1;
+};
+
+static struct doveadm_print_tab_context ctx;
+
+static void
+doveadm_print_tab_header(const struct doveadm_print_header *hdr)
+{
+ if (ctx.header_count++ > 0)
+ printf("\t");
+ printf("%s", hdr->title);
+}
+
+static void doveadm_print_tab_print(const char *value)
+{
+ if (!ctx.header_written) {
+ printf("\n");
+ ctx.header_written = TRUE;
+ }
+ if (ctx.header_idx > 0)
+ printf("\t");
+ printf("%s", value);
+
+ if (++ctx.header_idx < ctx.header_count)
+ printf(" ");
+ else {
+ ctx.header_idx = 0;
+ printf("\n");
+ }
+}
+
+static void doveadm_print_tab_deinit(void)
+{
+ if (!ctx.header_written)
+ printf("\n");
+}
+
+struct doveadm_print_vfuncs doveadm_print_tab_vfuncs = {
+ "tab",
+
+ NULL,
+ doveadm_print_tab_deinit,
+ doveadm_print_tab_header,
+ doveadm_print_tab_print
+};
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "doveadm-print-private.h"
+
+#include <stdio.h>
+
+#define DEFAULT_COLUMNS 80
+#define MAX_BUFFER_LINES 100
+
+struct doveadm_print_table_header {
+ const char *key;
+ const char *title;
+ enum doveadm_print_header_flags flags;
+ unsigned int min_length, max_length, length;
+};
+
+struct doveadm_print_table_context {
+ pool_t pool;
+ ARRAY_DEFINE(headers, struct doveadm_print_table_header);
+ ARRAY_TYPE(const_string) buffered_values;
+ unsigned int hdr_idx;
+ unsigned int columns;
+
+ unsigned int lengths_set:1;
+};
+
+static struct doveadm_print_table_context *ctx;
+
+static void
+doveadm_print_table_header(const struct doveadm_print_header *hdr)
+{
+ struct doveadm_print_table_header *thdr;
+
+ thdr = array_append_space(&ctx->headers);
+ thdr->key = p_strdup(ctx->pool, hdr->key);
+ thdr->title = p_strdup(ctx->pool, hdr->title);
+ thdr->length = thdr->max_length = thdr->min_length = strlen(hdr->title);
+ thdr->flags = hdr->flags;
+}
+
+static void doveadm_calc_header_length(void)
+{
+ struct doveadm_print_table_header *headers;
+ const char *value, *const *values;
+ unsigned int i, line, len, hdr_count, value_count, line_count;
+ unsigned int max_length, orig_length, diff;
+
+ headers = array_get_modifiable(&ctx->headers, &hdr_count);
+ values = array_get(&ctx->buffered_values, &value_count);
+ i_assert((value_count % hdr_count) == 0);
+ line_count = value_count / hdr_count;
+
+ /* find min and max lengths of fields */
+ for (line = 0; line < line_count; line++) {
+ for (i = 0; i < hdr_count; i++) {
+ value = values[line*hdr_count + i];
+ len = value == NULL ? 0 : strlen(value);
+ if (headers[i].min_length > len)
+ headers[i].min_length = len;
+ if (headers[i].max_length < len) {
+ headers[i].max_length = len;
+ headers[i].length = len;
+ }
+ }
+ }
+
+ /* +1 for space between fields */
+ max_length = 0;
+ for (i = 0; i < hdr_count; i++)
+ max_length += headers[i].max_length + 1;
+ max_length--;
+
+ while (max_length > ctx->columns) {
+ /* shrink something so we'll fit */
+ orig_length = max_length;
+ for (i = hdr_count - 1;; i--) {
+ diff = headers[i].length - headers[i].min_length;
+ if (max_length - diff <= ctx->columns) {
+ /* we can finish with this */
+ diff = max_length - ctx->columns;
+ headers[i].length -= diff;
+ max_length -= diff;
+ break;
+ }
+ if (diff > 0) {
+ /* take a bit off from it */
+ headers[i].length -= diff == 1 ? 1 : diff/2;
+ }
+
+ if (i == 0)
+ break;
+ }
+ if (max_length == orig_length) {
+ /* can't shrink it any more */
+ break;
+ }
+ }
+ if (max_length < ctx->columns)
+ headers[0].length += (ctx->columns - max_length) / 2;
+}
+
+static void doveadm_print_next(const char *value)
+{
+ const struct doveadm_print_table_header *hdr;
+
+ hdr = array_idx(&ctx->headers, ctx->hdr_idx);
+
+ if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY) == 0)
+ printf("%-*s", (int)hdr->length, value);
+ else
+ printf("%*s", (int)hdr->length, value);
+
+ if (++ctx->hdr_idx == array_count(&ctx->headers)) {
+ ctx->hdr_idx = 0;
+ printf("\n");
+ } else {
+ printf(" ");
+ }
+}
+
+static void doveadm_buffer_flush(void)
+{
+ const struct doveadm_print_table_header *headers;
+ const char *const *valuep;
+ unsigned int i, count;
+
+ doveadm_calc_header_length();
+
+ headers = array_get(&ctx->headers, &count);
+ for (i = 0; i < count; i++) {
+ if (i > 0) fprintf(stderr, " ");
+
+ if ((headers[i].flags &
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY) == 0) {
+ fprintf(stderr, "%-*s", (int)headers[i].length,
+ headers[i].title);
+ } else {
+ fprintf(stderr, "%*s", (int)headers[i].length,
+ headers[i].title);
+ }
+ }
+ fprintf(stderr, "\n");
+
+ array_foreach(&ctx->buffered_values, valuep)
+ doveadm_print_next(*valuep);
+ array_clear(&ctx->buffered_values);
+}
+
+static void doveadm_print_table_print(const char *value)
+{
+ if (!ctx->lengths_set) {
+ if (array_count(&ctx->buffered_values) < MAX_BUFFER_LINES) {
+ value = p_strdup(ctx->pool, value);
+ array_append(&ctx->buffered_values, &value, 1);
+ return;
+ }
+ doveadm_buffer_flush();
+ }
+ doveadm_print_next(value);
+}
+
+static void doveadm_print_table_init(void)
+{
+ pool_t pool;
+
+ pool = pool_alloconly_create("doveadm print table", 1024);
+ ctx = p_new(pool, struct doveadm_print_table_context, 1);
+ ctx->pool = pool;
+ p_array_init(&ctx->headers, pool, 16);
+ i_array_init(&ctx->buffered_values, 64);
+ ctx->columns = DEFAULT_COLUMNS;
+}
+
+static void doveadm_print_table_deinit(void)
+{
+ if (!ctx->lengths_set && array_count(&ctx->headers) > 0)
+ doveadm_buffer_flush();
+
+ array_free(&ctx->buffered_values);
+ pool_unref(&ctx->pool);
+ ctx = NULL;
+}
+
+struct doveadm_print_vfuncs doveadm_print_table_vfuncs = {
+ "table",
+
+ doveadm_print_table_init,
+ doveadm_print_table_deinit,
+ doveadm_print_table_header,
+ doveadm_print_table_print
+};
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "doveadm-print-private.h"
+
+struct doveadm_print_header_context {
+ const char *key;
+ char *sticky_value;
+ bool sticky;
+};
+
+struct doveadm_print_context {
+ pool_t pool;
+ ARRAY_DEFINE(headers, struct doveadm_print_header_context);
+ const struct doveadm_print_vfuncs *v;
+
+ unsigned int header_idx;
+};
+
+static struct doveadm_print_context *ctx;
+static const struct doveadm_print_vfuncs *doveadm_print_vfuncs_all[] = {
+ &doveadm_print_flow_vfuncs,
+ &doveadm_print_tab_vfuncs,
+ &doveadm_print_table_vfuncs
+};
+
+void doveadm_print_header(const char *key, const char *title,
+ enum doveadm_print_header_flags flags)
+{
+ struct doveadm_print_header hdr;
+ struct doveadm_print_header_context *hdr_ctx;
+
+ if (title == NULL)
+ flags |= DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE;
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.key = key;
+ hdr.title = title;
+ hdr.flags = flags;
+ ctx->v->header(&hdr);
+
+ hdr_ctx = array_append_space(&ctx->headers);
+ hdr_ctx->key = p_strdup(ctx->pool, key);
+ hdr_ctx->sticky = (flags & DOVEADM_PRINT_HEADER_FLAG_STICKY) != 0;
+}
+
+void doveadm_print_header_simple(const char *key_title)
+{
+ doveadm_print_header(key_title, key_title, 0);
+}
+
+void doveadm_print(const char *value)
+{
+ const struct doveadm_print_header_context *headers;
+ unsigned int count;
+
+ headers = array_get(&ctx->headers, &count);
+ for (;;) {
+ if (ctx->header_idx == count)
+ ctx->header_idx = 0;
+ else if (headers[ctx->header_idx].sticky) {
+ ctx->v->print(headers[ctx->header_idx].sticky_value);
+ ctx->header_idx++;
+ } else {
+ break;
+ }
+ }
+
+ ctx->v->print(value);
+ ctx->header_idx++;
+}
+
+void doveadm_print_num(uintmax_t value)
+{
+ T_BEGIN {
+ doveadm_print(dec2str(value));
+ } T_END;
+}
+
+void doveadm_print_sticky(const char *key, const char *value)
+{
+ struct doveadm_print_header_context *hdr;
+
+ array_foreach_modifiable(&ctx->headers, hdr) {
+ if (strcmp(hdr->key, key) == 0) {
+ i_free(hdr->sticky_value);
+ hdr->sticky_value = i_strdup(value);
+ return;
+ }
+ }
+ i_unreached();
+}
+
+void doveadm_print_init(const char *name)
+{
+ pool_t pool;
+ unsigned int i;
+
+ if (ctx != NULL) {
+ /* already forced the type */
+ return;
+ }
+
+ pool = pool_alloconly_create("doveadm print", 1024);
+ ctx = p_new(pool, struct doveadm_print_context, 1);
+ ctx->pool = pool;
+ p_array_init(&ctx->headers, pool, 16);
+
+ for (i = 0; i < N_ELEMENTS(doveadm_print_vfuncs_all); i++) {
+ if (strcmp(doveadm_print_vfuncs_all[i]->name, name) == 0) {
+ ctx->v = doveadm_print_vfuncs_all[i];
+ break;
+ }
+ }
+ if (ctx->v == NULL)
+ i_fatal("Unknown print formatter: %s", name);
+ if (ctx->v->init != NULL)
+ ctx->v->init();
+}
+
+void doveadm_print_deinit(void)
+{
+ struct doveadm_print_header_context *hdr;
+
+ if (ctx == NULL)
+ return;
+
+ ctx->v->deinit();
+ array_foreach_modifiable(&ctx->headers, hdr)
+ i_free(hdr->sticky_value);
+ pool_unref(&ctx->pool);
+ ctx = NULL;
+}
--- /dev/null
+#ifndef DOVEADM_PRINT_H
+#define DOVEADM_PRINT_H
+
+#define DOVEADM_PRINT_TYPE_FLOW "flow"
+#define DOVEADM_PRINT_TYPE_TABLE "table"
+
+enum doveadm_print_header_flags {
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY = 0x01,
+ DOVEADM_PRINT_HEADER_FLAG_STICKY = 0x02,
+ DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE = 0x04
+};
+
+void doveadm_print_header(const char *key, const char *title,
+ enum doveadm_print_header_flags flags);
+void doveadm_print_header_simple(const char *key_title);
+void doveadm_print(const char *value);
+void doveadm_print_num(uintmax_t value);
+void doveadm_print_sticky(const char *key, const char *value);
+
+void doveadm_print_init(const char *name);
+void doveadm_print_deinit(void);
+
+#endif
#include "istream.h"
#include "wildcard-match.h"
#include "hash.h"
+#include "str.h"
#include "doveadm.h"
+#include "doveadm-print.h"
#include "doveadm-who.h"
#include <stdio.h>
return TRUE;
}
+static void who_print_user(const struct who_user *user)
+{
+ const struct ip_addr *ip;
+ const pid_t *pid;
+ string_t *str = t_str_new(256);
+
+ doveadm_print(user->username);
+ doveadm_print(dec2str(user->connection_count));
+ doveadm_print(user->service);
+
+ str_append_c(str, '(');
+ array_foreach(&user->pids, pid)
+ str_printfa(str, "%ld ", (long)*pid);
+ if (str_len(str) > 1)
+ str_truncate(str, str_len(str)-1);
+ str_append_c(str, ')');
+ doveadm_print(str_c(str));
+
+ str_truncate(str, 0);
+ str_append_c(str, '(');
+ array_foreach(&user->ips, ip)
+ str_printfa(str, "%s ", net_ip2addr(ip));
+ if (str_len(str) > 1)
+ str_truncate(str, str_len(str)-1);
+ str_append_c(str, ')');
+ doveadm_print(str_c(str));
+}
+
static void who_print(struct who_context *ctx)
{
struct hash_iterate_context *iter;
void *key, *value;
- fprintf(stderr, "%-30s # proto\t(pids)\t(ips)\n", "username");
+ doveadm_print_header("username", "username", 0);
+ doveadm_print_header("connections", "#",
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
+ doveadm_print_header("service", "proto", 0);
+ doveadm_print_header("pids", "(pids)", 0);
+ doveadm_print_header("ips", "(ips)", 0);
iter = hash_table_iterate_init(ctx->users);
while (hash_table_iterate(iter, &key, &value)) {
struct who_user *user = value;
- const struct ip_addr *ip;
- const pid_t *pid;
- bool first = TRUE;
-
- if (!who_user_filter_match(user, &ctx->filter))
- continue;
-
- printf("%-30s %2u %-5s ", user->username,
- user->connection_count, user->service);
-
- printf("(");
- array_foreach(&user->pids, pid) T_BEGIN {
- if (first)
- first = FALSE;
- else
- printf(" ");
- printf("%ld", (long)*pid);
- } T_END;
- printf(") (");
- first = TRUE;
- array_foreach(&user->ips, ip) T_BEGIN {
- if (first)
- first = FALSE;
- else
- printf(" ");
- printf("%s", net_ip2addr(ip));
+
+ if (who_user_filter_match(user, &ctx->filter)) T_BEGIN {
+ who_print_user(user);
} T_END;
- printf(")\n");
- };
+ }
hash_table_iterate_deinit(&iter);
}
return;
for (i = 0; i < line->refcount; i++) T_BEGIN {
- printf("%-30s %-5s\t%ld\t%-15s\n", line->username,
- line->service, (long)line->pid, net_ip2addr(&line->ip));
+ doveadm_print(line->username);
+ doveadm_print(line->service);
+ doveadm_print(dec2str(line->pid));
+ doveadm_print(net_ip2addr(&line->ip));
} T_END;
}
argv += optind - 1;
who_parse_args(&ctx, argv);
+ doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
if (!separate_connections) {
who_lookup(&ctx, who_aggregate_line);
who_print(&ctx);
} else {
- fprintf(stderr, "%-30s proto\tpid\t%-15s\n", "username", "ip");
+ doveadm_print_header_simple("username");
+ doveadm_print_header_simple("service");
+ doveadm_print_header_simple("pid");
+ doveadm_print_header_simple("ip");
who_lookup(&ctx, who_print_line);
}
#include "module-dir.h"
#include "master-service.h"
#include "master-service-settings.h"
+#include "doveadm-print.h"
#include "doveadm-mail.h"
#include "doveadm-settings.h"
#include "doveadm.h"
const struct doveadm_cmd *cmd;
string_t *str = t_str_new(1024);
- fprintf(out, "usage: doveadm [-Dv] ");
+ fprintf(out, "usage: doveadm [-Dv] [-F <formatter>] ");
if (*prefix != '\0')
fprintf(out, "%s ", prefix);
fprintf(out, "<command> [<args>]\n");
/* "+" is GNU extension to stop at the first non-option.
others just accept -+ option. */
master_service = master_service_init("doveadm", service_flags,
- &argc, &argv, "+Dv");
+ &argc, &argv, "+DF:v");
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'D':
doveadm_debug = TRUE;
doveadm_verbose = TRUE;
break;
+ case 'F':
+ doveadm_print_init(optarg);
+ break;
case 'v':
doveadm_verbose = TRUE;
break;
if (!quick_init) {
doveadm_mail_deinit();
module_dir_unload(&modules);
+ doveadm_print_deinit();
}
array_free(&doveadm_cmds);
master_service_deinit(&master_service);
#include "module-dir.h"
#include "quota-plugin.h"
#include "quota-private.h"
+#include "doveadm-print.h"
#include "doveadm-mail.h"
const char *doveadm_quota_plugin_version = DOVECOT_VERSION;
void doveadm_quota_plugin_init(struct module *module);
void doveadm_quota_plugin_deinit(void);
-static void
-cmd_quota_get_root(struct doveadm_mail_cmd_context *ctx,
- struct quota_root *root)
+static void cmd_quota_get_root(struct quota_root *root)
{
const char *const *res;
uint64_t value, limit;
int ret;
- dm_printf(ctx, "%s: ", root->set->name);
res = quota_root_get_resources(root);
for (; *res != NULL; res++) {
ret = quota_get_resource(root, "", *res, &value, &limit);
- dm_printf(ctx, "%s ", *res);
+ doveadm_print(root->set->name);
+ doveadm_print(*res);
if (ret > 0) {
- dm_printf(ctx, "%llu/%llu",
- (unsigned long long)value,
- (unsigned long long)limit);
- if (limit >= 100) {
- dm_printf(ctx, " (%u%%)",
- (unsigned int)(value / (limit/100)));
- }
+ doveadm_print_num(value);
+ doveadm_print_num(limit);
+ if (limit >= 100)
+ doveadm_print_num(value / (limit/100));
+ else
+ doveadm_print("0");
} else if (ret == 0) {
- dm_printf(ctx, "%llu/unlimited",
- (unsigned long long)value);
- } else
- dm_printf(ctx, "error");
- if (res[1] != NULL)
- dm_printf(ctx, ", ");
+ doveadm_print_num(value);
+ doveadm_print("-");
+ doveadm_print("0");
+ } else {
+ doveadm_print("error");
+ doveadm_print("error");
+ doveadm_print("error");
+ }
}
- dm_printf(ctx, "\n");
}
static void
-cmd_quota_get_run(struct doveadm_mail_cmd_context *ctx,
+cmd_quota_get_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
struct mail_user *user)
{
struct quota_user *quser = QUOTA_USER_CONTEXT(user);
struct quota_root *const *root;
array_foreach(&quser->quota->roots, root)
- cmd_quota_get_root(ctx, *root);
+ cmd_quota_get_root(*root);
+}
+
+static void cmd_quota_get_init(struct doveadm_mail_cmd_context *ctx,
+ const char *const args[] ATTR_UNUSED)
+{
+ doveadm_print_header("root", "Quota name", 0);
+ doveadm_print_header("type", "Type", 0);
+ doveadm_print_header("value", "Value",
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
+ doveadm_print_header("limit", "Limit",
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
+ doveadm_print_header("percent", "%",
+ DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
+
+ ctx->search_args = doveadm_mail_build_search_args(args);
}
static struct doveadm_mail_cmd_context *
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
ctx->v.run = cmd_quota_get_run;
+ ctx->v.init = cmd_quota_get_init;
+ doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
return ctx;
}