summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--imbox.18
-rw-r--r--imbox.c12
2 files changed, 16 insertions, 4 deletions
diff --git a/imbox.1 b/imbox.1
index 4a0c34f..a8d1dcd 100644
--- a/imbox.1
+++ b/imbox.1
@@ -1,4 +1,4 @@
-.Dd December  4, 2020
+.Dd February 16, 2021
 .Dt IMBOX 1
 .Os
 .
@@ -8,7 +8,7 @@
 .
 .Sh SYNOPSIS
 .Nm
-.Op Fl vw
+.Op Fl ivw
 .Op Fl C Ar cc
 .Op Fl F Ar from
 .Op Fl S Ar subject
@@ -71,6 +71,10 @@ on the domain name of
 or simply the domain name
 if no SRV record exists.
 .
+.It Fl i
+If no messages initially match the criteria,
+wait for new messages using IMAP IDLE.
+.
 .It Fl m Ar mailbox
 Export messages from
 .Ar mailbox .
diff --git a/imbox.c b/imbox.c
index f1ed24a..1852815 100644
--- a/imbox.c
+++ b/imbox.c
@@ -27,6 +27,7 @@
 
 #include <err.h>
 #include <inttypes.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -74,16 +75,18 @@ int main(int argc, char *argv[]) {
 	const char *from = NULL;
 	const char *to = NULL;
 	const char *cc = NULL;
+	bool idle = false;
 	int rppFlags = 0;
 
 	int opt;
-	while (0 < (opt = getopt(argc, argv, "C:F:S:T:h:m:p:vw"))) {
+	while (0 < (opt = getopt(argc, argv, "C:F:S:T:h:im:p:vw"))) {
 		switch (opt) {
 			break; case 'C': cc = optarg;
 			break; case 'F': from = optarg;
 			break; case 'S': subject = optarg;
 			break; case 'T': to = optarg;
 			break; case 'h': host = optarg;
+			break; case 'i': idle = true;
 			break; case 'm': mailbox = optarg;
 			break; case 'p': port = optarg;
 			break; case 'v': imapVerbose = true;
@@ -122,6 +125,7 @@ int main(int argc, char *argv[]) {
 	for (; resp = respOk(imapResp(&imap)), resp.tag != examine; respFree(resp));
 	respFree(resp);
 
+search:;
 	struct List nums = {0};
 	enum Atom search = atom("search");
 	fprintf(imap.w, "%s SEARCH CHARSET UTF-8", Atoms[search]);
@@ -132,11 +136,15 @@ int main(int argc, char *argv[]) {
 	fprintf(imap.w, "\r\n");
 	for (; resp = respOk(imapResp(&imap)), resp.tag != search; respFree(resp)) {
 		if (resp.resp != AtomSearch) continue;
-		if (!resp.data.len) errx(EX_TEMPFAIL, "no matching messages");
 		nums = resp.data;
 		resp.data = (struct List) {0};
 	}
 	respFree(resp);
+	if (!nums.len) {
+		if (!idle) errx(EX_TEMPFAIL, "no matching messages");
+		respFree(respOk(imapIdle(&imap, atom("idle"))));
+		goto search;
+	}
 
 	enum Atom fetch = atom("fetch");
 	fprintf(imap.w, "%s FETCH ", Atoms[fetch]);