summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-05-01 17:31:58 -0400
committerJune McEnroe <june@causal.agency>2020-05-01 17:31:58 -0400
commitabb44ad860efa34ab19e1fad44a0c4d1dff28dfe (patch)
tree56050aa529a8a26a04379b0d6036b9173f9b56ee
parentUpdate IMAP parser (diff)
downloadimbox-abb44ad860efa34ab19e1fad44a0c4d1dff28dfe.tar.gz
imbox-abb44ad860efa34ab19e1fad44a0c4d1dff28dfe.zip
Simplify imbox code and remove text/plain restriction
-rw-r--r--imbox.17
-rw-r--r--imbox.c52
2 files changed, 18 insertions, 41 deletions
diff --git a/imbox.1 b/imbox.1
index 1d3d648..ff10932 100644
--- a/imbox.1
+++ b/imbox.1
@@ -1,4 +1,4 @@
-.Dd December 23, 2019
+.Dd May  1, 2020
 .Dt IMBOX 1
 .Os
 .
@@ -132,11 +132,6 @@ imbox -T list@example.org june@causal.agency | git am
 .Sh AUTHORS
 .An June Bug Aq Mt june@causal.agency
 .
-.Sh CAVEATS
-The
-.Nm
-utility only exports plain-text messages.
-.
 .Sh BUGS
 Send mail to
 .Aq Mt june@causal.agency
diff --git a/imbox.c b/imbox.c
index a37b24d..4770e86 100644
--- a/imbox.c
+++ b/imbox.c
@@ -40,14 +40,15 @@
 #endif
 
 #define FETCH_HEADERS \
-	"Date From To Cc Subject Message-Id In-Reply-To References " \
-	"Content-Transfer-Encoding"
+	"Date Subject From Sender Reply-To To Cc Bcc " \
+	"Message-Id In-Reply-To References " \
+	"MIME-Version Content-Type Content-Disposition Content-Transfer-Encoding"
 
-static void mboxrd(char *headers, char *body) {
+static void mboxrd(char *header, char *body) {
 	printf("From mboxrd@z Thu Jan  1 00:00:00 1970\n");
-	for (char *crlf; (crlf = strstr(headers, "\r\n")); headers = &crlf[2]) {
+	for (char *crlf; (crlf = strstr(header, "\r\n")); header = &crlf[2]) {
 		*crlf = '\0';
-		printf("%s\n", headers);
+		printf("%s\n", header);
 	}
 	for (char *crlf; (crlf = strstr(body, "\r\n")); body = &crlf[2]) {
 		*crlf = '\0';
@@ -197,13 +198,7 @@ int main(int argc, char *argv[]) {
 		}
 
 		if (resp.tag == examine) {
-			fprintf(
-				imap,
-				"%s SEARCH CHARSET UTF-8 OR "
-				"NOT HEADER Content-Type \"\" "
-				"HEADER Content-Type \"text/plain\"",
-				Atoms[AtomSearch]
-			);
+			fprintf(imap, "%s SEARCH CHARSET UTF-8", Atoms[AtomSearch]);
 			if (subject) fprintf(imap, " SUBJECT \"%s\"", subject);
 			if (from) fprintf(imap, " FROM \"%s\"", from);
 			if (to) fprintf(imap, " TO \"%s\"", to);
@@ -215,11 +210,8 @@ int main(int argc, char *argv[]) {
 			if (!resp.data.len) errx(EX_TEMPFAIL, "no matching messages");
 			fprintf(imap, "%s FETCH ", Atoms[AtomFetch]);
 			for (size_t i = 0; i < resp.data.len; ++i) {
-				struct Data data = resp.data.ptr[i];
-				if (data.type != Number) {
-					errx(EX_PROTOCOL, "invalid search result");
-				}
-				fprintf(imap, "%s%" PRIu32, (i ? "," : ""), data.number);
+				uint32_t num = dataCheck(resp.data.ptr[i], Number).number;
+				fprintf(imap, "%s%" PRIu32, (i ? "," : ""), num);
 			}
 			fprintf(
 				imap,
@@ -228,36 +220,26 @@ int main(int argc, char *argv[]) {
 		}
 
 		if (resp.resp == AtomFetch) {
-			if (!resp.data.len) {
-				errx(EX_PROTOCOL, "no fetch data");
-			}
-			if (resp.data.ptr[0].type != List) {
-				errx(EX_PROTOCOL, "invalid fetch data");
-			}
-
-			struct Data headers = {0};
+			if (!resp.data.len) errx(EX_PROTOCOL, "missing fetch data");
+			struct List items = dataCheck(resp.data.ptr[0], List).list;
+			struct Data header = {0};
 			struct Data body = {0};
-			struct List items = resp.data.ptr[0].list;
 			for (size_t i = 0; i < items.len; ++i) {
 				struct Data item = items.ptr[i];
 				if (item.type != List) continue;
 				if (!item.list.len) continue;
 				if (item.list.ptr[0].type != Atom) continue;
 				if (item.list.ptr[0].atom == AtomHeader) {
-					if (i + 1 < items.len) headers = items.ptr[i + 1];
+					if (i + 1 < items.len) header = items.ptr[i + 1];
 				}
 				if (item.list.ptr[0].atom == AtomText) {
 					if (i + 1 < items.len) body = items.ptr[i + 1];
 				}
 			}
-
-			if (headers.type != String) {
-				errx(EX_PROTOCOL, "invalid header data");
-			}
-			if (body.type != String) {
-				errx(EX_PROTOCOL, "invalid body data");
-			}
-			mboxrd(headers.string, body.string);
+			mboxrd(
+				dataCheck(header, String).string,
+				dataCheck(body, String).string
+			);
 		}
 
 		if (resp.tag == AtomFetch) {