chiark / gitweb /
Prep v231: Apply missing fixes from upstream (1/6) src/basic
[elogind.git] / src / basic / hexdecoct.c
index 4eb566b15aadd0d5d9a2f6a6eee2fb6bed73c662..c5bda6c4d68db6b69f2ec8a5d996f3928045ee98 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
 ***/
 
 #include <ctype.h>
-#include <inttypes.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
 
 #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 */