(mini_inted): rewrite to use `getaddrinfo'

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@7485 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1999-12-04 17:49:33 +00:00
parent 1e6bdd09fe
commit 00d67fa5c0

View File

@@ -63,66 +63,6 @@ RCSID("$Id$");
#include <roken.h>
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 ();
}