tInitial commit - scribo - Email-based phlog generator
HTML git clone git://git.z3bra.org/scribo.git
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit c861c67c0042328d3fd4e4ef9163bfdaf9c6a47c
HTML Author: Willy Goiffon <dev@z3bra.org>
Date: Sun, 6 Sep 2020 18:46:56 +0200
Initial commit
Diffstat:
A mailog.c | 36 +++++++++++++++++++++++++++++++
A makefile | 6 ++++++
A rfc5322.c | 93 +++++++++++++++++++++++++++++++
A rfc5322.h | 14 ++++++++++++++
4 files changed, 149 insertions(+), 0 deletions(-)
---
DIR diff --git a/mailog.c b/mailog.c
t@@ -0,0 +1,36 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/queue.h>
+
+#include "rfc5322.h"
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp = stdin;
+ struct header *p;
+ struct headers head = SLIST_HEAD_INITIALIZER(headers);
+ char buf[BUFSIZ];
+ size_t len;
+
+ if (argc > 1)
+ fp = fopen(argv[1], "r");
+
+ rfc5322_parse(fp, &head);
+
+ SLIST_FOREACH(p, &head, entries)
+ printf("%s: %s\n", p->field, p->body);
+
+ printf("\n");
+ while((len = fread(buf, 1, BUFSIZ, fp)))
+ printf("%s", buf);
+
+ fclose(fp);
+
+ return 0;
+}
DIR diff --git a/makefile b/makefile
t@@ -0,0 +1,6 @@
+include config.mk
+
+mailog: mailog.o rfc5322.o
+
+clean:
+ rm -f mailog *.o
DIR diff --git a/rfc5322.c b/rfc5322.c
t@@ -0,0 +1,93 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "rfc5322.h"
+
+struct header *
+rfc5322_header(char *s)
+{
+ char *f, *b;
+ struct header *h;
+
+ if (!(f = strsep(&s, ":")))
+ return NULL;
+
+ while (isblank(*s)) s++;
+
+ if (!(b = strsep(&s, "\r\n")))
+ return NULL;
+
+ if (!(h = calloc(sizeof(*h), 1)))
+ return NULL;
+
+ h->field = strdup(f);
+ h->body = strdup(b);
+
+ return h;
+}
+
+time_t
+rfc5322_date(const char *s)
+{
+ char *p;
+ struct tm tm = {.tm_isdst = -1};
+
+ p = strptime(s, "%a, %d %b %Y %T %z", &tm);
+ if (!p)
+ return -1;
+
+ return mktime(&tm);
+}
+
+int
+rfc5322_unfold(struct header *h, char *buf)
+{
+ char *l, *p;
+ size_t len;
+
+ l = strsep(&buf, "\r\n");
+ if (!l)
+ return -1;
+
+ len = strlen(h->body) + strlen(l);
+
+ p = realloc(h->body, len);
+ if (!p)
+ return -1;
+
+ strcat(p, l);
+
+ h->body = p;
+
+ return 0;
+}
+
+int
+rfc5322_parse(FILE *fp, struct headers *head)
+{
+ size_t bufsiz;
+ ssize_t len;
+ char *buf = NULL;
+ struct header *p = NULL;
+
+ while ((len = getline(&buf, &bufsiz, fp)) > 0) {
+ /* done parsin headers */
+ if (!strcmp(buf, "\n"))
+ break;
+
+ if (isblank(*buf)) {
+ rfc5322_unfold(p, buf);
+ } else {
+ p = rfc5322_header(buf);
+ if (p)
+ SLIST_INSERT_HEAD(head, p, entries);
+ }
+ }
+
+ free(buf);
+
+ return 0;
+}
DIR diff --git a/rfc5322.h b/rfc5322.h
t@@ -0,0 +1,14 @@
+#include <sys/queue.h>
+
+struct header {
+ char *field;
+ char *body;
+ SLIST_ENTRY(header) entries;
+};
+
+SLIST_HEAD(headers, header);
+
+time_t rfc5322_date(const char *);
+struct header *rfc5322_header(char *);
+int rfc5322_unfold(struct header *, char *);
+int rfc5322_parse(FILE *, struct headers *);