summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--export.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/export.c b/export.c
index fb26e74..c808ba8 100644
--- a/export.c
+++ b/export.c
@@ -30,6 +30,7 @@
 #include "imap.h"
 
 static const char *exportPath(uint32_t uid, const char *type) {
+	static char buf[PATH_MAX + 1];
 	char str[32];
 	snprintf(str, sizeof(str), "%" PRIu32, uid);
 	struct Variable vars[] = {
@@ -37,7 +38,6 @@ static const char *exportPath(uint32_t uid, const char *type) {
 		{ "type", type },
 		{0},
 	};
-	static char buf[PATH_MAX + 1];
 	templateBuffer(buf, sizeof(buf), PATH_UID, vars, escapePath);
 	return buf;
 }
@@ -62,6 +62,7 @@ bool exportFetch(FILE *imap, enum Atom tag, struct List threads) {
 	for (size_t i = 0; i < uids.len; ++i) {
 		fprintf(imap, "%s%" PRIu32, (i ? "," : ""), uids.ptr[i].number);
 	}
+	listFree(uids);
 	fprintf(
 		imap,
 		" (UID ENVELOPE BODYSTRUCTURE"
@@ -144,26 +145,34 @@ static void exportAtom(
 	if (error) err(EX_IOERR, "%s", path);
 }
 
-static int exportHTMLAttachment(
-	FILE *file, const struct Envelope *envelope, struct List *section,
-	const struct BodyPart *part, struct Data body
-) {
-	char buf[256] = "";
-	for (size_t i = 0; i < section->len; ++i) {
+static const char *sectionName(struct List section) {
+	static char buf[1024];
+	char str[32];
+	buf[0] = '\0';
+	for (size_t i = 0; i < section.len; ++i) {
 		snprintf(
-			&buf[strlen(buf)], sizeof(buf) - strlen(buf), "%s%" PRIu32,
-			(i ? "." : ""), dataCheck(section->ptr[i], Number).number
+			str, sizeof(str), "%s%" PRIu32,
+			(i ? "." : ""), dataCheck(section.ptr[i], Number).number
 		);
+		strlcat(buf, str, sizeof(buf));
 	}
+	return buf;
+}
+
+static int exportHTMLAttachment(
+	FILE *file, const struct Envelope *envelope, struct List section,
+	const struct BodyPart *part, struct Data body
+) {
 	const char *name = paramGet(part->disposition.params, "filename");
 	if (!name) name = paramGet(part->params, "name");
+
 	const char *disposition = part->disposition.type;
 	if (!disposition) disposition = "INLINE";
 
 	char path[PATH_MAX + 1];
 	struct Variable vars[] = {
 		{ "messageID", envelope->messageID },
-		{ "section", buf },
+		{ "section", sectionName(section) },
 		{ "name", (name ? name : "") },
 		{ "disposition", (name ? "" : disposition) },
 		{ ".", (name ? "" : ".") },
@@ -212,13 +221,11 @@ static int exportHTMLBody(
 		int error;
 		bool attached = false;
 		for (size_t i = 0; i < part->parts.len; ++i) {
-			if (!attached && isAttachment(&part->parts.ptr[i])) {
-				attached = true;
-				error = htmlAttachmentOpen(file);
-				if (error) return error;
-			} else if (attached && !isAttachment(&part->parts.ptr[i])) {
-				attached = false;
-				error = htmlAttachmentClose(file);
+			if (attached != isAttachment(&part->parts.ptr[i])) {
+				attached ^= true;
+				error = attached
+					? htmlAttachmentOpen(file)
+					: htmlAttachmentClose(file);
 				if (error) return error;
 			}
 			struct Data num = { .type = Number, .number = 1 + i };
@@ -230,11 +237,7 @@ static int exportHTMLBody(
 			if (error) return error;
 			section->len--;
 		}
-		if (attached) {
-			return htmlAttachmentClose(file);
-		} else {
-			return 0;
-		}
+		return (attached ? htmlAttachmentClose(file) : 0);
 
 	} else if (part->message.structure) {
 		const struct BodyPart *structure = part->message.structure;
@@ -251,7 +254,7 @@ static int exportHTMLBody(
 		return error;
 
 	} else {
-		return exportHTMLAttachment(file, envelope, section, part, body);
+		return exportHTMLAttachment(file, envelope, *section, part, body);
 	}
 }
 
@@ -291,14 +294,10 @@ static void fetchParts(
 	) {
 		fetchParts(imap, section, structure->message.structure);
 	} else {
-		fprintf(imap, " BODY[");
-		for (size_t i = 0; i < section->len; ++i) {
-			fprintf(imap, "%s%" PRIu32, (i ? "." : ""), section->ptr[i].number);
-		}
-		if (structure->message.structure) {
-			fprintf(imap, ".TEXT");
-		}
-		fprintf(imap, "]");
+		fprintf(
+			imap, " BODY[%s%s]",
+			sectionName(*section), (structure->message.structure ? ".TEXT" : "")
+		);
 	}
 }
 
@@ -373,6 +372,7 @@ bool exportData(FILE *imap, enum Atom tag, struct List items) {
 			}
 			dest = &dest->list.ptr[num - 1];
 		}
+		// Free with bodyParts:
 		*dest = dataTake(&items.ptr[i + 1]);
 	}