From 00d67fa5c0758f14c3b31d3971c119e91874765c Mon Sep 17 00:00:00 2001 From: Assar Westerlund Date: Sat, 4 Dec 1999 17:49:33 +0000 Subject: [PATCH] (mini_inted): rewrite to use `getaddrinfo' git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@7485 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/roken/mini_inetd.c | 133 +++++++++++++---------------------------- 1 file changed, 42 insertions(+), 91 deletions(-) diff --git a/lib/roken/mini_inetd.c b/lib/roken/mini_inetd.c index ec7f0436f..dd40b1176 100644 --- a/lib/roken/mini_inetd.c +++ b/lib/roken/mini_inetd.c @@ -63,66 +63,6 @@ RCSID("$Id$"); #include -static int -listen_v4 (int port) -{ - struct sockaddr_in sa; - int s; - - s = socket(AF_INET, SOCK_STREAM, 0); - if(s < 0) { - if (errno == ENOSYS) - return -1; - perror("socket"); - exit(1); - } - socket_set_reuseaddr (s, 1); - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = port; - sa.sin_addr.s_addr = INADDR_ANY; - if(bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0){ - perror("bind"); - exit(1); - } - if(listen(s, SOMAXCONN) < 0){ - perror("listen"); - exit(1); - } - return s; -} - -#ifdef HAVE_IPV6 -static int -listen_v6 (int port) -{ - struct sockaddr_in6 sa; - int s; - - s = socket(AF_INET6, SOCK_STREAM, 0); - if(s < 0) { - if (errno == ENOSYS) - return -1; - perror("socket"); - exit(1); - } - socket_set_reuseaddr (s, 1); - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET6; - sa.sin6_port = port; - sa.sin6_addr = in6addr_any; - if(bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0){ - perror("bind"); - exit(1); - } - if(listen(s, SOMAXCONN) < 0){ - perror("listen"); - exit(1); - } - return s; -} -#endif /* HAVE_IPV6 */ - /* * accept a connection on `s' and pretend it's served by inetd. */ @@ -133,10 +73,8 @@ accept_it (int s) int s2; s2 = accept(s, NULL, 0); - if(s2 < 0){ - perror("accept"); - exit(1); - } + if(s2 < 0) + err (1, "accept"); close(s); dup2(s2, STDIN_FILENO); dup2(s2, STDOUT_FILENO); @@ -151,44 +89,57 @@ accept_it (int s) void mini_inetd (int port) { - int ret; - int max_fd = -1; - int sock_v4 = -1; - int sock_v6 = -1; + int error, ret; + struct addrinfo *ai, *a, hints; + char portstr[NI_MAXSERV]; + int n, i; + int *fds; fd_set orig_read_set, read_set; + int max_fd = -1; + + memset (&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + + error = getaddrinfo (NULL, portstr, &hints, &ai); + if (error) + errx (1, "getaddrinfo: %s", gai_strerror (error)); + + for (n = 0, a = ai; a != NULL; a = a->ai_next) + ++n; + + fds = malloc (n * sizeof(*fds)); + if (fds == NULL) + errx (1, "mini_inetd: out of memory"); FD_ZERO(&orig_read_set); - sock_v4 = listen_v4 (port); - if (sock_v4 >= 0) { - max_fd = max(max_fd, sock_v4); - FD_SET(sock_v4, &orig_read_set); + for (i = 0, a = ai; a != NULL; a = a->ai_next, ++i) { + fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol); + if (fds[i] < 0) + err (1, "socket"); + socket_set_reuseaddr (fds[i], 1); + if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0) + err (1, "bind"); + if (listen (fds[i], SOMAXCONN) < 0) + err (1, "listen"); + FD_SET(fds[i], &orig_read_set); + max_fd = max(max_fd, fds[i]); } -#ifdef HAVE_IPV6 - sock_v6 = listen_v6 (port); - if (sock_v6 >= 0) { - max_fd = max(max_fd, sock_v6); - FD_SET(sock_v6, &orig_read_set); - } -#endif + freeaddrinfo (ai); do { read_set = orig_read_set; ret = select (max_fd + 1, &read_set, NULL, NULL, NULL); - if (ret < 0 && ret != EINTR) { - perror ("select"); - exit (1); - } + if (ret < 0 && errno != EINTR) + err (1, "select"); } while (ret <= 0); - if (sock_v4 > 0 && FD_ISSET (sock_v4, &read_set)) { - accept_it (sock_v4); - return; - } - if (sock_v6 > 0 && FD_ISSET (sock_v6, &read_set)) { - accept_it (sock_v6); - return; - } + for (i = 0; i < n; ++i) + if (FD_ISSET (fds[i], &read_set)) { + accept_it (fds[i]); + return; + } abort (); }