SMOLNET PORTAL home about changes
iimplement base64 data in-place decoding - ics2txt - convert icalendar .ics file to plain text	Err	bitreich.org	70
hgit clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt	URL:git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt	bitreich.org	70
1Log	/scm/ics2txt/log.gph	bitreich.org	70
1Files	/scm/ics2txt/files.gph	bitreich.org	70
1Refs	/scm/ics2txt/refs.gph	bitreich.org	70
1Tags	/scm/ics2txt/tag	bitreich.org	70
1README	/scm/ics2txt/file/README.md.gph	bitreich.org	70
i---	Err	bitreich.org	70
1commit b72092250747c7443e20fee06bee232b236f441e	/scm/ics2txt/commit/b72092250747c7443e20fee06bee232b236f441e.gph	bitreich.org	70
1parent 917f5b056d0b1241f0816bfd41276a36b5727fb1	/scm/ics2txt/commit/917f5b056d0b1241f0816bfd41276a36b5727fb1.gph	bitreich.org	70
hAuthor: Josuah Demangeon <me@josuah.net>	URL:mailto:me@josuah.net	bitreich.org	70
iDate:   Sun, 13 Jun 2021 13:47:25 +0200	Err	bitreich.org	70
i	Err	bitreich.org	70
iimplement base64 data in-place decoding	Err	bitreich.org	70
i	Err	bitreich.org	70
iThis is not done implicitly in case base64 decoding is not needed	Err	bitreich.org	70
ievery time, but instead available as a ical_get_value() function that	Err	bitreich.org	70
idecodes the content if it is base64 data.	Err	bitreich.org	70
i	Err	bitreich.org	70
iDiffstat:	Err	bitreich.org	70
i  M Makefile                            |       4 ++--	Err	bitreich.org	70
i  A base64.c                            |     107 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A base64.h                            |      19 +++++++++++++++++++	Err	bitreich.org	70
i  M ical.c                              |      22 +++++++++++++++++++++-	Err	bitreich.org	70
i  M ical.h                              |       9 +++++----	Err	bitreich.org	70
i  M ics2tree.c                          |       5 ++++-	Err	bitreich.org	70
i  D ics2tsv.c                           |      59 -------------------------------	Err	bitreich.org	70
i  M util.c                              |       2 +-	Err	bitreich.org	70
i	Err	bitreich.org	70
i8 files changed, 159 insertions(+), 68 deletions(-)	Err	bitreich.org	70
i---	Err	bitreich.org	70
1diff --git a/Makefile b/Makefile	/scm/ics2txt/file/Makefile.gph	bitreich.org	70
i@@ -7,8 +7,8 @@ CFLAGS = $D $W -g	Err	bitreich.org	70
i PREFIX = /usr/local	Err	bitreich.org	70
i MANPREFIX = ${PREFIX}/man	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-SRC = ical.c util.c	Err	bitreich.org	70
i-HDR = ical.h util.h	Err	bitreich.org	70
i+SRC = ical.c base64.c util.c	Err	bitreich.org	70
i+HDR = ical.h base64.h util.h	Err	bitreich.org	70
i OBJ = ${SRC:.c=.o}	Err	bitreich.org	70
i BIN = ics2tree	Err	bitreich.org	70
i MAN1 = ics2txt.1	Err	bitreich.org	70
1diff --git a/base64.c b/base64.c	/scm/ics2txt/file/base64.c.gph	bitreich.org	70
i@@ -0,0 +1,107 @@	Err	bitreich.org	70
i+#include "base64.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <assert.h>	Err	bitreich.org	70
i+#include <stddef.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+static char encode_map[64] =	Err	bitreich.org	70
i+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+base64_encode(char const *s, size_t slen, char *d, size_t *dlen)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char const *sbeg = s, *send = s + slen, *dbeg = d;	Err	bitreich.org	70
i+        unsigned char x;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        while (s < send) {	Err	bitreich.org	70
i+                switch ((s - sbeg) % 3) {	Err	bitreich.org	70
i+                case 0: /* AAAAAABB bbbbcccc ccdddddd */	Err	bitreich.org	70
i+                        assert((size_t)(d - dbeg) + 1 < *dlen);	Err	bitreich.org	70
i+                        *d++ = encode_map[*s >> 2];	Err	bitreich.org	70
i+                        x = *s << 4 & 0x3f;	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                case 1: /* aaaaaabb BBBBCCCC ccdddddd */	Err	bitreich.org	70
i+                        assert((size_t)(d - dbeg) + 1 < *dlen);	Err	bitreich.org	70
i+                        *d++ = encode_map[x | (*s >> 4)];	Err	bitreich.org	70
i+                        x = (*s << 2) & 0x3f;	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                case 2: /* aaaaaabb bbbbcccc CCDDDDDD */	Err	bitreich.org	70
i+                        assert((size_t)(d - dbeg) + 2 < *dlen);	Err	bitreich.org	70
i+                        *d++ = encode_map[x | (*s >> 6)];	Err	bitreich.org	70
i+                        *d++ = encode_map[*s & 0x3f];	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+                s++;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        /* flush extra content in 'x' */	Err	bitreich.org	70
i+        assert((size_t)(d - dbeg) + 1 < *dlen);	Err	bitreich.org	70
i+        if ((s - sbeg) % 3 != 2)	Err	bitreich.org	70
i+                *d++ = encode_map[x];	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        /* pad the end with '=' */	Err	bitreich.org	70
i+        while ((d - dbeg) % 4 != 0) {	Err	bitreich.org	70
i+                assert((size_t)(d - dbeg) + 1 < *dlen);	Err	bitreich.org	70
i+                *d++ = '=';	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        *dlen = d - dbeg;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+static int8_t decode_map[256] = {	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,	Err	bitreich.org	70
i+        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1,  0, -1, -1,	Err	bitreich.org	70
i+        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,	Err	bitreich.org	70
i+        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,	Err	bitreich.org	70
i+        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+base64_decode(char const *s, size_t *slen, char *d, size_t *dlen)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char const *sbeg = s, *send = sbeg + *slen, *dbeg = d;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (; s + 3 < send; s += 4) {	Err	bitreich.org	70
i+                int8_t x0 = decode_map[(unsigned)s[0]];	Err	bitreich.org	70
i+                int8_t x1 = decode_map[(unsigned)s[1]];	Err	bitreich.org	70
i+                int8_t x2 = decode_map[(unsigned)s[2]];	Err	bitreich.org	70
i+                int8_t x3 = decode_map[(unsigned)s[3]];	Err	bitreich.org	70
i+                uint32_t x = (x0 << 18) | (x1 << 12) | (x2 << 6) | (x3 << 0);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                assert((size_t)(d - dbeg) + 3 < *dlen);	Err	bitreich.org	70
i+                *d++ = x >> 16;	Err	bitreich.org	70
i+                *d++ = x >> 8 & 0xff;	Err	bitreich.org	70
i+                *d++ = x & 0xff;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                /* only "xxxx" or "xxx=" or "xx==" allowed  */	Err	bitreich.org	70
i+                if (s[0] == '=' || s[1] == '=' || (s[2] == '=' && s[3] != '='))	Err	bitreich.org	70
i+                        return -2;	Err	bitreich.org	70
i+                if (s[2] == '=')	Err	bitreich.org	70
i+                        d--;	Err	bitreich.org	70
i+                if (s[3] == '=') {	Err	bitreich.org	70
i+                        d--;	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                if (x0 < 0 || x1 < 0 || x2 < 0 || x3 < 0)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        *slen = s - sbeg;	Err	bitreich.org	70
i+        *dlen = d - dbeg;	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/base64.h b/base64.h	/scm/ics2txt/file/base64.h.gph	bitreich.org	70
i@@ -0,0 +1,19 @@	Err	bitreich.org	70
i+#ifndef BASE64_H	Err	bitreich.org	70
i+#define BASE64_H	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stddef.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void        base64_encode(char const *, size_t, char *, size_t *);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+/*	Err	bitreich.org	70
i+ * It is possible to use the same variables for both source and	Err	bitreich.org	70
i+ * destination. Then the base64 will overwrite the source buffer	Err	bitreich.org	70
i+ * with the destination data.	Err	bitreich.org	70
i+ *	Err	bitreich.org	70
i+ * If the same pointer is passed as both source and destination	Err	bitreich.org	70
i+ * size, the source size will be inaccurate but the destination	Err	bitreich.org	70
i+ * will be correct.	Err	bitreich.org	70
i+ */	Err	bitreich.org	70
i+int        base64_decode(char const *, size_t *, char *, size_t *);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
1diff --git a/ical.c b/ical.c	/scm/ics2txt/file/ical.c.gph	bitreich.org	70
i@@ -9,14 +9,31 @@	Err	bitreich.org	70
i #include <strings.h>	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #include "util.h"	Err	bitreich.org	70
i+#include "base64.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static int	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i ical_error(IcalParser *p, char const *msg)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i         p->errmsg = msg;	Err	bitreich.org	70
i         return -1;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+ical_get_value(IcalParser *p, char *s, size_t *len)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        *len = strlen(s);	Err	bitreich.org	70
i+        if (p->base64)	Err	bitreich.org	70
i+                if (base64_decode(s, len, s, len) < 0)	Err	bitreich.org	70
i+                        return ical_error(p, "invalid base64 data");	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+ical_get_time(IcalParser *p, char *s, time_t *t)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        return -1;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i #define CALL(p, fn, ...) ((p)->fn ? (p)->fn((p), __VA_ARGS__) : 0)	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static int	Err	bitreich.org	70
i@@ -40,6 +57,8 @@ ical_parse_value(IcalParser *p, char **sp, char *name)	Err	bitreich.org	70
i         c = *s, *s = '\0';	Err	bitreich.org	70
i         if ((err = CALL(p, fn_param_value, name, val)) != 0)	Err	bitreich.org	70
i                 return err;	Err	bitreich.org	70
i+        if (strcasecmp(name, "ENCODING") == 0)	Err	bitreich.org	70
i+                p->base64 = (strcasecmp(val, "BASE64") == 0);	Err	bitreich.org	70
i         *s = c;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         *sp = s;	Err	bitreich.org	70
i@@ -90,6 +109,7 @@ ical_parse_contentline(IcalParser *p, char *line)	Err	bitreich.org	70
i         *s = c;	Err	bitreich.org	70
i         end = s;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+        p->base64 = 0;	Err	bitreich.org	70
i         while (*s == ';') {	Err	bitreich.org	70
i                 s++;	Err	bitreich.org	70
i                 if ((err = ical_parse_param(p, &s)) != 0)	Err	bitreich.org	70
1diff --git a/ical.h b/ical.h	/scm/ics2txt/file/ical.h.gph	bitreich.org	70
i@@ -15,7 +15,7 @@ struct IcalParser {	Err	bitreich.org	70
i         int (*fn_block_end)(IcalParser *, char *);	Err	bitreich.org	70
i         /* if returning non-zero then halt the parser */	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        int         base64encoded;	Err	bitreich.org	70
i+        int         base64;	Err	bitreich.org	70
i         char const *errmsg;	Err	bitreich.org	70
i         size_t         line;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i@@ -24,8 +24,9 @@ struct IcalParser {	Err	bitreich.org	70
i         char         stack[1024];	Err	bitreich.org	70
i };	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-int         ical_parse(IcalParser *, FILE *);	Err	bitreich.org	70
i-//TODO: char        *ical_get_time(char *);	Err	bitreich.org	70
i-//TODO: char        *ical_get_value(IcalCtx *, char *);	Err	bitreich.org	70
i+int        ical_parse(IcalParser *, FILE *);	Err	bitreich.org	70
i+int        ical_get_time(IcalParser *, char *, time_t *);	Err	bitreich.org	70
i+int        ical_get_value(IcalParser *, char *, size_t *);	Err	bitreich.org	70
i+int        ical_error(IcalParser *, char const *);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
1diff --git a/ics2tree.c b/ics2tree.c	/scm/ics2txt/file/ics2tree.c.gph	bitreich.org	70
i@@ -39,8 +39,11 @@ fn_param_value(IcalParser *p, char *name, char *value)	Err	bitreich.org	70
i static int	Err	bitreich.org	70
i fn_entry_value(IcalParser *p, char *name, char *value)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i+        size_t len;	Err	bitreich.org	70
i         (void)name;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+        if (ical_get_value(p, value, &len) < 0)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i         print_ruler(p->level + 1);	Err	bitreich.org	70
i         printf("value %s\n", value);	Err	bitreich.org	70
i         return 0;	Err	bitreich.org	70
i@@ -59,7 +62,7 @@ main(int argc, char **argv)	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         if (*argv == NULL) {	Err	bitreich.org	70
i                 if (ical_parse(&p, stdin) < 0)	Err	bitreich.org	70
i-                        err("parsing stdin:%d %s", p.line, p.errmsg);	Err	bitreich.org	70
i+                        err("parsing stdin:%d: %s", p.line, p.errmsg);	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         for (; *argv != NULL; argv++, argc--) {	Err	bitreich.org	70
1diff --git a/ics2tsv.c b/ics2tsv.c	/scm/ics2txt/file/ics2tsv.c.gph	bitreich.org	70
i@@ -1,59 +0,0 @@	Err	bitreich.org	70
i-#include <stdio.h>	Err	bitreich.org	70
i-#include <stdlib.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include "ical.h"	Err	bitreich.org	70
i-#include "log.h"	Err	bitreich.org	70
i-#include "util.h"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-print_ical_tsv(FILE *fp)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        struct ical_vcalendar vcal;	Err	bitreich.org	70
i-        int e;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if ((e = ical_read_vcalendar(&vcal, fp)) < 0)	Err	bitreich.org	70
i-                die("reading ical file: %s", ical_strerror(e));	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        ical_free_vcalendar(&vcal);	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-void	Err	bitreich.org	70
i-print_header(void)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        char *fields[] = { "", NULL };	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        printf("%s\t%s", "beg", "end");	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (char **f = fields; *f != NULL; f++) {	Err	bitreich.org	70
i-                fprintf(stdout, "\t%s", *f);	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-        fprintf(stdout, "\n");	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-main(int argc, char **argv)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        print_header();	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        log_arg0 = *argv++;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if (*argv == NULL) {	Err	bitreich.org	70
i-                if (print_ical_tsv(stdin) < 0)	Err	bitreich.org	70
i-                        die("converting stdin");	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (; *argv != NULL; argv++, argc--) {	Err	bitreich.org	70
i-                FILE *fp;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-                info("converting \"%s\"", *argv);	Err	bitreich.org	70
i-                if ((fp = fopen(*argv, "r")) == NULL)	Err	bitreich.org	70
i-                        die("opening %s", *argv);	Err	bitreich.org	70
i-                if (print_ical_tsv(fp) < 0)	Err	bitreich.org	70
i-                        die("converting %s", *argv);	Err	bitreich.org	70
i-                fclose(fp);	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
1diff --git a/util.c b/util.c	/scm/ics2txt/file/util.c.gph	bitreich.org	70
i@@ -49,7 +49,7 @@ debug(char const *fmt, ...)	Err	bitreich.org	70
i         va_list va;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         if (verbose < 0)	Err	bitreich.org	70
i-                verbose = (getenv("DEBUG") == NULL);	Err	bitreich.org	70
i+                verbose = (getenv("DEBUG") != NULL);	Err	bitreich.org	70
i         if (!verbose)	Err	bitreich.org	70
i                 return;	Err	bitreich.org	70
i         va_start(va, fmt);	Err	bitreich.org	70
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/ics2txt/commit/b72092250747c7...
Content-Typetext/plain; charset=utf-8