about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--enroll.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/enroll.c b/enroll.c
index 62b72b7..7ef8e36 100644
--- a/enroll.c
+++ b/enroll.c
@@ -28,11 +28,13 @@
 #include <err.h>
 #include <errno.h>
 #include <limits.h>
+#include <netdb.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sysexits.h>
 #include <unistd.h>
@@ -119,6 +121,9 @@ static int yesno(bool *resp, bool def, const char *format, ...) {
 static struct {
 	char *network;
 	char *config;
+	char *host;
+	char *port;
+	struct addrinfo *addr;
 } info;
 
 static int getNetwork(const char *def) {
@@ -153,6 +158,7 @@ static int getConfig(const char *configHome) {
 		"The configuration will be written to: %s%s/catgirl\n",
 		info.network, prev, (suffix != configHome ? "~" : ""), suffix
 	);
+	free(name);
 	if (pop) return pop;
 
 	char path[PATH_MAX];
@@ -170,6 +176,57 @@ static int getConfig(const char *configHome) {
 	return 0;
 }
 
+static int srvLookup(char **host, char **port, const char *name) {
+	// TODO
+	return -1;
+}
+
+static int getHostPort(void) {
+	int error = srvLookup(&info.host, &info.port, info.network);
+	if (!error) {
+		log("Found SRV record %s:%s", info.host, info.port);
+		return 0;
+	}
+
+	char *ircdot = info.network;
+	if (strncmp(ircdot, "irc.", 4)) {
+		int n = asprintf(&ircdot, "irc.%s", ircdot);
+		if (n < 0) err(EX_OSERR, "asprintf");
+	}
+
+	int pop = prompt(
+		&info.host, ircdot,
+		"Which host should catgirl connect to?\n"
+		"Enter the hostname of the IRC server to connect to. Usually this\n"
+		"starts with \"irc.\".\n"
+	);
+	free(ircdot);
+	if (pop) return pop;
+
+	return prompt(
+		&info.port, "6697",
+		"Which port should catgirl connect to?\n"
+		"Enter the port number of the IRC server. This must be the port for\n"
+		"TLS, also called SSL.\n"
+	);
+}
+
+static int getAddr(void) {
+	log("Looking up %s:%s", info.host, info.port);
+	struct addrinfo hints = {
+		.ai_family = AF_UNSPEC,
+		.ai_socktype = SOCK_STREAM,
+		.ai_protocol = IPPROTO_TCP,
+	};
+	int error = getaddrinfo(info.host, info.port, &hints, &info.addr);
+	if (error) {
+		log("%s", gai_strerror(error));
+		printf("Could not find %s.\n", info.host);
+		return -1;
+	}
+	return 0;
+}
+
 static void unset(char **resp) {
 	free(*resp);
 	*resp = NULL;
@@ -214,22 +271,35 @@ int main(int argc, char *argv[]) {
 	int pop;
 	for (;;) {
 		if (!info.network) {
+			// TODO: Parse ircs: URL in args.
 			pop = getNetwork((optind < argc ? argv[optind] : NULL));
 			if (pop) return EX_USAGE;
 		} else if (!info.config) {
 			pop = getConfig(configHome);
 			if (pop) unset(&info.network);
+		} else if (!info.host || !info.port) {
+			pop = getHostPort();
+			if (pop) unset(&info.config);
+		} else if (!info.addr) {
+			pop = getAddr();
+			if (pop) {
+				unset(&info.host);
+				unset(&info.port);
+			}
 		} else {
 			break;
 		}
 	}
 
 	snprintf(path, sizeof(path), "%s/catgirl/%s", configHome, info.config);
-	log("Writing configuration to: %s", path);
+	log("Writing configuration to %s", path);
 	FILE *file = fopen(path, "w");
 	if (!file) err(EX_CANTCREAT, "%s", path);
 
-	fprintf(file, "host = %s\n", info.network); // FIXME: info.host
+	fprintf(file, "host = %s\n", info.host);
+	if (strcmp(info.port, "6697")) {
+		fprintf(file, "port = %s\n", info.port);
+	}
 
 	error = fclose(file);
 	if (error) err(EX_IOERR, "%s", path);