diff options
author | bde <bde@FreeBSD.org> | 1997-07-06 06:54:14 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1997-07-06 06:54:14 +0000 |
commit | 4d7f45e2595cdda6921d9ed62f7ce9ba08453d13 (patch) | |
tree | 8a1e564deb1b54debb4947f8ee448223b4ef4fb3 /usr.bin/rlogin | |
parent | e9b5b21c359ab94dbe38c62aa507bd29c30d295c (diff) | |
download | FreeBSD-src-4d7f45e2595cdda6921d9ed62f7ce9ba08453d13.zip FreeBSD-src-4d7f45e2595cdda6921d9ed62f7ce9ba08453d13.tar.gz |
Finish importing Lite2's src/usr.bin, except for ex, diff, grep, mail,
pascal and vmstat.sparc. All changed files on the vendor branch should
already have been imported.
Diffstat (limited to 'usr.bin/rlogin')
-rw-r--r-- | usr.bin/rlogin/des_rw.c | 203 | ||||
-rw-r--r-- | usr.bin/rlogin/rlogin.1 | 11 | ||||
-rw-r--r-- | usr.bin/rlogin/rlogin.c | 358 |
3 files changed, 415 insertions, 157 deletions
diff --git a/usr.bin/rlogin/des_rw.c b/usr.bin/rlogin/des_rw.c new file mode 100644 index 0000000..dbe47f0 --- /dev/null +++ b/usr.bin/rlogin/des_rw.c @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)des_rw.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#ifdef CRYPT +#ifdef KERBEROS +#include <sys/param.h> + +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static unsigned char des_inbuf[10240], storage[10240], *store_ptr; +static bit_64 *key; +static u_char *key_schedule; + +/* XXX these should be in a kerberos include file */ +int krb_net_read __P((int, char *, int)); +#ifdef notdef +/* XXX too hard to make this work */ +int des_pcbc_encrypt __P((des_cblock *, des_cblock *, long, + des_key_schedule, des_cblock *, int)); +#endif + +/* + * NB: These routines will not function properly if NBIO + * is set + */ + +/* + * des_set_key + * + * Set des encryption/decryption key for use by the des_read and + * des_write routines + * + * The inkey parameter is actually the DES initial vector, + * and the insched is the DES Key unwrapped for faster decryption + */ + +void +des_set_key(inkey, insched) + bit_64 *inkey; + u_char *insched; +{ + key = inkey; + key_schedule = insched; +} + +void +des_clear_key() +{ + bzero((char *) key, sizeof(C_Block)); + bzero((char *) key_schedule, sizeof(Key_schedule)); +} + + +int +des_read(fd, buf, len) + int fd; + register char *buf; + int len; +{ + int nreturned = 0; + long net_len, rd_len; + int nstored = 0; + + if (nstored >= len) { + (void) bcopy(store_ptr, buf, len); + store_ptr += len; + nstored -= len; + return(len); + } else if (nstored) { + (void) bcopy(store_ptr, buf, nstored); + nreturned += nstored; + buf += nstored; + len -= nstored; + nstored = 0; + } + + if (krb_net_read(fd, (char *)&net_len, sizeof(net_len)) != + sizeof(net_len)) { + /* XXX can't read enough, pipe + must have closed */ + return(0); + } + net_len = ntohl(net_len); + if (net_len <= 0 || net_len > sizeof(des_inbuf)) { + /* preposterous length; assume out-of-sync; only + recourse is to close connection, so return 0 */ + return(0); + } + /* the writer tells us how much real data we are getting, but + we need to read the pad bytes (8-byte boundary) */ + rd_len = roundup(net_len, 8); + if (krb_net_read(fd, (char *)des_inbuf, rd_len) != rd_len) { + /* pipe must have closed, return 0 */ + return(0); + } + (void) des_pcbc_encrypt(des_inbuf, /* inbuf */ + storage, /* outbuf */ + net_len, /* length */ + key_schedule, /* DES key */ + key, /* IV */ + DECRYPT); /* direction */ + + if(net_len < 8) + store_ptr = storage + 8 - net_len; + else + store_ptr = storage; + + nstored = net_len; + if (nstored > len) { + (void) bcopy(store_ptr, buf, len); + nreturned += len; + store_ptr += len; + nstored -= len; + } else { + (void) bcopy(store_ptr, buf, nstored); + nreturned += nstored; + nstored = 0; + } + + return(nreturned); +} + +static unsigned char des_outbuf[10240]; /* > longest write */ + +int +des_write(fd, buf, len) + int fd; + char *buf; + int len; +{ + static int seeded = 0; + static char garbage_buf[8]; + long net_len, garbage; + + if(len < 8) { + if(!seeded) { + seeded = 1; + srandom((int) time((long *)0)); + } + garbage = random(); + /* insert random garbage */ + (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8)); + /* this "right-justifies" the data in the buffer */ + (void) bcopy(buf, garbage_buf + 8 - len, len); + } + /* pcbc_encrypt outputs in 8-byte (64 bit) increments */ + + (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf, + des_outbuf, + (len < 8) ? 8 : len, + key_schedule, /* DES key */ + key, /* IV */ + ENCRYPT); + + /* tell the other end the real amount, but send an 8-byte padded + packet */ + net_len = htonl(len); + (void) write(fd, &net_len, sizeof(net_len)); + (void) write(fd, des_outbuf, roundup(len,8)); + return(len); +} +#endif /* KERBEROS */ +#endif /* CRYPT */ diff --git a/usr.bin/rlogin/rlogin.1 b/usr.bin/rlogin/rlogin.1 index 60da3cc..979658a 100644 --- a/usr.bin/rlogin/rlogin.1 +++ b/usr.bin/rlogin/rlogin.1 @@ -29,21 +29,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 5439c48..4aee20e 100644 --- a/usr.bin/rlogin/rlogin.c +++ b/usr.bin/rlogin/rlogin.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)rlogin.c 8.4 (Berkeley) 4/29/95"; #endif /* not lint */ /* @@ -49,6 +49,7 @@ static char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93"; #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> @@ -59,7 +60,7 @@ static char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93"; #include <netdb.h> #include <pwd.h> #include <setjmp.h> -#include <sgtty.h> +#include <termios.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -98,11 +99,6 @@ int eight, litout, rem; int noescape; u_char escapechar = '~'; -char *speeds[] = { - "0", "50", "75", "110", "134", "150", "200", "300", "600", "1200", - "1800", "2400", "4800", "9600", "19200", "38400" -}; - #ifdef OLDSUN struct winsize { unsigned short ws_row, ws_col; @@ -115,7 +111,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 *)); @@ -123,9 +119,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((char)); __dead void usage __P((void)); @@ -144,25 +141,24 @@ main(argc, argv) int argc; char *argv[]; { - extern char *optarg; - extern int optind; struct passwd *pw; struct servent *sp; - struct sgttyb ttyb; - long omask; - int argoff, ch, dflag, one, uid; + sigset_t smask; + uid_t uid; + int argoff, ch, dflag, one; char *host, *p, *user, term[1024]; + 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" */ @@ -231,9 +227,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; @@ -251,30 +255,34 @@ 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."); - (void)strcpy(term, (p = getenv("TERM")) ? p : "network"); - if (ioctl(0, TIOCGETP, &ttyb) == 0) { - (void)strcat(term, "/"); - (void)strcat(term, speeds[(int)ttyb.sg_ospeed]); - } + (void)snprintf(term, sizeof(term), "%s/%d", + ((p = getenv("TERM")) ? p : "network"), + speed(0)); (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: @@ -283,11 +291,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; @@ -305,11 +310,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) @@ -318,11 +320,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); } @@ -335,52 +334,77 @@ 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, defflags, deflflags, tabflag; -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 }; +#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; { - 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); + int i; + struct sigaction sa; + + 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); child = fork(); if (child == -1) { - (void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno)); + warn("fork"); done(1); } if (child == 0) { mode(1); - if (reader(omask) == 0) { + if (reader(smask) == 0) { msg("connection closed."); exit(0); } @@ -396,8 +420,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); @@ -408,25 +433,41 @@ void setsignal(sig) int sig; { - int omask = sigblock(sigmask(sig)); + struct sigaction sa; + sigset_t sigs; + + 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); - if (signal(sig, exit) == SIG_IGN) - (void)signal(sig, SIG_IGN); - (void)sigsetmask(omask); + (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); } @@ -441,9 +482,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; } @@ -452,16 +498,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 */ } @@ -502,11 +548,11 @@ writer() } } else if (local) { local = 0; - if (c == '.' || c == deftc.t_eofc) { + if (c == '.' || c == deftt.c_cc[VEOF]) { echo(c); break; } - if (c == defltc.t_suspc || c == defltc.t_dsuspc) { + if (c == deftt.c_cc[VSUSP] || c == deftt.c_cc[VDSUSP]) { bol = 1; echo(c); stop(c); @@ -538,8 +584,8 @@ writer() msg("line gone"); break; } - bol = c == defkill || c == deftc.t_eofc || - c == deftc.t_intrc || c == defltc.t_suspc || + bol = c == deftt.c_cc[VKILL] || c == deftt.c_cc[VEOF] || + c == deftt.c_cc[VINTR] || c == deftt.c_cc[VSUSP] || c == '\r' || c == '\n'; } } @@ -579,10 +625,16 @@ stop(cmdc) char cmdc; #endif { + struct sigaction sa; + mode(0); - (void)signal(SIGCHLD, SIG_IGN); - (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); - (void)signal(SIGCHLD, catch_child); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_RESTART; + (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0); + (void)kill(cmdc == deftt.c_cc[VSUSP] ? 0 : getpid(), SIGTSTP); + sa.sa_handler = catch_child; + (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0); mode(1); sigwinch(0); /* check for size changes */ } @@ -594,7 +646,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(); } @@ -636,14 +688,15 @@ sendwindow() #define WRITING 2 jmp_buf rcvtop; -int ppid, rcvcnt, rcvstate; +pid_t ppid; +int rcvcnt, rcvstate; char rcvbuf[8 * 1024]; void oob(signo) int signo; { - struct sgttyb sb; + struct termios tt; int atmark, n, out, rcvd; char waste[BUFSIZ], mark; @@ -678,29 +731,24 @@ oob(signo) (void)kill(ppid, SIGUSR1); } if (!eight && (mark & TIOCPKT_NOSTOP)) { - (void)ioctl(0, TIOCGETP, (char *)&sb); - sb.sg_flags &= ~CBREAK; - sb.sg_flags |= RAW; - (void)ioctl(0, TIOCSETN, (char *)&sb); - notc.t_stopc = -1; - notc.t_startc = -1; - (void)ioctl(0, TIOCSETC, (char *)¬c); + tcgetattr(0, &tt); + tt.c_iflag &= ~(IXON | IXOFF); + tt.c_cc[VSTOP] = _POSIX_VDISABLE; + tt.c_cc[VSTART] = _POSIX_VDISABLE; + tcsetattr(0, TCSANOW, &tt); } if (!eight && (mark & TIOCPKT_DOSTOP)) { - (void)ioctl(0, TIOCGETP, (char *)&sb); - sb.sg_flags &= ~RAW; - sb.sg_flags |= CBREAK; - (void)ioctl(0, TIOCSETN, (char *)&sb); - notc.t_stopc = deftc.t_stopc; - notc.t_startc = deftc.t_startc; - (void)ioctl(0, TIOCSETC, (char *)¬c); + tcgetattr(0, &tt); + tt.c_iflag |= (IXON|IXOFF); + tt.c_cc[VSTOP] = deftt.c_cc[VSTOP]; + tt.c_cc[VSTART] = deftt.c_cc[VSTART]; + tcsetattr(0, TCSANOW, &tt); } if (mark & TIOCPKT_FLUSHWRITE) { (void)ioctl(1, TIOCFLUSH, (char *)&out); for (;;) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) { - (void)fprintf(stderr, "rlogin: ioctl: %s.\n", - strerror(errno)); + warn("ioctl SIOCATMARK (ignored)"); break; } if (atmark) @@ -732,23 +780,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) { @@ -778,8 +832,7 @@ reader(omask) if (rcvcnt < 0) { if (errno == EINTR) continue; - (void)fprintf(stderr, "rlogin: read: %s.\n", - strerror(errno)); + warn("read"); return (-1); } } @@ -789,49 +842,44 @@ void mode(f) int f; { - struct ltchars *ltc; - struct sgttyb sb; - struct tchars *tc; - int lflags; - - (void)ioctl(0, TIOCGETP, (char *)&sb); - (void)ioctl(0, TIOCLGET, (char *)&lflags); - switch(f) { + struct termios tt; + + switch (f) { case 0: - sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); - sb.sg_flags |= defflags|tabflag; - tc = &deftc; - ltc = &defltc; - sb.sg_kill = defkill; - sb.sg_erase = deferase; - lflags = deflflags; + tcsetattr(0, TCSADRAIN, &deftt); break; case 1: - 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_flags &= ~TBDELAY; - tc = ¬c; - ltc = &noltc; - sb.sg_kill = sb.sg_erase = -1; - if (litout) - lflags |= LLITOUT; + tt = deftt; + tt.c_oflag &= ~(OPOST); + tt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + tt.c_iflag &= ~(ICRNL); + tt.c_cc[VMIN] = 1; + tt.c_cc[VTIME] = 0; + if (eight) { + tt.c_iflag &= ~(IXON | IXOFF | ISTRIP); + tt.c_cc[VSTOP] = _POSIX_VDISABLE; + tt.c_cc[VSTART] = _POSIX_VDISABLE; + } + /*if (litout) + lflags |= LLITOUT;*/ + tcsetattr(0, TCSADRAIN, &tt); break; + default: 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); } void lostpeer(signo) int signo; { - (void)signal(SIGPIPE, SIG_IGN); + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sa.sa_handler = SIG_IGN; + (void)sigaction(SIGPIPE, &sa, (struct sigaction *) 0); msg("\007connection closed."); done(1); } @@ -841,6 +889,7 @@ void copytochild(signo) int signo; { + (void)kill(child, SIGURG); } @@ -848,6 +897,7 @@ void msg(str) char *str; { + (void)fprintf(stderr, "rlogin: %s\r\n", str); } @@ -880,7 +930,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] "); |