static char sccsid
[] = "@(#)rlogin.c 4.18 (Berkeley) 85/05/31";
char *index(), *rindex(), *malloc(), *getenv();
struct passwd
*getpwuid();
{ "0", "50", "75", "110", "134", "150", "200", "300",
"600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
char term
[256] = "network";
host
= rindex(argv
[0], '/');
if (!strcmp(host
, "rlogin"))
if (argc
> 0 && !strcmp(*argv
, "-d")) {
if (argc
> 0 && !strcmp(*argv
, "-l")) {
if (argc
> 0 && !strncmp(*argv
, "-e", 2)) {
if (argc
> 0 && !strcmp(*argv
, "-8")) {
if (argc
> 0 && !strcmp(*argv
, "-L")) {
if (argc
> 0 && !strcmp(*argv
, "-w")) {
pwd
= getpwuid(getuid());
fprintf(stderr
, "Who are you?\n");
sp
= getservbyname("login", "tcp");
fprintf(stderr
, "rlogin: login/tcp: unknown service\n");
if (ioctl(0, TIOCGETP
, &ttyb
) == 0) {
strcat(term
, speeds
[ttyb
.sg_ospeed
]);
if (!nosigwin
&& ioctl(0, TIOCGWINSZ
, &winsize
) == 0) {
sprintf(cp
, "/%u,%u,%u,%u", winsize
.ws_row
, winsize
.ws_col
,
winsize
.ws_xpixel
, winsize
.ws_ypixel
);
signal(SIGPIPE
, lostpeer
);
rem
= rcmd(&host
, sp
->s_port
, pwd
->pw_name
,
name
? name
: pwd
->pw_name
, term
, 0);
if (options
& SO_DEBUG
&&
setsockopt(rem
, SOL_SOCKET
, SO_DEBUG
, &on
, sizeof (on
)) < 0)
perror("rlogin: setsockopt (SO_DEBUG)");
perror("rlogin: setuid");
"usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ] [ -w ]\n");
struct tchars notc
= { -1, -1, -1, -1, -1, -1 };
struct ltchars noltc
= { -1, -1, -1, -1, -1, -1 };
ioctl(0, TIOCGETP
, (char *)&sb
);
tabflag
= defflags
& TBDELAY
;
defflags
&= ECHO
| CRMOD
;
ioctl(0, TIOCLGET
, (char *)&deflflags
);
ioctl(0, TIOCGETC
, (char *)&deftc
);
notc
.t_startc
= deftc
.t_startc
;
notc
.t_stopc
= deftc
.t_stopc
;
ioctl(0, TIOCGLTC
, (char *)&defltc
);
prf("\007Connection closed.");
signal(SIGCHLD
, catchild
);
signal(SIGWINCH
, sigwinch
);
prf("Closed connection.");
if (child
> 0 && kill(child
, SIGKILL
) >= 0)
pid
= wait3(&status
, WNOHANG
|WUNTRACED
, 0);
* if the child (reader) dies, just quit
if (pid
< 0 || pid
== child
&& !WIFSTOPPED(status
))
* writer: write to remote: 0 -> line.
* ~^Z suspend rlogin process.
* ~^Y suspend rlogin process, but leave reader alone.
* Handle SIGWINCH's with in-band signaling of new
* window size. It seems reasonable that we flush
* pending input and not force out of band signal
* as this most likely will occur from an input device
* other than the keyboard (e.g. a mouse).
* The hack of using 0377 to signal an in-band signal
* is pretty bad, but otherwise we'd be forced to
* either get complicated (use MSG_OOB) or go to a
* serious (telnet-style) protocol.
if (setjmp(winsizechanged
)) {
struct winsize
*wp
= (struct winsize
*)(obuf
+4);
obuf
[0] = 0377; /* XXX */
obuf
[1] = 0377; /* XXX */
wp
->ws_row
= htons(winsize
.ws_row
);
wp
->ws_col
= htons(winsize
.ws_col
);
wp
->ws_xpixel
= htons(winsize
.ws_xpixel
);
wp
->ws_ypixel
= htons(winsize
.ws_ypixel
);
(void) write(rem
, obuf
, 4+sizeof (*wp
));
if (n
< 0 && errno
== EINTR
)
* If we're at the beginning of the line
* and recognize a command character, then
* we echo locally. Otherwise, characters
* are echo'd remotely. If the command
* character is doubled, this acts as a
* force and local echo is suppressed.
if (op
== obuf
+ 1 && *obuf
== cmdchar
)
if (write(rem
, &c
, 1) == 0) {
if (c
== '\r' || c
== '\n') {
if (cmdc
== '.' || cmdc
== deftc
.t_eofc
) {
write(0, CRLF
, sizeof(CRLF
));
if (cmdc
== defltc
.t_suspc
||
cmdc
== defltc
.t_dsuspc
) {
write(rem
, obuf
, op
- obuf
);
if (c
== defkill
|| c
== deftc
.t_eofc
||
if (op
>= &obuf
[sizeof (obuf
)])
write(0, CRLF
, sizeof(CRLF
));
signal(SIGCHLD
, SIG_IGN
);
kill(cmdc
== defltc
.t_suspc
? 0 : getpid(), SIGTSTP
);
signal(SIGCHLD
, catchild
);
sigwinch(); /* check for size changes */
if (!nosigwin
&& ioctl(0, TIOCGWINSZ
, &ws
) == 0 &&
bcmp(&ws
, &winsize
, sizeof (ws
))) {
longjmp(winsizechanged
, 1);
char waste
[BUFSIZ
], mark
;
ioctl(1, TIOCFLUSH
, (char *)&out
);
if (ioctl(rem
, SIOCATMARK
, &atmark
) < 0) {
(void) read(rem
, waste
, sizeof (waste
));
recv(rem
, &mark
, 1, MSG_OOB
);
if (mark
& TIOCPKT_NOSTOP
) {
ioctl(0, TIOCSETC
, (char *)¬c
);
if (mark
& TIOCPKT_DOSTOP
) {
notc
.t_stopc
= deftc
.t_stopc
;
notc
.t_startc
= deftc
.t_startc
;
ioctl(0, TIOCSETC
, (char *)¬c
);
* reader: read from remote: line -> 1
ioctl(rem
, SIOCSPGRP
, (char *)&pid
); }
cnt
= read(rem
, rb
, sizeof (rb
));
ioctl(0, TIOCGETP
, (char *)&sb
);
ioctl(0, TIOCLGET
, (char *)&lflags
);
sb
.sg_flags
&= ~(CBREAK
|RAW
|TBDELAY
);
sb
.sg_flags
|= defflags
|tabflag
;
sb
.sg_flags
|= (eight
? RAW
: CBREAK
);
sb
.sg_flags
&= ~defflags
;
/* preserve tab delays, but turn off XTABS */
if ((sb
.sg_flags
& TBDELAY
) == XTABS
)
sb
.sg_kill
= sb
.sg_erase
= -1;
ioctl(0, TIOCSLTC
, (char *)ltc
);
ioctl(0, TIOCSETC
, (char *)tc
);
ioctl(0, TIOCSETN
, (char *)&sb
);
ioctl(0, TIOCLSET
, (char *)&lflags
);
fprintf(stderr
, f
, a1
, a2
, a3
);
signal(SIGPIPE
, SIG_IGN
);
prf("\007Connection closed.");