+static void putb64(const octet *buf, size_t sz, FILE *fp)
+{
+ base64_ctx b;
+ dstr d = DSTR_INIT;
+
+ base64_init(&b);
+ b.indent = "";
+ b.maxline = 0;
+ base64_encode(&b, buf, sz, &d);
+ base64_encode(&b, 0, 0, &d);
+ dstr_write(&d, fp);
+ dstr_destroy(&d);
+}
+
+static size_t getb64(const char *p, octet *q, size_t sz, char **pp)
+{
+ base64_ctx b;
+ dstr d = DSTR_INIT;
+ size_t n = strlen(p);
+
+ base64_init(&b);
+ base64_decode(&b, p, n, &d);
+ if (pp) *pp = (/*unconst*/ char *)p + n;
+ base64_decode(&b, 0, 0, &d);
+ assert(d.len <= sz);
+ memcpy(q, d.buf, sz);
+ n = d.len;
+ dstr_destroy(&d);
+ return (n);
+}
+
+/* --- Base32 encoding --- */
+
+static void putb32(const octet *buf, size_t sz, FILE *fp)
+{
+ base32_ctx b;
+ dstr d = DSTR_INIT;
+
+ base32_init(&b);
+ b.indent = "";
+ b.maxline = 0;
+ base32_encode(&b, buf, sz, &d);
+ base32_encode(&b, 0, 0, &d);
+ dstr_write(&d, fp);
+ dstr_destroy(&d);
+}
+
+static size_t getb32(const char *p, octet *q, size_t sz, char **pp)
+{
+ base32_ctx b;
+ dstr d = DSTR_INIT;
+ size_t n = strlen(p);
+
+ base32_init(&b);
+ base32_decode(&b, p, n, &d);
+ if (pp) *pp = (/*unconst*/ char *)p + n;
+ base32_decode(&b, 0, 0, &d);
+ assert(d.len <= sz);
+ memcpy(q, d.buf, sz);
+ n = d.len;
+ dstr_destroy(&d);
+ return (n);
+}
+
+/* --- Table --- */
+
+typedef struct encodeops {
+ const char *name;
+ void (*put)(const octet *, size_t, FILE *);
+ size_t (*get)(const char *, octet *, size_t, char **);
+} encodeops;
+
+static const encodeops encodingtab[] = {
+ { "hex", puthex, gethex },
+ { "base64", putb64, getb64 },
+ { "base32", putb32, getb32 },
+ { 0, 0, 0 }