summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/lib/roken/mini_inetd.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/kerberosIV/lib/roken/mini_inetd.c')
-rw-r--r--crypto/kerberosIV/lib/roken/mini_inetd.c145
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 ();
}
OpenPOWER on IntegriCloud