Sync to 4.4BSD-Lite2

This commit is contained in:
tls 1997-01-09 06:57:45 +00:00
parent 81e84482e0
commit 29985c32a6
2 changed files with 173 additions and 80 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: rlogin.1,v 1.5 1996/09/27 02:49:50 thorpej Exp $
.\" $NetBSD: rlogin.1,v 1.6 1997/01/09 06:57:45 tls Exp $
.\"
.\" Copyright (c) 1983, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -31,21 +31,26 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)rlogin.1 8.1 (Berkeley) 6/6/93
.\" @(#)rlogin.1 8.2 (Berkeley) 4/29/95
.\"
.Dd June 6, 1993
.Dd April 29, 1995
.Dt RLOGIN 1
.Os BSD 4.2
.Sh NAME
.Nm rlogin
.Nd remote login
.Sh SYNOPSIS
.Ar rlogin
.Nm rlogin
.Op Fl 8EKLdx
.Op Fl e Ar char
.Op Fl k Ar realm
.Op Fl l Ar username
.Ar host
.Nm rlogin
.Op Fl 8EKLdx
.Op Fl e Ar char
.Op Fl k Ar realm
.Ar username@host
.Sh DESCRIPTION
.Nm Rlogin
starts a terminal session on a remote host

View File

@ -1,4 +1,4 @@
/* $NetBSD: rlogin.c,v 1.14 1996/08/10 19:47:32 explorer Exp $ */
/* $NetBSD: rlogin.c,v 1.15 1997/01/09 06:57:46 tls Exp $ */
/*
* Copyright (c) 1983, 1990, 1993
@ -41,9 +41,9 @@ static char copyright[] =
#ifndef lint
#if 0
static char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93";
static char sccsid[] = "@(#)rlogin.c 8.4 (Berkeley) 4/29/95";
#else
static char rcsid[] = "$NetBSD: rlogin.c,v 1.14 1996/08/10 19:47:32 explorer Exp $";
static char rcsid[] = "$NetBSD: rlogin.c,v 1.15 1997/01/09 06:57:46 tls Exp $";
#endif
#endif /* not lint */
@ -56,6 +56,7 @@ static char rcsid[] = "$NetBSD: rlogin.c,v 1.14 1996/08/10 19:47:32 explorer Exp
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@ -122,7 +123,7 @@ struct winsize winsize;
void catch_child __P((int));
void copytochild __P((int));
__dead void doit __P((long));
__dead void doit __P((sigset_t *));
__dead void done __P((int));
void echo __P((char));
u_int getescape __P((char *));
@ -130,9 +131,10 @@ void lostpeer __P((int));
void mode __P((int));
void msg __P((char *));
void oob __P((int));
int reader __P((int));
int reader __P((sigset_t *));
void sendwindow __P((void));
void setsignal __P((int));
int speed __P((int));
void sigwinch __P((int));
void stop __P((int));
__dead void usage __P((void));
@ -151,27 +153,26 @@ main(argc, argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind;
struct passwd *pw;
struct servent *sp;
struct termios tty;
long omask;
sigset_t smask;
int argoff, ch, dflag, one, uid;
int i, len, len2;
char *host, *p, *user, term[1024] = "network";
speed_t ospeed;
struct sigaction sa;
argoff = dflag = 0;
one = 1;
host = user = NULL;
if (p = rindex(argv[0], '/'))
if (p = strrchr(argv[0], '/'))
++p;
else
p = argv[0];
if (strcmp(p, "rlogin"))
if (strcmp(p, "rlogin") != 0)
host = p;
/* handle "rlogin host flags" */
@ -237,9 +238,17 @@ main(argc, argv)
if (*argv)
usage();
if (!(pw = getpwuid(uid = getuid()))) {
(void)fprintf(stderr, "rlogin: unknown user id.\n");
exit(1);
if (!(pw = getpwuid(uid = getuid())))
errx(1, "unknown user id.");
/* Accept user1@host format, though "-l user2" overrides user1 */
p = strchr(host, '@');
if (p) {
*p = '\0';
if (!user && p > host)
user = host;
host = p + 1;
if (*host == '\0')
usage();
}
if (!user)
user = pw->pw_name;
@ -257,10 +266,8 @@ main(argc, argv)
#endif
if (sp == NULL)
sp = getservbyname("login", "tcp");
if (sp == NULL) {
(void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n");
exit(1);
}
if (sp == NULL)
errx(1, "login/tcp: unknown service.");
if (p = getenv("TERM")) {
(void)strncpy(term, p, sizeof(term) - 1);
@ -278,17 +285,25 @@ main(argc, argv)
(void)get_window_size(0, &winsize);
(void)signal(SIGPIPE, lostpeer);
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = lostpeer;
(void)sigaction(SIGPIPE, &sa, (struct sigaction *) 0);
/* will use SIGUSR1 for window size hack, so hold it off */
omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
sigemptyset(&smask);
sigaddset(&smask, SIGURG);
sigaddset(&smask, SIGUSR1);
(void)sigprocmask(SIG_SETMASK, &smask, &smask);
/*
* We set SIGURG and SIGUSR1 below so that an
* incoming signal will be held pending rather than being
* discarded. Note that these routines will be ready to get
* a signal by the time that they are unblocked below.
*/
(void)signal(SIGURG, copytochild);
(void)signal(SIGUSR1, writeroob);
sa.sa_handler = copytochild;
(void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
sa.sa_handler = writeroob;
(void)sigaction(SIGUSR1, &sa, (struct sigaction *) 0);
#ifdef KERBEROS
try_connect:
@ -297,11 +312,8 @@ try_connect:
/* Fully qualify hostname (needed for krb_realmofhost). */
hp = gethostbyname(host);
if (hp != NULL && !(host = strdup(hp->h_name))) {
(void)fprintf(stderr, "rlogin: %s\n",
strerror(ENOMEM));
exit(1);
}
if (hp != NULL && !(host = strdup(hp->h_name)))
errx(1, "%s", strerror(ENOMEM));
rem = KSUCCESS;
errno = 0;
@ -319,11 +331,8 @@ try_connect:
if (rem < 0) {
use_kerberos = 0;
sp = getservbyname("login", "tcp");
if (sp == NULL) {
(void)fprintf(stderr,
"rlogin: unknown service login/tcp.\n");
exit(1);
}
if (sp == NULL)
errx(1, "unknown service login/tcp.");
if (errno == ECONNREFUSED)
warning("remote host doesn't support Kerberos");
if (errno == ENOENT)
@ -332,11 +341,8 @@ try_connect:
}
} else {
#ifdef CRYPT
if (doencrypt) {
(void)fprintf(stderr,
"rlogin: the -x flag requires Kerberos authentication.\n");
exit(1);
}
if (doencrypt)
errx(1, "the -x flag requires Kerberos authentication.");
#endif /* CRYPT */
rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
}
@ -349,35 +355,78 @@ try_connect:
if (dflag &&
setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
(void)fprintf(stderr, "rlogin: setsockopt: %s.\n",
strerror(errno));
warn("setsockopt DEBUG (ignored)");
one = IPTOS_LOWDELAY;
if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)
perror("rlogin: setsockopt TOS (ignored)");
warn("setsockopt TOS (ignored)");
(void)setuid(uid);
doit(omask);
doit(&smask);
/*NOTREACHED*/
}
int child;
#if BSD >= 198810
int
speed(fd)
int fd;
{
struct termios tt;
(void)tcgetattr(fd, &tt);
return ((int) cfgetispeed(&tt));
}
#else
int speeds[] = { /* for older systems, B0 .. EXTB */
0, 50, 75, 110,
134, 150, 200, 300,
600, 1200, 1800, 2400,
4800, 9600, 19200, 38400
};
int
speed(fd)
int fd;
{
struct termios tt;
(void)tcgetattr(fd, &tt);
return (speeds[(int)cfgetispeed(&tt)]);
}
#endif
pid_t child;
struct termios deftt;
struct termios nott;
void
doit(omask)
long omask;
doit(smask)
sigset_t *smask;
{
int i;
struct sigaction sa;
(void)signal(SIGINT, SIG_IGN);
for (i = 0; i < NCCS; i++)
nott.c_cc[i] = _POSIX_VDISABLE;
tcgetattr(0, &deftt);
nott.c_cc[VSTART] = deftt.c_cc[VSTART];
nott.c_cc[VSTOP] = deftt.c_cc[VSTOP];
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = SIG_IGN;
(void)sigaction(SIGINT, &sa, (struct sigaction *) 0);
setsignal(SIGHUP);
setsignal(SIGQUIT);
mode(1);
child = fork();
if (child == -1) {
(void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno));
warn("fork");
done(1);
}
if (child == 0) {
if (reader(omask) == 0) {
mode(1);
if (reader(smask) == 0) {
msg("connection closed.");
exit(0);
}
@ -393,8 +442,9 @@ doit(omask)
* signals to the child. We can now unblock SIGURG and SIGUSR1
* that were set above.
*/
(void)sigsetmask(omask);
(void)signal(SIGCHLD, catch_child);
(void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
sa.sa_handler = catch_child;
(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
writer();
msg("closed connection.");
done(0);
@ -405,25 +455,41 @@ void
setsignal(sig)
int sig;
{
int omask = sigblock(sigmask(sig));
struct sigaction sa;
sigset_t sigs;
if (signal(sig, exit) == SIG_IGN)
(void)signal(sig, SIG_IGN);
(void)sigsetmask(omask);
sigemptyset(&sigs);
sigaddset(&sigs, sig);
sigprocmask(SIG_BLOCK, &sigs, &sigs);
sigemptyset(&sa.sa_mask);
sa.sa_handler = exit;
sa.sa_flags = SA_RESTART;
(void)sigaction(sig, &sa, &sa);
if (sa.sa_handler == SIG_IGN)
(void)sigaction(sig, &sa, (struct sigaction *) 0);
(void)sigprocmask(SIG_SETMASK, &sigs, (sigset_t *) 0);
}
__dead void
done(status)
int status;
{
int w, wstatus;
pid_t w;
int wstatus;
struct sigaction sa;
mode(0);
if (child > 0) {
/* make sure catch_child does not snap it up */
(void)signal(SIGCHLD, SIG_DFL);
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
if (kill(child, SIGKILL) >= 0)
while ((w = wait(&wstatus)) > 0 && w != child);
while ((w = wait(&wstatus)) > 0 && w != child)
continue;
}
exit(status);
}
@ -438,9 +504,14 @@ void
writeroob(signo)
int signo;
{
struct sigaction sa;
if (dosigwinch == 0) {
sendwindow();
(void)signal(SIGWINCH, sigwinch);
sigemptyset(&sa.sa_mask);
sa.sa_handler = sigwinch;
sa.sa_flags = SA_RESTART;
(void)sigaction(SIGWINCH, &sa, (struct sigaction *) 0);
}
dosigwinch = 1;
}
@ -449,16 +520,16 @@ void
catch_child(signo)
int signo;
{
union wait status;
int pid;
int status;
pid_t pid;
for (;;) {
pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL);
pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
if (pid == 0)
return;
/* if the child (reader) dies, just quit */
if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
done((int)(status.w_termsig | status.w_retcode));
done(WEXITSTATUS(status) | WTERMSIG(status));
}
/* NOTREACHED */
}
@ -580,10 +651,16 @@ void
stop(all)
int all;
{
struct sigaction sa;
mode(0);
(void)signal(SIGCHLD, SIG_IGN);
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_IGN;
sa.sa_flags = SA_RESTART;
(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
(void)kill(all ? 0 : getpid(), SIGTSTP);
(void)signal(SIGCHLD, catch_child);
sa.sa_handler = catch_child;
(void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
mode(1);
sigwinch(0); /* check for size changes */
}
@ -595,7 +672,7 @@ sigwinch(signo)
struct winsize ws;
if (dosigwinch && get_window_size(0, &ws) == 0 &&
bcmp(&ws, &winsize, sizeof(ws))) {
memcmp(&ws, &winsize, sizeof(ws))) {
winsize = ws;
sendwindow();
}
@ -637,7 +714,8 @@ sendwindow()
#define WRITING 2
jmp_buf rcvtop;
int ppid, rcvcnt, rcvstate;
pid_t ppid;
int rcvcnt, rcvstate;
char rcvbuf[8 * 1024];
void
@ -691,8 +769,7 @@ oob(signo)
(void)tcflush(1, TCIOFLUSH);
for (;;) {
if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
(void)fprintf(stderr, "rlogin: ioctl: %s.\n",
strerror(errno));
warn("ioctl SIOCATMARK (ignored)");
break;
}
if (atmark)
@ -724,23 +801,29 @@ oob(signo)
/* reader: read from remote: line -> 1 */
int
reader(omask)
int omask;
reader(smask)
sigset_t *smask;
{
int pid, n, remaining;
pid_t pid;
int n, remaining;
char *bufp;
struct sigaction sa;
#if BSD >= 43 || defined(SUNOS4)
pid = getpid(); /* modern systems use positives for pid */
#else
pid = -getpid(); /* old broken systems use negatives */
#endif
(void)signal(SIGTTOU, SIG_IGN);
(void)signal(SIGURG, oob);
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = SIG_IGN;
(void)sigaction(SIGTTOU, &sa, (struct sigaction *) 0);
sa.sa_handler = oob;
(void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
ppid = getppid();
(void)fcntl(rem, F_SETOWN, pid);
(void)setjmp(rcvtop);
(void)sigsetmask(omask);
(void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
bufp = rcvbuf;
for (;;) {
while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
@ -770,8 +853,7 @@ reader(omask)
if (rcvcnt < 0) {
if (errno == EINTR)
continue;
(void)fprintf(stderr, "rlogin: read: %s.\n",
strerror(errno));
warn("read");
return (-1);
}
}
@ -803,6 +885,7 @@ mode(f)
}
(void)tcsetattr(0, TCSANOW, &tty);
break;
default:
return;
}
@ -812,7 +895,10 @@ void
lostpeer(signo)
int signo;
{
(void)signal(SIGPIPE, SIG_IGN);
struct sigaction sa;
sa.sa_flags = SA_RESTART;
sa.sa_handler = SIG_IGN;
(void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
msg("\aconnection closed.");
done(1);
}
@ -822,6 +908,7 @@ void
copytochild(signo)
int signo;
{
(void)kill(child, SIGURG);
}
@ -829,6 +916,7 @@ void
msg(str)
char *str;
{
(void)fprintf(stderr, "rlogin: %s\r\n", str);
}
@ -861,7 +949,7 @@ __dead void
usage()
{
(void)fprintf(stderr,
"usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",
"usage: rlogin [ -%s]%s[-e char] [ -l username ] [username@]host\n",
#ifdef KERBEROS
#ifdef CRYPT
"8EKLx", " [-k realm] ");