summary refs log tree commit diff
path: root/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'export.c')
-rw-r--r--export.c87
1 files changed, 51 insertions, 36 deletions
diff --git a/export.c b/export.c
index 0f35602..8fc82d8 100644
--- a/export.c
+++ b/export.c
@@ -60,15 +60,57 @@ bool exportFetch(FILE *imap, enum Atom tag, struct List threads) {
 	}
 	fprintf(
 		imap,
-		" (UID ENVELOPE"
+		" (UID ENVELOPE BODYSTRUCTURE"
 		" BODY[HEADER.FIELDS (" MBOX_HEADERS ")] BODY[TEXT])\r\n"
 	);
 	return true;
 }
 
-void exportData(struct List items) {
+static void exportEnvelope(
+	uint32_t uid, struct Envelope *envelope, char *header, char *body
+) {
+	const char *path;
+	FILE *file;
+	int error;
+
+	path = uidPath(uid, "mbox");
+	file = fopen(path, "w");
+	if (!file) err(EX_CANTCREAT, "%s", path);
+	error = 0
+		|| mboxFrom(file)
+		|| mboxHeader(file, header)
+		|| mboxBody(file, body)
+		|| fclose(file);
+	if (error) err(EX_IOERR, "%s", path);
+
+	const char *dest = messagePath(envelope->messageID, "mbox");
+	unlink(dest);
+	error = link(path, dest);
+	if (error) err(EX_CANTCREAT, "%s", dest);
+
+	path = uidPath(uid, "html");
+	file = fopen(path, "w");
+	if (!file) err(EX_CANTCREAT, "%s", path);
+	error = 0
+		|| htmlMessageHead(file, envelope)
+		|| htmlMessageTail(file)
+		|| fclose(file);
+	if (error) err(EX_IOERR, "%s", path);
+
+	path = uidPath(uid, "atom");
+	file = fopen(path, "w");
+	if (!file) err(EX_CANTCREAT, "%s", path);
+	error = 0
+		|| atomEntryHead(file, envelope)
+		|| atomEntryTail(file)
+		|| fclose(file);
+	if (error) err(EX_IOERR, "%s", path);
+}
+
+bool exportData(FILE *imap, enum Atom tag, struct List items) {
 	uint32_t uid = 0;
 	struct Envelope envelope = {0};
+	struct BodyPart structure = {0};
 	char *header = NULL;
 	char *body = NULL;
 
@@ -85,7 +127,7 @@ void exportData(struct List items) {
 		} else {
 			errx(EX_PROTOCOL, "invalid data item name");
 		}
-		
+
 		struct Data data = items.ptr[i + 1];
 		switch (name) {
 			break; case AtomBody:
@@ -94,6 +136,8 @@ void exportData(struct List items) {
 				uid = dataCheck(data, Number).number;
 			break; case AtomEnvelope:
 				parseEnvelope(&envelope, dataCheck(data, List).list);
+			break; case AtomBodyStructure:
+				parseBodyPart(&structure, dataCheck(data, List).list);
 			break; case AtomHeaderFields:
 				header = dataCheck(data, String).string;
 			break; case AtomText:
@@ -107,38 +151,9 @@ void exportData(struct List items) {
 	if (!header) errx(EX_PROTOCOL, "missing BODY[HEADER.FIELDS] data item");
 	if (!body) errx(EX_PROTOCOL, "missing BODY[TEXT] data item");
 
-	const char *path;
-	FILE *file;
-	int error;
-
-	path = uidPath(uid, "mbox");
-	file = fopen(path, "w");
-	if (!file) err(EX_CANTCREAT, "%s", path);
-	error = mboxFrom(file)
-		|| mboxHeader(file, header)
-		|| mboxBody(file, body)
-		|| fclose(file);
-	if (error) err(EX_IOERR, "%s", path);
-
-	const char *dest = messagePath(envelope.messageID, "mbox");
-	error = link(path, dest);
-	if (error) err(EX_CANTCREAT, "%s", dest);
-
-	path = uidPath(uid, "html");
-	file = fopen(path, "w");
-	if (!file) err(EX_CANTCREAT, "%s", path);
-	error = htmlMessageHead(file, &envelope)
-		|| htmlMessageTail(file)
-		|| fclose(file);
-	if (error) err(EX_IOERR, "%s", path);
-
-	path = uidPath(uid, "atom");
-	file = fopen(path, "w");
-	if (!file) err(EX_CANTCREAT, "%s", path);
-	error = atomEntryHead(file, &envelope)
-		|| atomEntryTail(file)
-		|| fclose(file);
-	if (error) err(EX_IOERR, "%s", path);
-
+	exportEnvelope(uid, &envelope, header, body);
 	envelopeFree(envelope);
+	bodyPartFree(structure);
+
+	return false;
 }