diff options
author | June McEnroe <june@causal.agency> | 2020-04-17 14:25:07 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-04-17 14:25:07 -0400 |
commit | 37afe4cdee822627e42e61910e9e39995822f1c5 (patch) | |
tree | de6a971a177aa1a69b6a7b072ffa12c6f6da62b1 | |
parent | Ignore config.mk (diff) | |
download | bubger-37afe4cdee822627e42e61910e9e39995822f1c5.tar.gz bubger-37afe4cdee822627e42e61910e9e39995822f1c5.zip |
Choose text/plain from multipart/alternative
-rw-r--r-- | export.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/export.c b/export.c index ed594de..21f5662 100644 --- a/export.c +++ b/export.c @@ -19,6 +19,7 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <strings.h> #include <sysexits.h> #include <unistd.h> @@ -73,6 +74,12 @@ static void exportMbox( if (error) err(EX_CANTCREAT, "%s", msg); } +static bool isInline(const struct BodyPart *part) { + if (!bodyPartType(part, "text", "plain")) return false; + if (!part->disposition.type) return true; + return !strcasecmp(part->disposition.type, "inline"); +} + static void exportAtom( uint32_t uid, const struct Envelope *envelope, const struct BodyPart *structure, struct Data body @@ -90,15 +97,14 @@ static void exportAtom( body = dataCheck(body, List).list.ptr[0]; } if (bodyPartType(part, "multipart", "alternative")) { - for (size_t i = 0; i < part->parts.len; ++i) { - if (bodyPartType(&part->parts.ptr[i], "text", "plain")) { - part = &part->parts.ptr[i]; - body = dataCheck(body, List).list.ptr[i]; - break; - } + for (size_t i = part->parts.len - 1; i < part->parts.len; --i) { + if (!isInline(&part->parts.ptr[i])) continue; + part = &part->parts.ptr[i]; + body = dataCheck(body, List).list.ptr[i]; + break; } } - if (bodyPartType(part, "text", "plain")) { + if (isInline(part)) { char *content = decodeToString(part, dataCheck(body, String).string); error = atomContent(file, content); if (error) err(EX_IOERR, "%s", path); @@ -111,33 +117,43 @@ static void exportAtom( static int exportHTMLBody( FILE *file, struct List *section, - const struct BodyPart *structure, struct Data body + const struct BodyPart *part, struct Data body ) { int error = 0; - if (structure->multipart) { - // TODO: Choose a part from multipart/alternative. - for (size_t i = 0; i < structure->parts.len; ++i) { - struct Data part = { .type = Number, .number = 1 + i }; - listPush(section, part); + if (bodyPartType(part, "multipart", "alternative")) { + for (size_t i = part->parts.len - 1; i < part->parts.len; --i) { + if (!isInline(&part->parts.ptr[i])) continue; + return exportHTMLBody( + file, section, &part->parts.ptr[i], + dataCheck(body, List).list.ptr[i] + ); + } + return exportHTMLBody( + file, section, &part->parts.ptr[part->parts.len - 1], + dataCheck(body, List).list.ptr[part->parts.len - 1] + ); + } else if (part->multipart) { + for (size_t i = 0; i < part->parts.len; ++i) { + struct Data num = { .type = Number, .number = 1 + i }; + listPush(section, num); error = exportHTMLBody( - file, section, - &structure->parts.ptr[i], dataCheck(body, List).list.ptr[i] + file, section, &part->parts.ptr[i], + dataCheck(body, List).list.ptr[i] ); if (error) return error; section->len--; } - } else if (structure->message.envelope) { + } else if (part->message.envelope) { error = 0 - || htmlMessageOpen(file, structure->message.envelope) - || exportHTMLBody(file, section, structure->message.structure, body) + || htmlMessageOpen(file, part->message.envelope) + || exportHTMLBody(file, section, part->message.structure, body) || htmlMessageClose(file); - } else if (bodyPartType(structure, "text", "plain")) { - // TODO: Check if not inline. - char *content = decodeToString( - structure, dataCheck(body, String).string - ); - error = htmlInline(file, structure, content); + } else if (isInline(part)) { + char *content = decodeToString(part, dataCheck(body, String).string); + error = htmlInline(file, part, content); free(content); + } else { + // TODO: Write out attachment. } return error; } |