summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--imbox.16
-rw-r--r--imbox.c66
2 files changed, 69 insertions, 3 deletions
diff --git a/imbox.1 b/imbox.1
index c91abd8..a1efa90 100644
--- a/imbox.1
+++ b/imbox.1
@@ -67,7 +67,9 @@ Connect to IMAP on
 .Ar host .
 The default host is determined by SRV record lookup
 on the domain name of
-.Ar user .
+.Ar user ,
+or simply the domain name
+if no SRV record exists.
 .
 .It Fl m Ar mailbox
 Export messages from
@@ -95,7 +97,7 @@ Read the password from standard input.
 .
 .Sh EXAMPLES
 .Bd -literal
-imbox june@causal.agency | git am
+imbox -T list@example.org june@causal.agency | git am
 .Ed
 .
 .Sh SEE ALSO
diff --git a/imbox.c b/imbox.c
index 0328c34..f2c65e8 100644
--- a/imbox.c
+++ b/imbox.c
@@ -26,6 +26,14 @@
 #include <tls.h>
 #include <unistd.h>
 
+#ifndef DIG_PATH
+#	ifdef __FreeBSD__
+#		define DIG_PATH "/usr/bin/drill"
+#	else
+#		define DIG_PATH "dig"
+#	endif
+#endif
+
 static void compile(regex_t *regex, const char *pattern) {
 	if (regex->re_nsub) return;
 	int error = regcomp(regex, pattern, REG_EXTENDED | REG_NEWLINE);
@@ -83,6 +91,56 @@ static void mboxrd(const char *headers, const char *body) {
 #undef MATCH
 }
 
+static void lookup(const char **host, const char **port, const char *domain) {
+	static char buf[1024];
+	snprintf(buf, sizeof(buf), "_imaps._tcp.%s", domain);
+
+	int rw[2];
+	int error = pipe(rw);
+	if (error) err(EX_OSERR, "pipe");
+
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
+
+	if (!pid) {
+		close(rw[0]);
+		dup2(rw[1], STDOUT_FILENO);
+		dup2(rw[1], STDERR_FILENO);
+		close(rw[1]);
+		execlp(DIG_PATH, DIG_PATH, "-t", "SRV", "-q", buf, "+short", NULL);
+		err(EX_CONFIG, "%s", DIG_PATH);
+	}
+
+	int status;
+	pid = wait(&status);
+	if (pid < 0) err(EX_OSERR, "wait");
+
+	close(rw[1]);
+	FILE *pipe = fdopen(rw[0], "r");
+	if (!pipe) err(EX_IOERR, "fdopen");
+
+	fgets(buf, sizeof(buf), pipe);
+	if (ferror(pipe)) err(EX_IOERR, "fgets");
+	fclose(pipe);
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+		fprintf(stderr, "%s", buf);
+		exit(WEXITSTATUS(status));
+	}
+
+	char *ptr = buf;
+	char *dot = strrchr(ptr, '.');
+	if (dot) *dot = '\0';
+	strsep(&ptr, " \n"); // priority
+	strsep(&ptr, " \n"); // weight
+	*port = strsep(&ptr, " \n");
+	*host = strsep(&ptr, " \n");
+	if (!*host) {
+		*host = domain;
+		*port = "imaps";
+	}
+}
+
 static bool verbose;
 
 int tlsRead(void *_tls, char *ptr, int len) {
@@ -165,7 +223,7 @@ static char *readLiteral(FILE *imap, const char *line) {
 }
 
 int main(int argc, char *argv[]) {
-	const char *host = "imap.fastmail.com";
+	const char *host = NULL;
 	const char *port = "imaps";
 	const char *mailbox = "INBOX";
 	const char *subject = "[PATCH";
@@ -193,6 +251,12 @@ int main(int argc, char *argv[]) {
 	const char *user = argv[optind];
 	if (!user) errx(EX_USAGE, "username required");
 
+	if (!host) {
+		const char *domain = strchr(user, '@');
+		if (!domain) errx(EX_USAGE, "no domain in username");
+		lookup(&host, &port, &domain[1]);
+	}
+
 	char buf[1024];
 	char *pass = readpassphrase(
 		(rppFlags & RPP_STDIN ? "" : "Password: "),
f='/catgirl/commit/handle.c?h=twitch&id=3a325d3914e75bd079ad8df31ca4f39197519386&follow=1'>Handle RPL_AWAYJune McEnroe 2020-02-11Support monochromatic terminalsJune McEnroe Oops, division by zero! 2020-02-11Add .gz to chroot-man scriptJune McEnroe 2020-02-11Add -R restricted flagJune McEnroe 2020-02-11Add chroot targetJune McEnroe 2020-02-11Exit focus and paste modes on err exitJune McEnroe 2020-02-11Add startup GPLv3 note and URLJune McEnroe I am a degenerate. 2020-02-11Make sure -D_GNU_SOURCE ends up in CFLAGS on LinuxJune McEnroe 2020-02-11Add note about setting PKG_CONFIG_PATHJune McEnroe 2020-02-11Rename query ID on nick changeJune McEnroe 2020-02-11Call completeClear when closing a windowJune McEnroe 2020-02-11Don't insert color codes for non-mentionsJune McEnroe 2020-02-11Take first two words in colorMentionsJune McEnroe This lets phrases like "hi june" get colored, but still doesn't get carried away. 2020-02-11Use time_t for save signatureJune McEnroe It's actually more likely to be 64-bit than size_t anyway, and it eliminates some helper functions. Also don't error when reading an empty save file. 2020-02-11Set self.nick to * initiallyJune McEnroe Allows removing a bunch of checks that self.nick is set, and it's what the server usually calls you before registration. Never highlight notices as mentions. 2020-02-11Define ColorCap instead of hardcoding 100June McEnroe 2020-02-11Move hash to top of chat.hJune McEnroe 2020-02-11Move base64 out of chat.hJune McEnroe 2020-02-11Move XDG_SUBDIR out of chat.hJune McEnroe 2020-02-11Fix whois idle unit calculationJune McEnroe Rookie mistake. 2020-02-11Cast towupper to wchar_tJune McEnroe For some reason it takes and returns wint_t... 2020-02-11Cast set but unused variables to voidJune McEnroe 2020-02-11Declare strlcatJune McEnroe 2020-02-11Check if VDSUSP existsJune McEnroe 2020-02-11Fix completeReplace iterationJune McEnroe 2020-02-11Use pkg(8) to configure on FreeBSDJune McEnroe 2020-02-11Remove legacy codeJune McEnroe 2020-02-11Add INSTALLING section to READMEJune McEnroe