vhangup to clear pty
[unix-history] / usr / src / libexec / telnetd / telnetd.c
index b52d35d..cccb361 100644 (file)
@@ -1,22 +1,24 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)telnetd.c  4.8 82/10/07";
+static char sccsid[] = "@(#)telnetd.c  4.14 82/12/29";
 #endif
 
 /*
  * Stripped-down telnet server.
  */
 #endif
 
 /*
  * Stripped-down telnet server.
  */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
 #include <stdio.h>
 #include <signal.h>
 #include <errno.h>
 #include <sgtty.h>
 #include <wait.h>
 #include <stdio.h>
 #include <signal.h>
 #include <errno.h>
 #include <sgtty.h>
 #include <wait.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/in.h>
 #include <netdb.h>
 #include <netdb.h>
+
 #include "telnet.h"
 
 #include "telnet.h"
 
-#define        INFINITY        10000000
 #define        BELL            '\07'
 
 char   hisopts[256];
 #define        BELL            '\07'
 
 char   hisopts[256];
@@ -42,7 +44,6 @@ extern        int errno;
 char   line[] = "/dev/ptyp0";
 
 struct sockaddr_in sin = { AF_INET };
 char   line[] = "/dev/ptyp0";
 
 struct sockaddr_in sin = { AF_INET };
-int    options = SO_ACCEPTCONN|SO_KEEPALIVE;
 
 main(argc, argv)
        char *argv[];
 
 main(argc, argv)
        char *argv[];
@@ -58,34 +59,55 @@ main(argc, argv)
        }
        sin.sin_port = sp->s_port;
        argc--, argv++;
        }
        sin.sin_port = sp->s_port;
        argc--, argv++;
-       if (argc > 0 && !strcmp(argv[0], "-d"))
-               options |= SO_DEBUG, argc--, argv++;
        if (argc > 0) {
                sin.sin_port = atoi(*argv);
                if (sin.sin_port <= 0) {
                        fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
                        exit(1);
                }
        if (argc > 0) {
                sin.sin_port = atoi(*argv);
                if (sin.sin_port <= 0) {
                        fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
                        exit(1);
                }
+               sin.sin_port = htons((u_short)sin.sin_port);
+       }
+#ifndef DEBUG
+       if (fork())
+               exit(0);
+       for (s = 0; s < 10; s++)
+               (void) close(s);
+       (void) open("/", 0);
+       (void) dup2(0, 1);
+       (void) dup2(0, 2);
+       { int tt = open("/dev/tty", 2);
+         if (tt > 0) {
+               ioctl(tt, TIOCNOTTY, 0);
+               close(tt);
+         }
        }
        }
-       sin.sin_port = htons(sin.sin_port);
+#endif
+again:
+       s = socket(AF_INET, SOCK_STREAM, 0, 0);
+       if (s < 0) {
+               perror("telnetd: socket");;
+               sleep(5);
+               goto again;
+       }
+       while (bind(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
+               perror("telnetd: bind");
+               sleep(5);
+       }
+       listen(s, 10);
        for (;;) {
        for (;;) {
-               errno = 0;
-               if ((s = socket(SOCK_STREAM, 0, &sin, options)) < 0) {
-                       perror("socket");
-                       sleep(5);
-                       continue;
-               }
-               if (accept(s, 0) < 0) {
-                       perror("accept");
-                       close(s);
+               int s2;
+
+               s2 = accept(s, (caddr_t)0, 0, 0);
+               if (s2 < 0) {
+                       perror("telnetd: accept");
                        sleep(1);
                        continue;
                }
                if ((pid = fork()) < 0)
                        printf("Out of processes\n");
                else if (pid == 0)
                        sleep(1);
                        continue;
                }
                if ((pid = fork()) < 0)
                        printf("Out of processes\n");
                else if (pid == 0)
-                       doit(s);
-               close(s);
+                       doit(s2);
+               close(s2);
                while (wait3(status, WNOHANG, 0) > 0)
                        continue;
        }
                while (wait3(status, WNOHANG, 0) > 0)
                        continue;
        }
@@ -109,9 +131,8 @@ doit(f)
                if (p > 0)
                        goto gotpty;
        }
                if (p > 0)
                        goto gotpty;
        }
