diff options
Diffstat (limited to 'crypto/kerberosIV/lib/roken/mini_inetd.c')
-rw-r--r-- | crypto/kerberosIV/lib/roken/mini_inetd.c | 145 |
1 files changed, 113 insertions, 32 deletions
diff --git a/crypto/kerberosIV/lib/roken/mini_inetd.c b/crypto/kerberosIV/lib/roken/mini_inetd.c index 75169d3..a0c6333 100644 --- a/crypto/kerberosIV/lib/roken/mini_inetd.c +++ b/crypto/kerberosIV/lib/roken/mini_inetd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,12 +14,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: mini_inetd.c,v 1.13 1998/02/05 22:54:33 assar Exp $"); +RCSID("$Id: mini_inetd.c,v 1.18 1999/12/02 16:58:51 joda Exp $"); #endif #include <stdio.h> @@ -49,6 +44,9 @@ RCSID("$Id: mini_inetd.c,v 1.13 1998/02/05 22:54:33 assar Exp $"); #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif @@ -65,32 +63,23 @@ RCSID("$Id: mini_inetd.c,v 1.13 1998/02/05 22:54:33 assar Exp $"); #include <roken.h> -void -mini_inetd (int port) +static int +listen_v4 (int port) { struct sockaddr_in sa; int s; - int s2; s = socket(AF_INET, SOCK_STREAM, 0); if(s < 0) { + if (errno == ENOSYS) + return -1; perror("socket"); exit(1); } -#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) - { - int one = 1; - - if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&one, - sizeof(one)) < 0){ - perror("setsockopt"); - exit(1); - } - } -#endif + socket_set_reuseaddr (s, 1); memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = port; + 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"); @@ -100,14 +89,106 @@ mini_inetd (int port) perror("listen"); exit(1); } - s2 = accept(s, NULL, 0); - if(s2 < 0){ - perror("accept"); + 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); } - close(s); - dup2(s2, STDIN_FILENO); - dup2(s2, STDOUT_FILENO); - /* dup2(s2, STDERR_FILENO); */ - close(s2); + return s; +} +#endif /* HAVE_IPV6 */ + +/* + * accept a connection on `s' and pretend it's served by inetd. + */ + +static void +accept_it (int s) +{ + int s2; + + s2 = accept(s, NULL, 0); + if(s2 < 0){ + perror("accept"); + exit(1); + } + close(s); + dup2(s2, STDIN_FILENO); + dup2(s2, STDOUT_FILENO); + /* dup2(s2, STDERR_FILENO); */ + close(s2); +} + +/* + * Listen on `port' emulating inetd. + */ + +void +mini_inetd (int port) +{ + int ret; + int max_fd = -1; + int sock_v4 = -1; + int sock_v6 = -1; + fd_set orig_read_set, read_set; + + 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); + } +#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 + + 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); + } + } 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; + } + abort (); } |