Commit Diff


commit - fbe4e593edbbed17c1d7b84d42312cd749b3f79e
commit + 3e0dfc1698580979b40e0c5604db07e59b63b0e3
blob - 2e689513d7490efa18d0e5e5a78d6f4a23c0cdf6
blob + 9cdf01853cb5fe6445274adef51b199a311c4223
--- icbirc.c
+++ icbirc.c
@@ -36,6 +36,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <ctype.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <netdb.h>
@@ -51,7 +52,6 @@
 
 int		sync_write(int, const char *, int);
 static void	usage(void);
-static void	handle_client(int);
 
 int terminate_client;
 static struct sockaddr_in sa_connect;
@@ -70,25 +70,23 @@ int
 main(int argc, char *argv[])
 {
 	int debug = 0;
-	const char *addr_listen = NULL, *addr_connect = NULL;
-	unsigned port_listen = 6667, port_connect = 7326;
+	const char *addr_connect = NULL;
+	unsigned port_connect = 7326;
 	int ch;
-	int listen_fd = -1;
-	struct sockaddr_in sa;
-	socklen_t len;
-	int val;
+	int listen_fd = -1, server_fd = -1;
+	time_t t;
+	unsigned long bytes_in, bytes_out;
 
-	while ((ch = getopt(argc, argv, "dl:p:s:P:")) != -1) {
+#ifdef __OpenBSD__
+	if (pledge("stdio inet dns", NULL) == -1)
+		err(1, "pledge");
+#endif /* __OpenBSD__ */
+
+	while ((ch = getopt(argc, argv, "dp:s:P:")) != -1) {
 		switch (ch) {
 		case 'd':
 			debug++;
 			break;
-		case 'l':
-			addr_listen = optarg;
-			break;
-		case 'p':
-			port_listen = atoi(optarg);
-			break;
 		case 's':
 			addr_connect = optarg;
 			break;
@@ -109,175 +107,63 @@ main(int argc, char *argv[])
 	if (sa_connect.sin_addr.s_addr == INADDR_NONE) {
 		struct hostent *h;
 
-		if ((h = gethostbyname(addr_connect)) == NULL) {
-			fprintf(stderr, "gethostbyname: %s: %s\n",
+		if ((h = gethostbyname(addr_connect)) == NULL)
+			errx(1, "gethostbyname: %s: %s\n",
 			    addr_connect, hstrerror(h_errno));
-			goto error;
-		}
 		memcpy(&sa_connect.sin_addr.s_addr, h->h_addr,
 		    sizeof(in_addr_t));
 	}
 	sa_connect.sin_port = htons(port_connect);
 
-	if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		perror("socket");
-		goto error;
-	}
+	if (fcntl(0, F_SETFL, fcntl(listen_fd, F_GETFL) | O_NONBLOCK))
+		err(1, "fcntl");
 
-	if (fcntl(listen_fd, F_SETFL, fcntl(listen_fd, F_GETFL) |
-	    O_NONBLOCK)) {
-		perror("fcntl");
-		goto error;
-	}
-
-        val = 1;
-        if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
-	    (const char *)&val, sizeof(val))) {
-		perror("setsockopt");
-		goto error;
-        }
-
-	memset(&sa, 0, sizeof(sa));
-	sa.sin_family = AF_INET;
-	if (addr_listen != NULL)
-		sa.sin_addr.s_addr = inet_addr(addr_listen);
-	else
-		sa.sin_addr.s_addr = INADDR_ANY;
-	sa.sin_port = htons(port_listen);
-        if (bind(listen_fd, (const struct sockaddr *)&sa, sizeof(sa))) {
-		fprintf(stderr, "bind %s:%u: %s\n", inet_ntoa(sa.sin_addr),
-		    ntohs(sa.sin_port), strerror(errno));
-		goto error;
-        }
-
-        if (listen(listen_fd, 1)) {
-		perror("listen");
-		goto error;
-        }
-
-	if (!debug && daemon(0, 0)) {
-		perror("daemon");
-		goto error;
-	}
 	signal(SIGPIPE, SIG_IGN);
-
-#ifdef __OpenBSD__
-	if (pledge("stdio inet dns", NULL) == -1) {
-		perror("pledge");
-		goto error;
-	}
-#endif /* __OpenBSD__ */
-
-	/* handle incoming client connections */
-	while (1) {
-		fd_set readfds;
-		struct timeval tv;
-		int r;
-
-		FD_ZERO(&readfds);
-		FD_SET(listen_fd, &readfds);
-		memset(&tv, 0, sizeof(tv));
-		tv.tv_sec = 10;
-		r = select(listen_fd + 1, &readfds, NULL, NULL, &tv);
-		if (r < 0) {
-			if (errno != EINTR) {
-				perror("select");
-				break;
-			}
-			continue;
-		}
-		if (r > 0 && FD_ISSET(listen_fd, &readfds)) {
-			int client_fd;
-
-			memset(&sa, 0, sizeof(sa));
-			len = sizeof(sa);
-			client_fd = accept(listen_fd,
-			    (struct sockaddr *)&sa, &len);
-			if (client_fd < 0) {
-				if (errno != ECONNABORTED) {
-					perror("accept");
-					break;
-				}
-				continue;
-			}
-			printf("client connection from %s:%i\n",
-			    inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
-			handle_client(client_fd);
-			close(client_fd);
-		}
-	}
 
-	close(listen_fd);
-	return (0);
-
-error:
-	if (listen_fd)
-		close(listen_fd);
-
-	return (1);
-}
-
-static void
-handle_client(int client_fd)
-{
-	int server_fd;
-	int max_fd;
-	time_t t;
-	unsigned long bytes_in, bytes_out;
-
 	t = time(NULL);
 	bytes_in = bytes_out = 0;
-	irc_pass[0] = irc_nick[0] = irc_ident[0] = irc_channel[0] = 0;
-	icb_logged_in = 0;
-	terminate_client = 1;
 
-	printf("connecting to server %s:%u\n",
+	fprintf(stderr, "connecting to server %s:%u\n",
 	    inet_ntoa(sa_connect.sin_addr), ntohs(sa_connect.sin_port));
-	irc_send_notice(client_fd, "*** Connecting to server %s:%u",
+	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) {
-		perror("socket");
-		goto done;
-	}
+	if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+		err(1, "socket");
 	if (connect(server_fd, (struct sockaddr *)&sa_connect,
 	    sizeof(sa_connect))) {
-		perror("connect");
-		irc_send_notice(client_fd, "*** Error: connect: %s",
+		warn("connect");
+		irc_send_notice(1, "*** Error: connect: %s",
 		    strerror(errno));
 		close(server_fd);
-		goto done;
+		exit(1);
 	}
 
-	if (fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_NONBLOCK) ||
-	    fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL) | O_NONBLOCK)) {
-		perror("fcntl");
-		goto done;
-	}
+	if (fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_NONBLOCK))
+		err(1, "fcntl");
 
-	if (client_fd > server_fd)
-		max_fd = client_fd;
-	else
-		max_fd = server_fd;
+#ifdef __OpenBSD__
+	/* drop inet dns */
+	if (pledge("stdio", NULL) == -1)
+		err(1, "pledge");
+#endif /* __OpenBSD__ */
 
-	irc_send_notice(client_fd, "*** Connected");
-	terminate_client = 0;
+	irc_send_notice(1, "*** Connected");
 	icb_init();
-	while (!terminate_client) {
+
+	for (;;) {
 		fd_set readfds;
 		struct timeval tv;
 		int r;
 
 		FD_ZERO(&readfds);
 		FD_SET(server_fd, &readfds);
-		FD_SET(client_fd, &readfds);
+		FD_SET(0, &readfds);
 		memset(&tv, 0, sizeof(tv));
                 tv.tv_sec = 10;
-                r = select(max_fd + 1, &readfds, NULL, NULL, &tv);
+                r = select(server_fd + 1, &readfds, NULL, NULL, &tv);
                 if (r < 0) {
-			if (errno != EINTR) {
-				perror("select");
-				break;
-			}
+			if (errno != EINTR)
+				err(1, "select");
 			continue;
 		}
 		if (r > 0) {
@@ -289,45 +175,39 @@ handle_client(int client_fd)
 				if (len < 0) {
 					if (errno == EINTR)
 						continue;
-					perror("read");
+					warnx("read");
 					len = 0;
 				}
 				if (len == 0) {
-					printf("connection closed by server\n");
-					irc_send_notice(client_fd,
-					    "*** Connection closed by server");
+					warnx("connection closed by server");
+					irc_send_notice(1, "*** Connection "
+					    "closed by server");
 					break;
 				}
-				icb_recv(buf, len, client_fd, server_fd);
+				icb_recv(buf, len, 0, server_fd);
 				bytes_in += len;
 			}
-			if (FD_ISSET(client_fd, &readfds)) {
-				len = read(client_fd, buf, sizeof(buf));
+			if (FD_ISSET(0, &readfds)) {
+				len = read(0, buf, sizeof(buf));
 				if (len < 0) {
 					if (errno == EINTR)
 						continue;
-					perror("read");
+					warnx("read");
 					len = 0;
 				}
 				if (len == 0) {
-					printf("connection closed by client\n");
+					warnx("connection closed by client\n");
 					break;
 				}
-				irc_recv(buf, len, client_fd, server_fd);
+				irc_recv(buf, len, 1, server_fd);
 				bytes_out += len;
 			}
 		}
 	}
 
-done:
-	if (server_fd >= 0)
-		close(server_fd);
-	printf("(%lu seconds, %lu:%lu bytes)\n",
-	    (unsigned long)(time(NULL) - t), bytes_out, bytes_in);
-	if (terminate_client)
-		irc_send_notice(client_fd, "*** Closing connection "
-		    "(%u seconds, %lu:%lu bytes)",
-		    time(NULL) - t, bytes_out, bytes_in);
+	irc_send_notice(1, "*** Closing connection "
+	    "(%u seconds, %lu:%lu bytes)",
+	    time(NULL) - t, bytes_out, bytes_in);
 }
 
 int