projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
set term since login expects it now
[unix-history]
/
usr
/
src
/
libexec
/
telnetd
/
telnetd.c
diff --git
a/usr/src/libexec/telnetd/telnetd.c
b/usr/src/libexec/telnetd/telnetd.c
index
a86f912
..
1698d4c
100644
(file)
--- a/
usr/src/libexec/telnetd/telnetd.c
+++ b/
usr/src/libexec/telnetd/telnetd.c
@@
-1,5
+1,5
@@
#ifndef lint
#ifndef lint
-static char sccsid[] = "@(#)telnetd.c 4.
11 82/11/15
";
+static char sccsid[] = "@(#)telnetd.c 4.
25 (Berkeley) 83/07/06
";
#endif
/*
#endif
/*
@@
-7,19
+7,20
@@
static char sccsid[] = "@(#)telnetd.c 4.11 82/11/15";
*/
#include <sys/types.h>
#include <sys/socket.h>
*/
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/in.h>
+#include <arpa/telnet.h>
+
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sgtty.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sgtty.h>
-#include <wait.h>
#include <netdb.h>
#include <netdb.h>
-#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];
char hisopts[256];
char myopts[256];
@@
-40,6
+41,8
@@
int pcc, ncc;
int pty, net;
int inter;
int pty, net;
int inter;
+int reapchild();
+extern char **environ;
extern int errno;
char line[] = "/dev/ptyp0";
extern int errno;
char line[] = "/dev/ptyp0";
@@
-48,8
+51,7
@@
struct sockaddr_in sin = { AF_INET };
main(argc, argv)
char *argv[];
{
main(argc, argv)
char *argv[];
{
- int s, pid;
- union wait status;
+ int s, pid, options;
struct servent *sp;
sp = getservbyname("telnet", "tcp");
struct servent *sp;
sp = getservbyname("telnet", "tcp");
@@
-59,14
+61,18
@@
main(argc, argv)
}
sin.sin_port = sp->s_port;
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);
}
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);
#ifndef DEBUG
if (fork())
exit(0);
@@
-83,47
+89,68
@@
main(argc, argv)
}
#endif
again:
}
#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 (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);
}
while (bind(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
perror("telnetd: bind");
sleep(5);
}
+ signal(SIGCHLD, reapchild);
listen(s, 10);
for (;;) {
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 (s2 < 0) {
+ if (errno == EINTR)
+ continue;
perror("telnetd: accept");
sleep(1);
continue;
}
if ((pid = fork()) < 0)
printf("Out of processes\n");
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);
close(s2);
- while (wait3(status, WNOHANG, 0) > 0)
- continue;
}
/*NOTREACHED*/
}
}
/*NOTREACHED*/
}
+reapchild()
+{
+ union wait status;
+
+ while (wait3(&status, WNOHANG, 0) > 0)
+ ;
+}
+
+char *envinit[] = { "TERM=network", 0 };
int cleanup();
/*
* Get a pty, scan input lines.
*/
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;
int i, p, cc, t;
struct sgttyb b;
+ struct hostent *hp;
for (i = 0; i < 16; i++) {
cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
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);
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)
if ((i = fork()) < 0)
fatalperror(f, "fork", errno);
if (i)
@@
-160,7
+193,8
@@
gotpty:
dup2(t, 1);
dup2(t, 2);
close(t);
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*/
}
fatalperror(f, "/bin/login", errno);
/*NOTREACHED*/
}
@@
-195,18
+229,25
@@
fatalperror(f, msg, errno)
telnet(f, p)
{
int on = 1;
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);
net = f, pty = p;
ioctl(f, FIONBIO, &on);
ioctl(p, FIONBIO, &on);
signal(SIGTSTP, SIG_IGN);
- sig
set
(SIGCHLD, cleanup);
+ sig
nal
(SIGCHLD, cleanup);
/*
* Request to do remote echo.
*/
dooption(TELOPT_ECHO);
myopts[TELOPT_ECHO] = 1;
/*
* 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;
for (;;) {
int ibits = 0, obits = 0;
register int c;
@@
-579,13
+620,10
@@
netflush()
cleanup()
{
cleanup()
{
- int how = 2;
rmut();
rmut();
-#ifdef notdef
- vhangup();
-#endif
- ioctl(net, SIOCDONE, &how);
+ vhangup(); /* XXX */
+ shutdown(net, 2);
kill(0, SIGKILL);
exit(1);
}
kill(0, SIGKILL);
exit(1);
}
@@
-610,6
+648,7
@@
rmut()
continue;
lseek(f, -(long)sizeof (wtmp), 1);
SCPYN(wtmp.ut_name, "");
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++;
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, "");
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));
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);
}
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);
+}