X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fbasic%2Fhexdecoct.c;h=c5bda6c4d68db6b69f2ec8a5d996f3928045ee98;hp=4eb566b15aadd0d5d9a2f6a6eee2fb6bed73c662;hb=c60d32aa37fc0b10451b0d392d90b3b96eb88ebc;hpb=da2587d5154e11d4e643e326793f3ce2cc48dee6 diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 4eb566b15..c5bda6c4d 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -20,10 +18,13 @@ ***/ #include -#include +#include +#include +#include #include "alloc-util.h" #include "hexdecoct.h" +#include "macro.h" #include "util.h" char octchar(int x) { @@ -275,8 +276,8 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l if (padding) { /* strip the padding */ while (l > 0 && p[l - 1] == '=' && pad < 7) { - pad ++; - l --; + pad++; + l--; } } @@ -504,7 +505,7 @@ int unbase64char(char c) { if (c == '+') return offset; - offset ++; + offset++; if (c == '/') return offset; @@ -512,14 +513,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 */ @@ -547,9 +548,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_safe(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; @@ -565,9 +621,9 @@ int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) { /* strip the padding */ if (l > 0 && p[l - 1] == '=') - l --; + l--; if (l > 0 && p[l - 1] == '=') - l --; + l--; /* a group of four input bytes needs three output bytes, in case of padding we need to add two or three extra bytes */