From a4ed715f7237b99aee25288af07f472882eba24c Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 14 Apr 2020 13:40:54 -0400 Subject: Build a list of body parts parallel to structure --- export.c | 36 +++++++++++++++++++++++++----------- imap.h | 7 +++++++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/export.c b/export.c index b34111f..952f72e 100644 --- a/export.c +++ b/export.c @@ -131,8 +131,9 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) { uint32_t uid = 0; struct Envelope envelope = {0}; struct BodyPart structure = {0}; - const char *header = NULL; - const char *text = NULL; + const char *bodyHeader = NULL; + const char *bodyText = NULL; + struct Data bodyParts = {0}; for (size_t i = 0; i + 1 < items.len; i += 2) { enum Atom name = dataCheck(items.ptr[i], Atom).atom; @@ -150,22 +151,34 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) { if (!section.len) { errx(EX_PROTOCOL, "missing body data item section"); } - if (i + 2 >= items.len) { + i++; + if (i + 1 >= items.len) { errx(EX_PROTOCOL, "missing body data item value"); } - data = items.ptr[++i + 1]; + data = items.ptr[i + 1]; if (section.ptr[0].type == Atom) { name = section.ptr[0].atom; if (name == AtomHeaderFields) { - header = dataCheck(data, String).string; + bodyHeader = dataCheck(data, String).string; } else if (name == AtomText) { - text = dataCheck(data, String).string; + bodyText = dataCheck(data, String).string; } continue; } - // TODO: Build a structure of body data parallel to structure. + data = dataTake(&items.ptr[i + 1]); + struct Data *dest = &bodyParts; + for (size_t i = 0; i < section.len; ++i) { + if (section.ptr[i].type != Number) continue; + uint32_t num = section.ptr[i].number; + *dest = (struct Data) { .type = List }; + while (dest->list.len < num) { + listPush(&dest->list, (struct Data) {0}); + } + dest = &dest->list.ptr[num - 1]; + *dest = data; + } } if (!uid) { @@ -177,14 +190,14 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) { bool fetch = false; if (envelope.subject) { - if (!header) { + if (!bodyHeader) { errx(EX_PROTOCOL, "missing BODY[HEADER.FIELDS] data item"); } - if (!text) { + if (!bodyText) { errx(EX_PROTOCOL, "missing BODY[TEXT] data item"); } - exportMbox(uid, &envelope, header, text); - exportAtom(uid, &envelope, &structure, text); + exportMbox(uid, &envelope, bodyHeader, bodyText); + exportAtom(uid, &envelope, &structure, bodyText); if (structure.multipart) { fetch = true; @@ -203,5 +216,6 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) { envelopeFree(envelope); bodyPartFree(structure); + dataFree(bodyParts); return fetch; } diff --git a/imap.h b/imap.h index 5919b8f..a2c13bd 100644 --- a/imap.h +++ b/imap.h @@ -117,6 +117,13 @@ static inline struct Data dataCheck(struct Data data, enum Type type) { return data; } +static inline struct Data dataTake(struct Data *from) { + struct Data take = *from; + from->type = Atom; + from->atom = AtomNil; + return take; +} + static inline void listPush(struct List *list, struct Data data) { if (list->len == list->cap) { list->cap = (list->cap ? list->cap * 2 : 4); -- cgit 1.4.1