Sync to 4.4BSD-Lite2
This commit is contained in:
parent
81e84482e0
commit
29985c32a6
|
@ -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
|
||||
|
|
|
@ -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] ");
|
||||
|
|
Loading…
Reference in New Issue