summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--archive.c73
1 files changed, 40 insertions, 33 deletions
diff --git a/archive.c b/archive.c
index a3b7f84..ca2914f 100644
--- a/archive.c
+++ b/archive.c
@@ -140,9 +140,13 @@ int main(int argc, char *argv[]) {
 
 	FILE *imapRead, *imap;
 	imapOpen(&imapRead, &imap, host, port);
-	for (struct Resp resp; resp = imapResp(imapRead), resp.resp != AtomBye;) {
+	for (
+		struct Resp resp;
+		resp = imapResp(imapRead), resp.resp != AtomBye;
+		respFree(resp)
+	) {
 		if (resp.resp == AtomNo || resp.resp == AtomBad) {
-			errx(EX_CONFIG, "%s %s", Atoms[resp.resp], resp.text);
+			errx(EX_CONFIG, "%s: %s", Atoms[resp.tag], resp.text);
 		}
 
 		switch (state) {
@@ -161,37 +165,40 @@ int main(int argc, char *argv[]) {
 			}
 
 			break; case Examine: {
-				if (resp.resp == AtomOk && resp.code.len > 1) {
-					enum Atom code = dataCheck(resp.code.ptr[0], Atom).atom;
-					struct Data value = resp.code.ptr[1];
-					if (code == AtomUIDValidity) {
-						uint32_t validity = dataCheck(value, Number).number;
-						uint32_t previous = uidRead("UIDVALIDITY");
-						if (previous && validity != previous) {
-							errx(
-								EX_TEMPFAIL,
-								"UIDVALIDITY changed; fresh export required"
-							);
-						}
-						if (!previous) uidWrite("UIDVALIDITY", validity);
-					} else if (code == AtomUIDNext) {
-						uidNext = dataCheck(value, Number).number;
-						uint32_t prev = uidRead("UIDNEXT");
-						if (uidNext == prev) {
-							fprintf(imap, "ayy LOGOUT\r\n");
-							state = Logout;
-						} else {
-							exitStatus = EXIT_SUCCESS;
-						}
-					}
+				if (resp.tag == examine) {
+					fprintf(
+						imap, "%s UID THREAD %s UTF-8 %s\r\n",
+						Atoms[thread], algo, search
+					);
+					state = Thread;
+					break;
 				}
 
-				if (resp.tag != examine) break;
-				fprintf(
-					imap, "%s UID THREAD %s UTF-8 %s\r\n",
-					Atoms[thread], algo, search
-				);
-				state = Thread;
+				if (resp.resp != AtomOk || !resp.code.len) break;
+				enum Atom code = dataCheck(resp.code.ptr[0], Atom).atom;
+				struct Data value = resp.code.ptr[1];
+
+				if (code == AtomUIDValidity) {
+					uint32_t validity = dataCheck(value, Number).number;
+					uint32_t previous = uidRead("UIDVALIDITY");
+					if (previous && validity != previous) {
+						errx(
+							EX_TEMPFAIL,
+							"UIDVALIDITY changed; fresh export required"
+						);
+					}
+					if (!previous) uidWrite("UIDVALIDITY", validity);
+
+				} else if (code == AtomUIDNext) {
+					uidNext = dataCheck(value, Number).number;
+					uint32_t prev = uidRead("UIDNEXT");
+					if (uidNext == prev) {
+						fprintf(imap, "ayy LOGOUT\r\n");
+						state = Logout;
+					} else {
+						exitStatus = EXIT_SUCCESS;
+					}
+				}
 			}
 
 			break; case Thread: {
@@ -202,7 +209,7 @@ int main(int argc, char *argv[]) {
 				createDirs();
 
 				threads = resp.data;
-				resp.data = (struct List) {0};
+				resp.data = (struct List) {0}; // prevent freeing threads
 				envelopes = calloc(threads.len, sizeof(*envelopes));
 				if (!envelopes) err(EX_OSERR, "calloc");
 
@@ -229,6 +236,7 @@ int main(int argc, char *argv[]) {
 			break; case Concat: {
 				if (resp.resp == AtomFetch) {
 					if (!resp.data.len) errx(EX_PROTOCOL, "missing FETCH data");
+					// Prevent freeing data in envelopes:
 					struct Data items = dataTake(&resp.data.ptr[0]);
 					concatData(threads, envelopes, dataCheck(items, List).list);
 				}
@@ -242,7 +250,6 @@ int main(int argc, char *argv[]) {
 			
 			break; case Logout:;
 		}
-		respFree(resp);
 	}
 	fclose(imapRead);
 	fclose(imap);