-       dup2(f, 1);
-       printf("All network ports in use.\n");
-       exit(1);
+       fatal(f, "All network ports in use");
+       /*NOTREACHED*/
 gotpty:
        dup2(f, 0);
        cp[strlen("/dev/")] = 't';
 gotpty:
        dup2(f, 0);
        cp[strlen("/dev/")] = 't';
@@ -121,22 +142,16 @@ gotpty:
                close(t);
        }
        t = open(cp, 2);
                close(t);
        }
        t = open(cp, 2);
-       if (t < 0) {
-               dup2(f, 2);
-               perror(cp);
-               exit(1);
-       }
+       if (t < 0)
+               fatalperror(f, cp, errno);
        ioctl(t, TIOCGETP, &b);
        b.sg_flags = CRMOD|XTABS|ANYP;
        ioctl(t, TIOCSETP, &b);
        ioctl(p, TIOCGETP, &b);
        b.sg_flags &= ~ECHO;
        ioctl(p, TIOCSETP, &b);
        ioctl(t, TIOCGETP, &b);
        b.sg_flags = CRMOD|XTABS|ANYP;
        ioctl(t, TIOCSETP, &b);
        ioctl(p, TIOCGETP, &b);
        b.sg_flags &= ~ECHO;
        ioctl(p, TIOCSETP, &b);
-       if ((i = fork()) < 0) {
-               dup2(f, 2);
-               perror("fork");
-               exit(1);
-       }
+       if ((i = fork()) < 0)
+               fatalperror(f, "fork", errno);
        if (i)
                telnet(f, p);
        close(f);
        if (i)
                telnet(f, p);
        close(f);
@@ -146,10 +161,33 @@ gotpty:
        dup2(t, 2);
        close(t);
        execl("/bin/login", "telnet-login", 0);
        dup2(t, 2);
        close(t);
        execl("/bin/login", "telnet-login", 0);
-       perror("/bin/login");
+       fatalperror(f, "/bin/login", errno);
+       /*NOTREACHED*/
+}
+
+fatal(f, msg)
+       int f;
+       char *msg;
+{
+       char buf[BUFSIZ];
+
+       (void) sprintf(buf, "telnetd: %s.\n", msg);
+       (void) write(f, buf, strlen(buf));
        exit(1);
 }
 
        exit(1);
 }
 
+fatalperror(f, msg, errno)
+       int f;
+       char *msg;
+       int errno;
+{
+       char buf[BUFSIZ];
+       extern char *sys_errlist[];
+
+       (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
+       fatal(f, buf);
+}
+
 /*
  * Main loop.  Select from pty and network, and
  * hand data to telnet receiver finite state machine.
 /*
  * Main loop.  Select from pty and network, and
  * hand data to telnet receiver finite state machine.
@@ -187,7 +225,7 @@ telnet(f, p)
                        ibits |= (1 << f);
                if (ncc < 0 && pcc < 0)
                        break;
                        ibits |= (1 << f);
                if (ncc < 0 && pcc < 0)
                        break;
-               select(32, &ibits, &obits, INFINITY);
+               select(16, &ibits, &obits, 0, 0);
                if (ibits == 0 && obits == 0) {
                        sleep(5);
                        continue;
                if (ibits == 0 && obits == 0) {
                        sleep(5);
                        continue;
@@ -378,7 +416,7 @@ telrcv()
                        continue;
 
                default:
                        continue;
 
                default:
-                       printf("netser: panic state=%d\n", state);
+                       printf("telnetd: panic state=%d\n", state);
                        exit(1);
                }
        }
                        exit(1);
                }
        }
@@ -544,7 +582,7 @@ cleanup()
        int how = 2;
 
        rmut();
        int how = 2;
 
        rmut();
-       vhangup();
+       vhangup();      /* XXX */
        ioctl(net, SIOCDONE, &how);
        kill(0, SIGKILL);
        exit(1);
        ioctl(net, SIOCDONE, &how);
        kill(0, SIGKILL);
        exit(1);