about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-12-11 00:35:35 -0500
committerJune McEnroe <june@causal.agency>2021-02-16 19:34:38 -0500
commitff0fbe914e2cb10c7df4819a68c5103588abd69f (patch)
tree2717d66eed50d8e8cff434bbf1f72253c75bddf4
parentRewrite main loop linearly (diff)
downloadimbox-ff0fbe914e2cb10c7df4819a68c5103588abd69f.tar.gz
imbox-ff0fbe914e2cb10c7df4819a68c5103588abd69f.zip
Add imapIdle
Handles re-IDLE-ing every 29 minutes and returns the first response it
gets.
-rw-r--r--imap.c22
-rw-r--r--imap.h1
2 files changed, 23 insertions, 0 deletions
diff --git a/imap.c b/imap.c
index e21141d..e875595 100644
--- a/imap.c
+++ b/imap.c
@@ -28,6 +28,7 @@
 #include <err.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#include <poll.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -265,3 +266,24 @@ struct Resp imapResp(struct IMAP *imap) {
 
 	return resp;
 }
+
+struct Resp imapIdle(struct IMAP *imap, enum Atom tag) {
+	for (;;) {
+		fprintf(imap->w, "%s IDLE\r\n", Atoms[tag]);
+		struct Resp resp = imapResp(imap);
+		if (resp.tag != AtomContinue) {
+			fprintf(imap->w, "DONE\r\n");
+			return resp;
+		}
+		respFree(resp);
+
+		struct pollfd pfd = { .fd = imap->sock, .events = POLLIN };
+		int ready = poll(&pfd, 1, 29 * 60 * 1000);
+		if (ready < 0) err(EX_IOERR, "poll");
+
+		fprintf(imap->w, "DONE\r\n");
+		resp = imapResp(imap);
+		if (ready || resp.tag != tag) return resp;
+		respFree(resp);
+	}
+}
diff --git a/imap.h b/imap.h
index 2730d1a..d4cc927 100644
--- a/imap.h
+++ b/imap.h
@@ -182,5 +182,6 @@ struct IMAP {
 
 struct IMAP imapOpen(const char *host, const char *port);
 struct Resp imapResp(struct IMAP *imap);
+struct Resp imapIdle(struct IMAP *imap, enum Atom tag);
 
 #endif /* IMAP_H */