Mercurial > dovecot > core-2.2
changeset 21894:cb05b557fd74
lib-imap: Add imap_write_args_for_human()
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 04 Apr 2017 15:58:15 +0300 |
parents | 5511ffac2ca4 |
children | 76327526ee5c |
files | src/lib-imap/imap-util.c src/lib-imap/imap-util.h |
diffstat | 2 files changed, 72 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-imap/imap-util.c Tue Apr 04 15:38:00 2017 +0300 +++ b/src/lib-imap/imap-util.c Tue Apr 04 15:58:15 2017 +0300 @@ -4,6 +4,7 @@ #include "array.h" #include "str.h" #include "strescape.h" +#include "unichar.h" #include "mail-types.h" #include "imap-parser.h" #include "imap-util.h" @@ -119,6 +120,73 @@ } } +static void imap_human_args_fix_control_chars(char *str) +{ + size_t i; + + for (i = 0; str[i] != '\0'; i++) { + if (str[i] < 0x20 || str[i] == 0x7f) + str[i] = '?'; + } +} + +void imap_write_args_for_human(string_t *dest, const struct imap_arg *args) +{ + bool first = TRUE; + + for (; !IMAP_ARG_IS_EOL(args); args++) { + if (first) + first = FALSE; + else + str_append_c(dest, ' '); + + switch (args->type) { + case IMAP_ARG_NIL: + str_append(dest, "NIL"); + break; + case IMAP_ARG_ATOM: + /* atom has only printable us-ascii chars */ + str_append(dest, imap_arg_as_astring(args)); + break; + case IMAP_ARG_STRING: + case IMAP_ARG_LITERAL: { + const char *strarg = imap_arg_as_astring(args); + + if (strpbrk(strarg, "\r\n") != NULL) { + str_printfa(dest, "<%"PRIuSIZE_T" byte multi-line literal>", + strlen(strarg)); + break; + } + strarg = str_escape(strarg); + + str_append_c(dest, '"'); + size_t start_pos = str_len(dest); + /* append only valid UTF-8 chars */ + if (uni_utf8_get_valid_data((const unsigned char *)strarg, + strlen(strarg), dest)) + str_append(dest, strarg); + /* replace all control chars */ + imap_human_args_fix_control_chars( + str_c_modifiable(dest) + start_pos); + str_append_c(dest, '"'); + break; + } + case IMAP_ARG_LIST: + str_append_c(dest, '('); + imap_write_args_for_human(dest, imap_arg_as_list(args)); + str_append_c(dest, ')'); + break; + case IMAP_ARG_LITERAL_SIZE: + case IMAP_ARG_LITERAL_SIZE_NONSYNC: + str_printfa(dest, "<%"PRIuUOFF_T" byte literal>", + imap_arg_as_literal_size(args)); + break; + case IMAP_ARG_EOL: + i_unreached(); + } + } +} + const char *imap_args_to_str(const struct imap_arg *args) { string_t *str;
--- a/src/lib-imap/imap-util.h Tue Apr 04 15:38:00 2017 +0300 +++ b/src/lib-imap/imap-util.h Tue Apr 04 15:58:15 2017 +0300 @@ -16,6 +16,10 @@ void imap_write_seq_range(string_t *dest, const ARRAY_TYPE(seq_range) *array); /* Write IMAP args to given string. The string is mainly useful for humans. */ void imap_write_args(string_t *dest, const struct imap_arg *args); +/* Write IMAP args in a human-readable format to given string (e.g. for + logging). The output is a single valid UTF-8 line without control + characters. Multi-line literals are replaced with a generic placeholder. */ +void imap_write_args_for_human(string_t *dest, const struct imap_arg *args); /* Like imap_write_args(), but return the string allocated from data stack. */ const char *imap_args_to_str(const struct imap_arg *args);