From 1e302b4e07d5229869821aa6240520420304d3f1 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Thu, 9 Apr 2020 16:37:28 -0400 Subject: Export mbox files --- archive.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 6 deletions(-) (limited to 'archive.c') diff --git a/archive.c b/archive.c index cdfd982..497b5a6 100644 --- a/archive.c +++ b/archive.c @@ -75,7 +75,13 @@ static enum Atom fetchNew(FILE *imap, struct List threads) { for (size_t i = 0; i < uids.len; ++i) { fprintf(imap, "%s%" PRIu32, (i ? "," : ""), uids.ptr[i].number); } - fprintf(imap, " (UID ENVELOPE)\r\n"); + fprintf( + imap, + " (" + "UID ENVELOPE " + "BODY[HEADER.FIELDS (" MBOX_HEADERS ")] BODY[TEXT]" + ")\r\n" + ); done: listFree(uids); @@ -167,19 +173,37 @@ static struct Envelope parseEnvelope(struct List list) { } static void exportMessage(struct List items) { - static enum Atom AtomUID; - static enum Atom AtomEnvelope; + static enum Atom AtomUID, AtomEnvelope, AtomBody; + static enum Atom AtomHeaderFields, AtomText; if (!AtomUID) AtomUID = atom("UID"); if (!AtomEnvelope) AtomEnvelope = atom("ENVELOPE"); + if (!AtomBody) AtomBody = atom("BODY"); + if (!AtomHeaderFields) AtomHeaderFields = atom("HEADER.FIELDS"); + if (!AtomText) AtomText = atom("TEXT"); uint32_t uid = 0; struct Envelope envelope = {0}; + char *header = NULL; + char *body = NULL; + for (size_t i = 0; i + 1 < items.len; i += 2) { - if (items.ptr[i].type != Atom) { + enum Atom name; + if (items.ptr[i].type == Atom) { + name = items.ptr[i].atom; + } else if ( + items.ptr[i].type == List && + items.ptr[i].list.len && + items.ptr[i].list.ptr[0].type == Atom + ) { + name = items.ptr[i].list.ptr[0].atom; + } else { errx(EX_PROTOCOL, "invalid data item name"); } - enum Atom name = items.ptr[i].atom; - if (name == AtomUID) { + + if (name == AtomBody) { + i--; + continue; + } else if (name == AtomUID) { if (items.ptr[i + 1].type != Number) { errx(EX_PROTOCOL, "invalid UID data item value"); } @@ -189,10 +213,33 @@ static void exportMessage(struct List items) { errx(EX_PROTOCOL, "invalid ENVELOPE data item value"); } envelope = parseEnvelope(items.ptr[i + 1].list); + } else if (name == AtomHeaderFields) { + if (items.ptr[i + 1].type != String) { + errx(EX_PROTOCOL, "invalid BODY[HEADER.FIELDS] data item value"); + } + header = items.ptr[i + 1].string; + } else if (name == AtomText) { + if (items.ptr[i + 1].type != String) { + errx(EX_PROTOCOL, "invalid BODY[TEXT] data item value"); + } + body = items.ptr[i + 1].string; } } + if (!uid) errx(EX_PROTOCOL, "missing UID data item"); if (!envelope.subject) errx(EX_PROTOCOL, "missing ENVELOPE data item"); + if (!header) errx(EX_PROTOCOL, "missing BODY[HEADER.FIELDS] data item"); + if (!body) errx(EX_PROTOCOL, "missing BODY[TEXT] data item"); + + const char *path = uidPath(uid, "mbox"); + FILE *file = fopen(path, "w"); + if (!file) err(EX_CANTCREAT, "%s", path); + + int error = mboxFrom(file) + || mboxHeader(file, header) + || mboxBody(file, body) + || fclose(file); + if (error) err(EX_IOERR, "%s", path); envelopeFree(envelope); } -- cgit 1.4.1