summaryrefslogtreecommitdiffstats
path: root/usr.bin/rlogin
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1997-07-06 06:54:14 +0000
committerbde <bde@FreeBSD.org>1997-07-06 06:54:14 +0000
commit4d7f45e2595cdda6921d9ed62f7ce9ba08453d13 (patch)
tree8a1e564deb1b54debb4947f8ee448223b4ef4fb3 /usr.bin/rlogin
parente9b5b21c359ab94dbe38c62aa507bd29c30d295c (diff)
downloadFreeBSD-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.c203
-rw-r--r--usr.bin/rlogin/rlogin.111
-rw-r--r--usr.bin/rlogin/rlogin.c358
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 *)&notc);
+ 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 *)&notc);
+ 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 = &notc;
- 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] ");
OpenPOWER on IntegriCloud