scribo

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.z3bra.org/scribo.git
Log | Files | Refs

commit c861c67c0042328d3fd4e4ef9163bfdaf9c6a47c
Author: Willy Goiffon <dev@z3bra.org>
Date:   Sun,  6 Sep 2020 18:46:56 +0200

Initial commit

Diffstat:
Amailog.c | 36++++++++++++++++++++++++++++++++++++
Amakefile | 6++++++
Arfc5322.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arfc5322.h | 14++++++++++++++
4 files changed, 149 insertions(+), 0 deletions(-)

diff --git a/mailog.c b/mailog.c @@ -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; +} diff --git a/makefile b/makefile @@ -0,0 +1,6 @@ +include config.mk + +mailog: mailog.o rfc5322.o + +clean: + rm -f mailog *.o diff --git a/rfc5322.c b/rfc5322.c @@ -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; +} diff --git a/rfc5322.h b/rfc5322.h @@ -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 *);