Commit Diff


commit - 4070540ca2491cdbe09ad5ec39f602e34883f7aa
commit + 7d9bde6e7a005dfe5d4ee78278f3d231717a955f
blob - efd320241a1163f5806321964b08e8f60b4737ed
blob + 2d8dcf4204b45e80e712fd25347a20129528eeca
--- icbirc.c
+++ icbirc.c
@@ -55,8 +55,6 @@ void		icbirc_quit(void);
 int		sync_write(int, const char *, int);
 static void	usage(void);
 
-static struct sockaddr_in sa_connect;
-
 time_t t;
 unsigned long bytes_in, bytes_out;
 
@@ -74,10 +72,10 @@ int
 main(int argc, char *argv[])
 {
 	struct pollfd pfds[2], *pirc, *picb;
-	const char *addr_connect = NULL;
+	struct addrinfo hints, *res, *res0;
+	const char *host, *cause = NULL;
 	char *port, *room;
-	unsigned port_connect = 7326;
-	int ch;
+	int ch, error, save_errno;
 	int listen_fd = -1, server_fd = -1;
 
 #ifdef __OpenBSD__
@@ -97,55 +95,58 @@ main(int argc, char *argv[])
 	if (argc != 1)
 		usage();
 
+	signal(SIGPIPE, SIG_IGN);
+	if (fcntl(0, F_SETFL, fcntl(listen_fd, F_GETFL) | O_NONBLOCK))
+		err(1, "fcntl");
+
 	if ((port = strchr(argv[0], ':')) != NULL) {
 		*port++ = '\0';
 		if ((room = strchr(port, '/')) != NULL) {
 			*room++ = '\0';
 			strlcpy(irc_pass, room, sizeof(irc_pass));
 		}
-		port_connect = atoi(port);
 	} else if ((room = strchr(argv[0], '/')) != NULL) {
 		*room++ = '\0';
 		strlcpy(irc_pass, room, sizeof(irc_pass));
 	}
-	addr_connect = argv[0];
+	host = argv[0];
+	if (port == NULL)
+		port = "7326";
 
-	memset(&sa_connect, 0, sizeof(sa_connect));
-	sa_connect.sin_family = AF_INET;
-	sa_connect.sin_addr.s_addr = inet_addr(addr_connect);
-	if (sa_connect.sin_addr.s_addr == INADDR_NONE) {
-		struct hostent *h;
+	t = time(NULL);
 
-		if ((h = gethostbyname(addr_connect)) == NULL)
-			errx(1, "gethostbyname: %s: %s\n",
-			    addr_connect, hstrerror(h_errno));
-		memcpy(&sa_connect.sin_addr.s_addr, h->h_addr,
-		    sizeof(in_addr_t));
-	}
-	sa_connect.sin_port = htons(port_connect);
+	fprintf(stderr, "connecting to server %s:%s\n", host, port);
+	irc_send_notice(1, "*** Connecting to server %s:%s", host, port);
 
-	if (fcntl(0, F_SETFL, fcntl(listen_fd, F_GETFL) | O_NONBLOCK))
-		err(1, "fcntl");
-
-	signal(SIGPIPE, SIG_IGN);
-
-	t = time(NULL);
-	bytes_in = bytes_out = 0;
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	error = getaddrinfo(host, port, &hints, &res0);
+	if (error)
+		errx(1, "can't resolve %s: %s", host, gai_strerror(error));
 
-	fprintf(stderr, "connecting to server %s:%u\n",
-	    inet_ntoa(sa_connect.sin_addr), ntohs(sa_connect.sin_port));
-	irc_send_notice(1, "*** Connecting to server %s:%u",
-	    inet_ntoa(sa_connect.sin_addr), ntohs(sa_connect.sin_port));
-	if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-		err(1, "socket");
-	if (connect(server_fd, (struct sockaddr *)&sa_connect,
-	    sizeof(sa_connect))) {
-		warn("connect");
-		irc_send_notice(1, "*** Error: connect: %s",
-		    strerror(errno));
-		close(server_fd);
-		exit(1);
+	for (res = res0; res; res = res->ai_next) {
+		server_fd = socket(res->ai_family, res->ai_socktype,
+			res->ai_protocol);
+		if (server_fd == -1) {
+			cause = "socket";
+			continue;
+		}
+
+		if (connect(server_fd, res->ai_addr, res->ai_addrlen) == -1) {
+			cause = "connect";
+			save_errno = errno;
+			close(server_fd);
+			errno = save_errno;
+			server_fd = -1;
+			continue;
+		}
+
+		break;
 	}
+	freeaddrinfo(res0);
+	if (server_fd == -1)
+		err(1, "%s", cause);
 
 	if (fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_NONBLOCK))
 		err(1, "fcntl");