X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/8f2758db19869ab441ebc2c1cd59037f1189e865..fe5c5547066496480f77152fbcfbd68c56e9cf6f:/usr/src/libexec/telnetd/telnetd.c diff --git a/usr/src/libexec/telnetd/telnetd.c b/usr/src/libexec/telnetd/telnetd.c index a86f912194..1698d4ccf8 100644 --- a/usr/src/libexec/telnetd/telnetd.c +++ b/usr/src/libexec/telnetd/telnetd.c @@ -1,5 +1,5 @@ #ifndef lint -static char sccsid[] = "@(#)telnetd.c 4.11 82/11/15"; +static char sccsid[] = "@(#)telnetd.c 4.25 (Berkeley) 83/07/06"; #endif /* @@ -7,19 +7,20 @@ static char sccsid[] = "@(#)telnetd.c 4.11 82/11/15"; */ #include #include +#include #include +#include + #include #include #include #include -#include #include -#include "telnet.h" - -#define BELL '\07' +#define BELL '\07' +#define BANNER "\r\n\r\n4.2 BSD UNIX (%s)\r\n\r\r\n\r%s" char hisopts[256]; char myopts[256]; @@ -40,6 +41,8 @@ int pcc, ncc; int pty, net; int inter; +int reapchild(); +extern char **environ; extern int errno; char line[] = "/dev/ptyp0"; @@ -48,8 +51,7 @@ struct sockaddr_in sin = { AF_INET }; main(argc, argv) char *argv[]; { - int s, pid; - union wait status; + int s, pid, options; struct servent *sp; sp = getservbyname("telnet", "tcp"); @@ -59,14 +61,18 @@ main(argc, argv) } sin.sin_port = sp->s_port; argc--, argv++; + if (argc > 0 && !strcmp(*argv, "-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); } + sin.sin_port = htons((u_short)sin.sin_port); } - sin.sin_port = htons((u_short)sin.sin_port); #ifndef DEBUG if (fork()) exit(0); @@ -83,47 +89,68 @@ main(argc, argv) } #endif again: - s = socket(0, SOCK_STREAM, 0, 0); + s = socket(AF_INET, SOCK_STREAM, 0, 0); if (s < 0) { perror("telnetd: socket");; sleep(5); goto again; } + if (options & SO_DEBUG) + if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) + perror("telnetd: setsockopt (SO_DEBUG)"); + if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0) + perror("telnetd: setsockopt (SO_KEEPALIVE)"); while (bind(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { perror("telnetd: bind"); sleep(5); } + signal(SIGCHLD, reapchild); listen(s, 10); for (;;) { - int s2; + struct sockaddr_in from; + int s2, fromlen = sizeof (from); - s2 = accept(s, (caddr_t)0, 0, 0); + s2 = accept(s, (caddr_t)&from, &fromlen); if (s2 < 0) { + if (errno == EINTR) + continue; perror("telnetd: accept"); sleep(1); continue; } if ((pid = fork()) < 0) printf("Out of processes\n"); - else if (pid == 0) - doit(s2); + else if (pid == 0) { + signal(SIGCHLD, SIG_IGN); + doit(s2, &from); + } close(s2); - while (wait3(status, WNOHANG, 0) > 0) - continue; } /*NOTREACHED*/ } +reapchild() +{ + union wait status; + + while (wait3(&status, WNOHANG, 0) > 0) + ; +} + +char *envinit[] = { "TERM=network", 0 }; int cleanup(); /* * Get a pty, scan input lines. */ -doit(f) +doit(f, who) + int f; + struct sockaddr_in *who; { - char *cp = line; + char *cp = line, *host, *ntoa(); int i, p, cc, t; struct sgttyb b; + struct hostent *hp; for (i = 0; i < 16; i++) { cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i]; @@ -150,6 +177,12 @@ gotpty: ioctl(p, TIOCGETP, &b); b.sg_flags &= ~ECHO; ioctl(p, TIOCSETP, &b); + hp = gethostbyaddr(&who->sin_addr, sizeof (struct in_addr), + who->sin_family); + if (hp) + host = hp->h_name; + else + host = ntoa(who->sin_addr); if ((i = fork()) < 0) fatalperror(f, "fork", errno); if (i) @@ -160,7 +193,8 @@ gotpty: dup2(t, 1); dup2(t, 2); close(t); - execl("/bin/login", "telnet-login", 0); + environ = envinit; + execl("/bin/login", "login", "-h", host, 0); fatalperror(f, "/bin/login", errno); /*NOTREACHED*/ } @@ -195,18 +229,25 @@ fatalperror(f, msg, errno) telnet(f, p) { int on = 1; + char hostname[32]; net = f, pty = p; ioctl(f, FIONBIO, &on); ioctl(p, FIONBIO, &on); signal(SIGTSTP, SIG_IGN); - sigset(SIGCHLD, cleanup); + signal(SIGCHLD, cleanup); /* * Request to do remote echo. */ dooption(TELOPT_ECHO); myopts[TELOPT_ECHO] = 1; + /* + * Show banner that getty never gave. + */ + gethostname(hostname, sizeof (hostname)); + sprintf(nfrontp, BANNER, hostname, ""); + nfrontp += strlen(nfrontp); for (;;) { int ibits = 0, obits = 0; register int c; @@ -579,13 +620,10 @@ netflush() cleanup() { - int how = 2; rmut(); -#ifdef notdef - vhangup(); -#endif - ioctl(net, SIOCDONE, &how); + vhangup(); /* XXX */ + shutdown(net, 2); kill(0, SIGKILL); exit(1); } @@ -610,6 +648,7 @@ rmut() continue; lseek(f, -(long)sizeof (wtmp), 1); SCPYN(wtmp.ut_name, ""); + SCPYN(wtmp.ut_host, ""); time(&wtmp.ut_time); write(f, (char *)&wtmp, sizeof (wtmp)); found++; @@ -621,6 +660,7 @@ rmut() if (f >= 0) { SCPYN(wtmp.ut_line, line+5); SCPYN(wtmp.ut_name, ""); + SCPYN(wtmp.ut_host, ""); time(&wtmp.ut_time); lseek(f, (long)0, 2); write(f, (char *)&wtmp, sizeof (wtmp)); @@ -633,3 +673,20 @@ rmut() chmod(line, 0666); chown(line, 0, 0); } + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +char * +ntoa(in) + struct in_addr in; +{ + static char b[18]; + register char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (b); +}