(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>
|
#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.
|
* accept a connection on `s' and pretend it's served by inetd.
|
||||||
*/
|
*/
|
||||||
@@ -133,10 +73,8 @@ accept_it (int s)
|
|||||||
int s2;
|
int s2;
|
||||||
|
|
||||||
s2 = accept(s, NULL, 0);
|
s2 = accept(s, NULL, 0);
|
||||||
if(s2 < 0){
|
if(s2 < 0)
|
||||||
perror("accept");
|
err (1, "accept");
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
close(s);
|
close(s);
|
||||||
dup2(s2, STDIN_FILENO);
|
dup2(s2, STDIN_FILENO);
|
||||||
dup2(s2, STDOUT_FILENO);
|
dup2(s2, STDOUT_FILENO);
|
||||||
@@ -151,44 +89,57 @@ accept_it (int s)
|
|||||||
void
|
void
|
||||||
mini_inetd (int port)
|
mini_inetd (int port)
|
||||||
{
|
{
|
||||||
int ret;
|
int error, ret;
|
||||||
int max_fd = -1;
|
struct addrinfo *ai, *a, hints;
|
||||||
int sock_v4 = -1;
|
char portstr[NI_MAXSERV];
|
||||||
int sock_v6 = -1;
|
int n, i;
|
||||||
|
int *fds;
|
||||||
fd_set orig_read_set, read_set;
|
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);
|
FD_ZERO(&orig_read_set);
|
||||||
|
|
||||||
sock_v4 = listen_v4 (port);
|
for (i = 0, a = ai; a != NULL; a = a->ai_next, ++i) {
|
||||||
if (sock_v4 >= 0) {
|
fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
|
||||||
max_fd = max(max_fd, sock_v4);
|
if (fds[i] < 0)
|
||||||
FD_SET(sock_v4, &orig_read_set);
|
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
|
freeaddrinfo (ai);
|
||||||
sock_v6 = listen_v6 (port);
|
|
||||||
if (sock_v6 >= 0) {
|
|
||||||
max_fd = max(max_fd, sock_v6);
|
|
||||||
FD_SET(sock_v6, &orig_read_set);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
read_set = orig_read_set;
|
read_set = orig_read_set;
|
||||||
|
|
||||||
ret = select (max_fd + 1, &read_set, NULL, NULL, NULL);
|
ret = select (max_fd + 1, &read_set, NULL, NULL, NULL);
|
||||||
if (ret < 0 && ret != EINTR) {
|
if (ret < 0 && errno != EINTR)
|
||||||
perror ("select");
|
err (1, "select");
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
} while (ret <= 0);
|
} while (ret <= 0);
|
||||||
|
|
||||||
if (sock_v4 > 0 && FD_ISSET (sock_v4, &read_set)) {
|
for (i = 0; i < n; ++i)
|
||||||
accept_it (sock_v4);
|
if (FD_ISSET (fds[i], &read_set)) {
|
||||||
return;
|
accept_it (fds[i]);
|
||||||
}
|
return;
|
||||||
if (sock_v6 > 0 && FD_ISSET (sock_v6, &read_set)) {
|
}
|
||||||
accept_it (sock_v6);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user