From 29985c32a6f0b73acb09757d5df6f51e0c842089 Mon Sep 17 00:00:00 2001 From: tls Date: Thu, 9 Jan 1997 06:57:45 +0000 Subject: [PATCH] Sync to 4.4BSD-Lite2 --- usr.bin/rlogin/rlogin.1 | 13 ++- usr.bin/rlogin/rlogin.c | 240 +++++++++++++++++++++++++++------------- 2 files changed, 173 insertions(+), 80 deletions(-) diff --git a/usr.bin/rlogin/rlogin.1 b/usr.bin/rlogin/rlogin.1 index 76a9c15ca852..7cf5fdb01e37 100644 --- a/usr.bin/rlogin/rlogin.1 +++ b/usr.bin/rlogin/rlogin.1 @@ -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 diff --git a/usr.bin/rlogin/rlogin.c b/usr.bin/rlogin/rlogin.c index d00958d69c01..7ae681a51135 100644 --- a/usr.bin/rlogin/rlogin.c +++ b/usr.bin/rlogin/rlogin.c @@ -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 #include #include +#include #include #include @@ -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] ");