(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:
@@ -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 ();
|
||||
}
|
||||
|
Reference in New Issue
Block a user