Use the POSIX tty interface instead of the old interface. This makes

rlogin work properly without COMPAT_43.

Obtained from:	NetBSD (mycroft)
This commit is contained in:
Tim J. Robbins 2003-09-28 08:54:56 +00:00
parent f27d1bf2ec
commit c32cccd0bb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120547
2 changed files with 56 additions and 102 deletions

View File

@ -40,7 +40,7 @@
.Nd remote login .Nd remote login
.Sh SYNOPSIS .Sh SYNOPSIS
.Ar rlogin .Ar rlogin
.Op Fl 468DELd .Op Fl 468DEd
.Op Fl e Ar char .Op Fl e Ar char
.Op Fl i Ar localname .Op Fl i Ar localname
.Op Fl l Ar username .Op Fl l Ar username
@ -78,14 +78,6 @@ Stop any character from being recognized as an escape character.
When used with the When used with the
.Fl 8 .Fl 8
option, this provides a completely transparent connection. option, this provides a completely transparent connection.
.It Fl L
Allow the
.Nm
session to be run in
.Dq litout
(see
.Xr tty 4 )
mode.
.It Fl d .It Fl d
Turn on socket debugging (see Turn on socket debugging (see
.Xr setsockopt 2 ) .Xr setsockopt 2 )

View File

@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -76,7 +77,7 @@ __FBSDID("$FreeBSD$");
#include <paths.h> #include <paths.h>
#include <pwd.h> #include <pwd.h>
#include <setjmp.h> #include <setjmp.h>
#include <sgtty.h> #include <termios.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -92,18 +93,14 @@ __FBSDID("$FreeBSD$");
#define SIGUSR1 30 #define SIGUSR1 30
#endif #endif
int eight, litout, rem; int eight, rem;
struct termios deftty;
int family = PF_UNSPEC; int family = PF_UNSPEC;
int noescape; int noescape;
u_char escapechar = '~'; u_char escapechar = '~';
const char *speeds[] = {
"0", "50", "75", "110", "134", "150", "200", "300", "600", "1200",
"1800", "2400", "4800", "9600", "19200", "38400", "57600", "115200"
#define MAX_SPEED_LENGTH (sizeof("115200") - 1)
};
#define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp) #define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp)
struct winsize winsize; struct winsize winsize;
@ -131,13 +128,14 @@ main(int argc, char *argv[])
{ {
struct passwd *pw; struct passwd *pw;
struct servent *sp; struct servent *sp;
struct sgttyb ttyb; struct termios tty;
long omask; long omask;
int argoff, ch, dflag, Dflag, one; int argoff, ch, dflag, Dflag, one;
uid_t uid; uid_t uid;
char *host, *localname, *p, *user, term[1024]; char *host, *localname, *p, *user, term[1024];
speed_t ospeed;
struct sockaddr_storage ss; struct sockaddr_storage ss;
int sslen; int i, len, len2, sslen;
argoff = dflag = Dflag = 0; argoff = dflag = Dflag = 0;
one = 1; one = 1;
@ -157,7 +155,7 @@ main(int argc, char *argv[])
argoff = 1; argoff = 1;
} }
#define OPTIONS "468DELde:i:l:" #define OPTIONS "468DEKde:i:l:"
while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1)
switch(ch) { switch(ch) {
case '4': case '4':
@ -177,9 +175,6 @@ main(int argc, char *argv[])
case 'E': case 'E':
noescape = 1; noescape = 1;
break; break;
case 'L':
litout = 1;
break;
case 'd': case 'd':
dflag = 1; dflag = 1;
break; break;
@ -220,14 +215,15 @@ main(int argc, char *argv[])
if (sp == NULL) if (sp == NULL)
errx(1, "login/tcp: unknown service"); errx(1, "login/tcp: unknown service");
#define MAX_TERM_LENGTH (sizeof(term) - 1 - MAX_SPEED_LENGTH - 1) if ((p = getenv("TERM")) != NULL)
(void)strlcpy(term, p, sizeof(term));
(void)strncpy(term, (p = getenv("TERM")) ? p : "network", len = strlen(term);
MAX_TERM_LENGTH); if (len < (sizeof(term) - 1) && tcgetattr(0, &tty) == 0) {
term[MAX_TERM_LENGTH] = '\0'; /* start at 2 to include the / */
if (ioctl(0, TIOCGETP, &ttyb) == 0) { for (ospeed = i = cfgetospeed(&tty), len2 = 2; i > 9; len2++)
(void)strcat(term, "/"); i /= 10;
(void)strcat(term, speeds[(int)ttyb.sg_ospeed]); if (len + len2 < sizeof(term))
(void)snprintf(term + len, len2 + 1, "/%d", ospeed);
} }
(void)get_window_size(0, &winsize); (void)get_window_size(0, &winsize);
@ -272,39 +268,22 @@ main(int argc, char *argv[])
/*NOTREACHED*/ /*NOTREACHED*/
} }
int child, defflags, deflflags, tabflag; int child;
char deferase, defkill;
struct tchars deftc;
struct ltchars defltc;
struct tchars notc = { -1, -1, -1, -1, -1, -1 };
struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
void void
doit(long omask) doit(long omask)
{ {
struct sgttyb sb;
(void)ioctl(0, TIOCGETP, (char *)&sb);
defflags = sb.sg_flags;
tabflag = defflags & TBDELAY;
defflags &= ECHO | CRMOD;
deferase = sb.sg_erase;
defkill = sb.sg_kill;
(void)ioctl(0, TIOCLGET, &deflflags);
(void)ioctl(0, TIOCGETC, &deftc);
notc.t_startc = deftc.t_startc;
notc.t_stopc = deftc.t_stopc;
(void)ioctl(0, TIOCGLTC, &defltc);
(void)signal(SIGINT, SIG_IGN); (void)signal(SIGINT, SIG_IGN);
setsignal(SIGHUP); setsignal(SIGHUP);
setsignal(SIGQUIT); setsignal(SIGQUIT);
mode(1);
child = fork(); child = fork();
if (child == -1) { if (child == -1) {
warn("fork"); warn("fork");
done(1); done(1);
} }
if (child == 0) { if (child == 0) {
mode(1);
if (reader(omask) == 0) { if (reader(omask) == 0) {
msg("connection closed"); msg("connection closed");
exit(0); exit(0);
@ -425,11 +404,12 @@ writer(void)
} }
} else if (local) { } else if (local) {
local = 0; local = 0;
if (c == '.' || c == deftc.t_eofc) { if (c == '.' || CCEQ(deftty.c_cc[VEOF], c)) {
echo(c); echo(c);
break; break;
} }
if (c == defltc.t_suspc || c == defltc.t_dsuspc) { if (CCEQ(deftty.c_cc[VSUSP], c) ||
CCEQ(deftty.c_cc[VDSUSP], c)) {
bol = 1; bol = 1;
echo(c); echo(c);
stop(c); stop(c);
@ -443,8 +423,10 @@ writer(void)
msg("line gone"); msg("line gone");
break; break;
} }
bol = c == defkill || c == deftc.t_eofc || bol = CCEQ(deftty.c_cc[VKILL], c) ||
c == deftc.t_intrc || c == defltc.t_suspc || CCEQ(deftty.c_cc[VEOF], c) ||
CCEQ(deftty.c_cc[VINTR], c) ||
CCEQ(deftty.c_cc[VSUSP], c) ||
c == '\r' || c == '\n'; c == '\r' || c == '\n';
} }
} }
@ -476,7 +458,7 @@ stop(char cmdc)
{ {
mode(0); mode(0);
(void)signal(SIGCHLD, SIG_IGN); (void)signal(SIGCHLD, SIG_IGN);
(void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); (void)kill(CCEQ(deftty.c_cc[VSUSP], cmdc) ? 0 : getpid(), SIGTSTP);
(void)signal(SIGCHLD, catch_child); (void)signal(SIGCHLD, catch_child);
mode(1); mode(1);
sigwinch(0); /* check for size changes */ sigwinch(0); /* check for size changes */
@ -532,11 +514,10 @@ char rcvbuf[8 * 1024];
void void
oob(int signo __unused) oob(int signo __unused)
{ {
struct sgttyb sb; struct termios tty;
int atmark, n, out, rcvd; int atmark, n, rcvd;
char waste[BUFSIZ], mark; char waste[BUFSIZ], mark;
out = O_RDWR;
rcvd = 0; rcvd = 0;
while (recv(rem, &mark, 1, MSG_OOB) < 0) { while (recv(rem, &mark, 1, MSG_OOB) < 0) {
switch (errno) { switch (errno) {
@ -567,25 +548,17 @@ oob(int signo __unused)
(void)kill(ppid, SIGUSR1); (void)kill(ppid, SIGUSR1);
} }
if (!eight && (mark & TIOCPKT_NOSTOP)) { if (!eight && (mark & TIOCPKT_NOSTOP)) {
(void)ioctl(0, TIOCGETP, (char *)&sb); (void)tcgetattr(0, &tty);
sb.sg_flags &= ~CBREAK; tty.c_iflag &= ~IXON;
sb.sg_flags |= RAW; (void)tcsetattr(0, TCSANOW, &tty);
(void)ioctl(0, TIOCSETN, (char *)&sb);
notc.t_stopc = -1;
notc.t_startc = -1;
(void)ioctl(0, TIOCSETC, (char *)&notc);
} }
if (!eight && (mark & TIOCPKT_DOSTOP)) { if (!eight && (mark & TIOCPKT_DOSTOP)) {
(void)ioctl(0, TIOCGETP, (char *)&sb); (void)tcgetattr(0, &tty);
sb.sg_flags &= ~RAW; tty.c_iflag |= (deftty.c_iflag & IXON);
sb.sg_flags |= CBREAK; (void)tcsetattr(0, TCSANOW, &tty);
(void)ioctl(0, TIOCSETN, (char *)&sb);
notc.t_stopc = deftc.t_stopc;
notc.t_startc = deftc.t_startc;
(void)ioctl(0, TIOCSETC, (char *)&notc);
} }
if (mark & TIOCPKT_FLUSHWRITE) { if (mark & TIOCPKT_FLUSHWRITE) {
(void)ioctl(1, TIOCFLUSH, (char *)&out); (void)tcflush(1, TCIOFLUSH);
for (;;) { for (;;) {
if (ioctl(rem, SIOCATMARK, &atmark) < 0) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
warn("ioctl"); warn("ioctl");
@ -665,42 +638,31 @@ reader(int omask)
void void
mode(int f) mode(int f)
{ {
struct ltchars *ltc; struct termios tty;
struct sgttyb sb;
struct tchars *tc;
int lflags;
(void)ioctl(0, TIOCGETP, (char *)&sb); switch (f) {
(void)ioctl(0, TIOCLGET, (char *)&lflags);
switch(f) {
case 0: case 0:
sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); (void)tcsetattr(0, TCSANOW, &deftty);
sb.sg_flags |= defflags|tabflag;
tc = &deftc;
ltc = &defltc;
sb.sg_kill = defkill;
sb.sg_erase = deferase;
lflags = deflflags;
break; break;
case 1: case 1:
sb.sg_flags |= (eight ? RAW : CBREAK); (void)tcgetattr(0, &deftty);
sb.sg_flags &= ~defflags; tty = deftty;
/* preserve tab delays, but turn off XTABS */ /* This is loosely derived from sys/kern/tty_compat.c. */
if ((sb.sg_flags & TBDELAY) == XTABS) tty.c_lflag &= ~(ECHO|ICANON|ISIG|IEXTEN);
sb.sg_flags &= ~TBDELAY; tty.c_iflag &= ~ICRNL;
tc = &notc; tty.c_oflag &= ~OPOST;
ltc = &noltc; tty.c_cc[VMIN] = 1;
sb.sg_kill = sb.sg_erase = -1; tty.c_cc[VTIME] = 0;
if (litout) if (eight) {
lflags |= LLITOUT; tty.c_iflag &= IXOFF;
tty.c_cflag &= ~(CSIZE|PARENB);
tty.c_cflag |= CS8;
}
(void)tcsetattr(0, TCSANOW, &tty);
break; break;
default: default:
return; return;
} }
(void)ioctl(0, TIOCSLTC, (char *)ltc);
(void)ioctl(0, TIOCSETC, (char *)tc);
(void)ioctl(0, TIOCSETN, (char *)&sb);
(void)ioctl(0, TIOCLSET, (char *)&lflags);
} }
/* ARGSUSED */ /* ARGSUSED */
@ -731,7 +693,7 @@ usage(void)
{ {
(void)fprintf(stderr, (void)fprintf(stderr,
"usage: rlogin [-46%s]%s[-e char] [-i localname] [-l username] host\n", "usage: rlogin [-46%s]%s[-e char] [-i localname] [-l username] host\n",
"8DELd", " "); "8DEd", " ");
exit(1); exit(1);
} }