diff options
-rw-r--r-- | src/basic/hexdecoct.c | 61 | ||||
-rw-r--r-- | src/basic/hexdecoct.h | 5 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.c | 33 | ||||
-rw-r--r-- | src/test/test-util.c | 21 |
4 files changed, 90 insertions, 30 deletions
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 1e907de228..f30e028f45 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -514,14 +514,14 @@ int unbase64char(char c) { return -EINVAL; } -char *base64mem(const void *p, size_t l) { +ssize_t base64mem(const void *p, size_t l, char **out) { char *r, *z; const uint8_t *x; /* three input bytes makes four output bytes, padding is added so we must round up */ z = r = malloc(4 * (l + 2) / 3 + 1); if (!r) - return NULL; + return -ENOMEM; for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) { /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */ @@ -549,9 +549,64 @@ char *base64mem(const void *p, size_t l) { } *z = 0; - return r; + *out = r; + return z - r; +} + +static int base64_append_width(char **prefix, int plen, + const char *sep, int indent, + const void *p, size_t l, + int width) { + + _cleanup_free_ char *x = NULL; + char *t, *s; + ssize_t slen, len, avail; + int line, lines; + + len = base64mem(p, l, &x); + if (len <= 0) + return len; + + lines = (len + width - 1) / width; + + slen = sep ? strlen(sep) : 0; + t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines); + if (!t) + return -ENOMEM; + + memcpy(t + plen, sep, slen); + + for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) { + int act = MIN(width, avail); + + if (line > 0 || sep) { + memset(s, ' ', indent); + s += indent; + } + + memcpy(s, x + width * line, act); + s += act; + *(s++) = line < lines - 1 ? '\n' : '\0'; + avail -= act; + } + assert(avail == 0); + + *prefix = t; + return 0; } +int base64_append(char **prefix, int plen, + const void *p, size_t l, + int indent, int width) { + if (plen > width / 2 || plen + indent > width) + /* leave indent on the left, keep last column free */ + return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1); + else + /* leave plen on the left, keep last column free */ + return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1); +}; + + int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) { _cleanup_free_ uint8_t *r = NULL; int a, b, c, d; diff --git a/src/basic/hexdecoct.h b/src/basic/hexdecoct.h index d9eb54a8a1..243c5e921e 100644 --- a/src/basic/hexdecoct.h +++ b/src/basic/hexdecoct.h @@ -49,7 +49,10 @@ int unbase64char(char c) _const_; char *base32hexmem(const void *p, size_t l, bool padding); int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len); -char *base64mem(const void *p, size_t l); +ssize_t base64mem(const void *p, size_t l, char **out); +int base64_append(char **prefix, int plen, + const void *p, size_t l, + int margin, int width); int unbase64mem(const char *p, size_t l, void **mem, size_t *len); void hexdump(FILE *f, const void *p, size_t s); diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 7273ef3825..a3df8d5aff 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -30,6 +30,7 @@ #include "string-table.h" #include "string-util.h" #include "strv.h" +#include "terminal-util.h" DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) { DnsResourceKey *k; @@ -958,23 +959,27 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { case DNS_TYPE_DNSKEY: { _cleanup_free_ char *alg = NULL; + int n; r = dnssec_algorithm_to_string_alloc(rr->dnskey.algorithm, &alg); if (r < 0) return NULL; - t = base64mem(rr->dnskey.key, rr->dnskey.key_size); - if (!t) - return NULL; - - r = asprintf(&s, "%s %u %u %s %s", + r = asprintf(&s, "%s %u %u %s %n", k, rr->dnskey.flags, rr->dnskey.protocol, alg, - t); + &n); if (r < 0) return NULL; + + r = base64_append(&s, n, + rr->dnskey.key, rr->dnskey.key_size, + 8, columns()); + if (r < 0) + return NULL; + break; } @@ -982,6 +987,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { _cleanup_free_ char *alg = NULL; char expiration[strlen("YYYYMMDDHHmmSS") + 1], inception[strlen("YYYYMMDDHHmmSS") + 1]; const char *type; + int n; type = dns_type_to_string(rr->rrsig.type_covered); @@ -989,10 +995,6 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { if (r < 0) return NULL; - t = base64mem(rr->rrsig.signature, rr->rrsig.signature_size); - if (!t) - return NULL; - r = format_timestamp_dns(expiration, sizeof(expiration), rr->rrsig.expiration); if (r < 0) return NULL; @@ -1004,7 +1006,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { /* TYPE?? follows * http://tools.ietf.org/html/rfc3597#section-5 */ - r = asprintf(&s, "%s %s%.*u %s %u %u %s %s %u %s %s", + r = asprintf(&s, "%s %s%.*u %s %u %u %s %s %u %s %n", k, type ?: "TYPE", type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered, @@ -1015,9 +1017,16 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { inception, rr->rrsig.key_tag, rr->rrsig.signer, - t); + &n); if (r < 0) return NULL; + + r = base64_append(&s, n, + rr->rrsig.signature, rr->rrsig.signature_size, + 8, columns()); + if (r < 0) + return NULL; + break; } diff --git a/src/test/test-util.c b/src/test/test-util.c index f6ed55878c..e199497818 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -545,38 +545,31 @@ static void test_unbase32hexmem(void) { static void test_base64mem(void) { char *b64; - b64 = base64mem("", strlen("")); - assert_se(b64); + assert_se(base64mem("", strlen(""), &b64) == 0); assert_se(streq(b64, "")); free(b64); - b64 = base64mem("f", strlen("f")); - assert_se(b64); + assert_se(base64mem("f", strlen("f"), &b64) == 4); assert_se(streq(b64, "Zg==")); free(b64); - b64 = base64mem("fo", strlen("fo")); - assert_se(b64); + assert_se(base64mem("fo", strlen("fo"), &b64) == 4); assert_se(streq(b64, "Zm8=")); free(b64); - b64 = base64mem("foo", strlen("foo")); - assert_se(b64); + assert_se(base64mem("foo", strlen("foo"), &b64) == 4); assert_se(streq(b64, "Zm9v")); free(b64); - b64 = base64mem("foob", strlen("foob")); - assert_se(b64); + assert_se(base64mem("foob", strlen("foob"), &b64) == 8); assert_se(streq(b64, "Zm9vYg==")); free(b64); - b64 = base64mem("fooba", strlen("fooba")); - assert_se(b64); + assert_se(base64mem("fooba", strlen("fooba"), &b64) == 8); assert_se(streq(b64, "Zm9vYmE=")); free(b64); - b64 = base64mem("foobar", strlen("foobar")); - assert_se(b64); + assert_se(base64mem("foobar", strlen("foobar"), &b64) == 8); assert_se(streq(b64, "Zm9vYmFy")); free(b64); } |