#ifndef lint
-static char sccsid[] = "@(#)rlogin.c 4.4 82/11/15";
+static char sccsid[] = "@(#)rlogin.c 4.5 82/11/27";
#endif
-#include <stdio.h>
-#include <sgtty.h>
#include <sys/types.h>
#include <sys/socket.h>
+
#include <netinet/in.h>
+
+#include <stdio.h>
+#include <sgtty.h>
#include <errno.h>
#include <pwd.h>
+#include <signal.h>
+#include <netdb.h>
/*
- * rlogin - remote login; this is a hacked version of cu
+ * rlogin - remote login
*/
char *index(), *rindex(), *malloc(), *getenv();
struct passwd *getpwuid();
-struct passwd *pwd;
-char *name, *pass;
+char *name;
int rem;
char cmdchar = '~';
int rcmdoptions = 0;
char *speeds[] =
{ "0", "50", "75", "110", "134", "150", "200", "300",
"600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
-char term[64] = "dumb";
+char term[64] = "network";
+extern int errno;
+int lostpeer();
+
+#define CTRL(c) ('c' & 037)
main(argc, argv)
int argc;
char **argv;
{
- int pid;
- char *host, *cp, **ap, buf[BUFSIZ];
- register int cc;
+ char *host, *cp;
struct sgttyb ttyb;
struct passwd *pwd;
+ struct servent *sp;
+ int uid;
host = rindex(argv[0], '/');
if (host)
fprintf(stderr, "Who are you?\n");
exit(1);
}
- cc = 0;
+ sp = getservbyname("login", "tcp");
+ if (sp == 0) {
+ fprintf(stderr, "rlogin: login/tcp: unknown service\n");
+ exit(2);
+ }
cp = getenv("TERM");
if (cp)
strcpy(term, cp);
strcat(term, "/");
strcat(term, speeds[ttyb.sg_ospeed]);
}
- rem = rcmd(&host, IPPORT_LOGINSERVER, pwd->pw_name,
+ signal(SIGPIPE, lostpeer);
+ rem = rcmd(&host, sp->s_port, pwd->pw_name,
name ? name : pwd->pw_name, term, 0);
if (rem < 0)
exit(1);
- setuid(getuid());
- cumain();
- exit(0);
+ uid = getuid();
+ if (setuid(uid) < 0) {
+ perror("rlogin: setuid");
+ exit(1);
+ }
+ doit();
+ /*NOTREACHED*/
usage:
fprintf(stderr,
"usage: rlogin host [ -ex ] [ -l username ]\n");
exit(1);
}
-#include <ctype.h>
-#include <signal.h>
-
#define CRLF "\r\n"
-#define wrc(ds) write(ds,&c,1)
-
-char tkill, terase; /* current input kill & erase */
-int efk; /* process of id of listener */
-char c, oc;
-int pipes[] = {-1,-1};
-int intr, sig2();
-int parent;
-int nhup;
+int child;
int done();
-struct tchars deftchars;
-struct tchars notchars = { 0377, 0377, 'q'&037, 's'&037, 0377, 0377 };
-struct ltchars defltchars;
-struct ltchars noltchars = { 0377, 0377, 0377, 0377, 0377, 0377 };
-char defkill, deferase, defflags;
+char tkill, terase; /* current input kill & erase */
+char defkill, deferase, defflags;
-cumain()
+struct tchars deftchars;
+struct tchars notchars = { -1, -1, CTRL(q), CTRL(s), -1, -1 };
+struct ltchars defltchars;
+struct ltchars noltchars = { -1, -1, -1, -1, -1, -1 };
+
+doit()
{
- int fk;
- int speed;
- char *telno;
struct sgttyb stbuf;
int exit();
- gtty(0, &stbuf);
+ ioctl(0, TIOCGETP, (char *)&stbuf);
defkill = stbuf.sg_kill;
deferase = stbuf.sg_erase;
defflags = stbuf.sg_flags & (ECHO | CRMOD);
- ioctl(0, TIOCGETC, &deftchars);
- ioctl(0, TIOCGLTC, &defltchars);
+ ioctl(0, TIOCGETC, (char *)&deftchars);
+ ioctl(0, TIOCGLTC, (char *)&defltchars);
signal(SIGINT, exit);
signal(SIGHUP, exit);
signal(SIGQUIT, exit);
- pipe(pipes);
- parent = getpid();
- fk = fork();
- nhup = (int)signal(SIGINT, SIG_IGN);
- if (fk == 0) {
- rd();
- sleep(1);
+ child = fork();
+ if (child == -1) {
+ perror("rlogin: fork");
+ done();
+ }
+ signal(SIGINT, SIG_IGN);
+ if (child == 0) {
+ signal(SIGPIPE, SIG_IGN);
+ reader();
prf("\007Lost connection.");
exit(3);
}
signal(SIGCHLD, done);
mode(1);
- efk = fk;
- wr();
- if (fk != -1) kill(fk, SIGKILL);
+ writer();
prf("Disconnected.");
done();
}
{
mode(0);
- wait((int *)NULL);
+ if (child > 0 && kill(child, SIGKILL) >= 0)
+ wait((int *)0);
exit(0);
}
/*
- * wr: write to remote: 0 -> line.
- * ~. terminate
- * ~<file send file
- * ~! local login-style shell
- * ~!cmd execute cmd locally
- * ~$proc execute proc locally, send output to line
- * ~%cmd execute builtin cmd (put and take)
- * ~^Z suspend cu process.
+ * writer: write to remote: 0 -> line.
+ * ~. terminate
+ * ~^Z suspend rlogin process.
*/
-
-wr()
+writer()
{
- int ds,fk,lcl,x;
- char *p,b[600];
- for (;;) {
- p=b;
- while (rdc(0) == 1) {
- if (p == b) lcl=(c == cmdchar);
- if (p == b+1 && b[0] == cmdchar) lcl=(c!=cmdchar);
- if (!lcl) {
- c = oc;
- if (wrc(rem) == 0) {
- prf("line gone"); return;
- }
- if (eight == 0)
- c &= 0177;
- }
- if (lcl) {
- if (c == 0177) c=tkill;
- if (c == '\r' || c == '\n') goto A;
- wrc(0);
- }
- *p++=c;
- if (c == terase) {
- p=p-2;
- if (p<b) p=b;
- }
- if (c == tkill || c == 0177 || c == '\4' || c == '\r' || c == '\n') p=b;
- }
- return;
-A:
- echo("");
- *p=0;
- switch (b[1]) {
- case '.':
- case '\004':
- return;
- case '!':
- case '$':
- fk = fork();
- signal(SIGCHLD, SIG_DFL);
- if (fk == 0) {
- char *shell = getenv("SHELL");
- if (shell == 0) shell = "/bin/sh";
- close(1);
- dup(b[1] == '$'? rem:2);
- close(rem);
- mode(0);
- if (!nhup) signal(SIGINT, SIG_DFL);
- if (b[2] == 0) execl(shell,shell,0);
- /* if (b[2] == 0) execl(shell,"-",0); */
- else execl(shell,"sh","-c",b+2,0);
- prf("Can't execute shell");
- exit(~0);
- }
- if (fk!=(-1)) {
- while (wait(&x)!=fk);
- }
- signal(SIGCHLD, done);
- mode(1);
- if (b[1] == '!') echo("!");
- break;
- case '<':
- if (b[2] == 0) break;
- if ((ds=open(b+2,0))<0) {
- prf("Can't divert %s",b+1);
- break;
- }
- intr=x=0;
- mode(2);
- if (!nhup) signal(SIGINT, sig2);
- while (!intr && rdc(ds) == 1) {
- if (wrc(rem) == 0) {
- x=1;
- break;
- }
- }
- signal(SIGINT, SIG_IGN);
- close(ds);
- mode(1);
- if (x) return;
- break;
- case '>':
- case ':':
- {
- register char *q;
+ char b[600], c;
+ register char *p;
- q = b+1;
- if(*q=='>') q++;
- write(pipes[1],q,strlen(q)+1);
- if (efk != -1) kill(efk,SIGEMT);
- }
- break;
-#ifdef SIGTSTP
-#define CTRLZ 26
- case CTRLZ:
- mode(0);
- signal(SIGCHLD, SIG_IGN);
- kill(0, SIGTSTP);
- signal(SIGCHLD, done);
- mode(1);
- break;
-#endif
- case '%':
- dopercen(&b[2]);
- break;
- default:
- prf("Use `%c%c' to start line with `%c'", cmdchar, cmdchar, cmdchar);
- }
- continue;
- }
-}
+top:
+ p = b;
+ while (read(0, &c, 1) > 0) {
+ int local;
-dopercen(line)
-register char *line;
-{
- char *args[10];
- register narg, f;
- int rcount;
- for (narg = 0; narg < 10;) {
- while(*line == ' ' || *line == '\t')
- line++;
- if (*line == '\0')
- break;
- args[narg++] = line;
- while(*line != '\0' && *line != ' ' && *line != '\t')
- line++;
- if (*line == '\0')
- break;
- *line++ = '\0';
- }
- if (equal(args[0], "take")) {
- if (narg < 2) {
- prf("usage: %c%%take from [to]", cmdchar);
- return;
- }
- if (narg < 3)
- args[2] = args[1];
- write(pipes[1], ">/dev/null",sizeof(">/dev/null"));
- if (efk != -1) kill(efk,SIGEMT);
- sleep(5);
- wrln("echo '%c>:", cmdchar);
- wrln(args[2]);
- wrln("'; tee /dev/null <");
- wrln(args[1]);
- wrln(";echo '%c>'\n", cmdchar);
- return;
- } else if (equal(args[0], "put")) {
- prf("%c%%put doesn't work yet (use rsh)", cmdchar);
- return;
-/*
- if (narg < 2) {
- prf("usage: %c%%put from [to]", cmdchar);
- return;
- }
- if (narg < 3)
- args[2] = args[1];
- if ((f = open(args[1], 0)) < 0) {
- prf("cannot open: %s", args[1]);
- return;
- }
- wrln("stty -echo;cat >");
- wrln(args[2]);
- wrln(";stty echo\n");
- sleep(5);
- intr = 0;
- if (!nhup)
- signal(SIGINT, sig2);
- mode(2);
- rcount = 0;
- while(!intr && rdc(f) == 1) {
- rcount++;
- if (c == tkill || c == terase)
- wrln("\\");
- if (wrc(rem) != 1) {
- sleep(2);
- if (wrc(rem) != 1) {
- prf("character missed");
- intr = 1;
- break;
+ if (eight == 0)
+ c &= 0177;
+ /*
+ * If we're at the beginning of the line
+ * and recognize a command character, then
+ * we echo locally. Otherwise, characters
+ * are echo'd remotely. If the command
+ * character is doubled, this acts as a
+ * force and local echo is suppressed.
+ */
+ if (p == b)
+ local = (c == cmdchar);
+ if (p == b + 1 && *b == cmdchar)
+ local = (c != cmdchar);
+ if (!local) {
+ if (write(rem, &c, 1) == 0) {
+ prf("line gone");
+ return;
+ }
+ if (eight == 0)
+ c &= 0177;
+ } else {
+ if (c == 0177)
+ c = tkill;
+ if (c == '\r' || c == '\n') {
+ switch (b[1]) {
+
+ case '.':
+ case CTRL(d):
+ write(0, CRLF, sizeof(CRLF));
+ return;
+
+ case CTRL(z):
+ write(0, CRLF, sizeof(CRLF));
+ mode(0);
+ signal(SIGCHLD, SIG_IGN);
+ kill(0, SIGTSTP);
+ signal(SIGCHLD, done);
+ mode(1);
+ goto top;
}
+ *p++ = c;
+ write(rem, b, p - b);
+ goto top;
}
+ write(1, &c, 1);
}
- signal(SIGINT, SIG_IGN);
- close(f);
- if (intr) {
- wrln("\n");
- prf("stopped after %d bytes", rcount);
- }
- wrln("\004");
- sleep(5);
- mode(1);
- return;
-*/
- }
- prf("%c%%%s unknown\n", cmdchar, args[0]);
-}
-
-equal(s1, s2)
-register char *s1, *s2;
-{
- while (*s1++ == *s2)
- if (*s2++ == '\0')
- return(1);
- return(0);
-}
-
-wrln(s, p1, p2, p3)
-register char *s;
-int p1, p2, p3;
-{
- char wbuf[256];
-
- sprintf(wbuf, s, p1, p2, p3);
- s = wbuf;
- while (*s)
- write(rem, s++, 1);
-}
-int ds,slnt;
-int justrung;
-
-/*
- * rd: read from remote: line -> 1
- * catch:
- * ~>[>][:][file]
- * stuff from file...
- * ~> (ends diversion)
- */
-
-int ds,slnt,taking;
-int justrung;
-readmsg(){
- static char dobuff[128], morejunk[256];
- int n;
- justrung = 1;
- signal(SIGEMT,readmsg);
- n = read(pipes[0],morejunk,256);
- dodiver(morejunk);
-}
-
-dodiver(msg)
-char *msg;
-{
- register char *cp = msg;
-
- if (*cp=='>') cp++;
- if (*cp==':') {
- cp++;
- if(*cp==0) {
- slnt ^= 1;
- return;
- } else {
- slnt = 1;
+ *p++ = c;
+ if (c == terase) {
+ p -= 2;
+ if (p < b)
+ goto top;
}
+ if (c == tkill || c == 0177 || c == CTRL(d) ||
+ c == '\r' || c == '\n')
+ goto top;
}
- if (ds >= 0) close(ds);
- if (*cp==0) {
- slnt = 0;
- ds = -1;
- return;
- }
- if (*msg!='>' || (ds=open(cp,1))<0) ds=creat(cp,0644);
- lseek(ds, (long)0, 2);
- if(ds < 0) prf("Creat failed:"), prf(cp);
- if (ds<0) prf("Can't divert %s",cp+1);
}
-
-/*
- * rd: read from remote: line -> 1
- * catch: diversion caught by interrupt routine
- */
-
-#define ORDIN 0
-#define SAWCR 1
-#define EOL 2
-#define SAWTL 3
-#define DIVER 4
-
oob()
{
- int mark, cc, out = 1+1;
- char waste[512];
+ int out = 1+1;
+ char waste[BUFSIZ], mark;
signal(SIGURG, oob);
- ioctl(1, TIOCFLUSH, &out);
+ ioctl(1, TIOCFLUSH, (char *)&out);
for (;;) {
if (ioctl(rem, SIOCATMARK, &mark) < 0) {
perror("ioctl");
}
if (mark)
break;
- cc = read(rem, waste, 512);
+ (void) read(rem, waste, sizeof (waste));
}
recv(rem, &mark, 1, SOF_OOB);
if (mark & TIOCPKT_NOSTOP) {
- notchars.t_stopc = 0377;
- notchars.t_startc = 0377;
- ioctl(0, TIOCSETC, ¬chars);
+ notchars.t_stopc = -1;
+ notchars.t_startc = -1;
+ ioctl(0, TIOCSETC, (char *)¬chars);
}
if (mark & TIOCPKT_DOSTOP) {
- notchars.t_stopc = 's'&037;
- notchars.t_startc = 'q'&037;
- ioctl(0, TIOCSETC, ¬chars);
+ notchars.t_stopc = CTRL(s);
+ notchars.t_startc = CTRL(q);
+ ioctl(0, TIOCSETC, (char *)¬chars);
}
}
-rd()
+/*
+ * reader: read from remote: line -> 1
+ */
+reader()
{
- extern int ds,slnt;
- char rb[600], lb[600], *rlim, *llim, c;
- register char *p,*q;
- int cnt, state = 0, mustecho, oldslnt, readmsg();
+ char rb[BUFSIZ];
+ register int cnt;
- signal(SIGEMT,readmsg); /* set up child for catching diversion msgs
- from parent */
- signal(SIGURG,oob);
+ signal(SIGURG, oob);
+#ifdef notdef
{ int pid = -getpid();
- ioctl(rem, SIOCSPGRP, &pid); }
- ds=(-1);
- p = lb; llim = lb+600;
-agin:
+ ioctl(rem, SIOCSPGRP, (char *)&pid); }
+#endif
for (;;) {
- extern errno;
- errno = 0;
- cnt = read(rem,rb,600);
+ cnt = read(rem, rb, sizeof (rb));
if (cnt <= 0) {
- if (errno == EINTR) {
- errno = 0;
+ if (errno == EINTR)
continue;
- }
break;
}
- if(!slnt) write(1,rb,cnt);
- if(ds < 0) continue;
- oldslnt = slnt;
- for( q=rb, rlim = rb + cnt - 1; q <= rlim; ) {
- if (eight == 0)
- c &= 0177;
- if(p < llim) *p++ = c;
- switch(state) {
- case ORDIN:
- if(c=='\r') state = SAWCR;
- break;
- case SAWCR:
- if(c=='\n') {
- state = EOL;
- p--;
- p[-1] = '\n';
- } else state = ORDIN;
- break;
- case EOL:
- state = (c==cmdchar ? SAWTL :
- (c=='\r' ? SAWCR : ORDIN));
- break;
- case SAWTL:
- state = (c=='>' ? DIVER :
- (c=='\r' ? SAWCR : ORDIN));
- break;
- case DIVER:
- if(c=='\r') {
- p--;
- } else if (c=='\n') {
- state = ORDIN;
- p[-1] = 0;
- dodiver(lb+2);
- c = 0; p = lb;
- }
- }
- if(slnt==0 && oldslnt) {
- if(c=='\n') {
- write(rem,lb,p-lb-1);
- write(rem,CRLF,sizeof(CRLF));
- } else if(q==rlim) {
- write(rem,lb,p-lb);
- c = '\n'; /*force flush to file*/
- }
- }
- if(c=='\n') {
- if(ds >= 0)
- write(ds,lb,p-lb);
- p = lb;
- }
- }
- }
- if(justrung) {
- justrung = 0;
- goto agin;
+ write(1, rb, cnt);
}
}
-struct {char lobyte; char hibyte;};
mode(f)
{
struct sgttyb stbuf;
- ioctl(0, TIOCGETP, &stbuf);
+
+ ioctl(0, TIOCGETP, (char *)&stbuf);
if (f == 0) {
stbuf.sg_flags &= ~CBREAK;
stbuf.sg_flags |= defflags;
- ioctl(0, TIOCSETC, &deftchars);
- ioctl(0, TIOCSLTC, &defltchars);
+ ioctl(0, TIOCSETC, (char *)&deftchars);
+ ioctl(0, TIOCSLTC, (char *)&defltchars);
stbuf.sg_kill = defkill;
stbuf.sg_erase = deferase;
}
if (f == 1) {
stbuf.sg_flags |= CBREAK;
stbuf.sg_flags &= ~(ECHO|CRMOD);
- ioctl(0, TIOCSETC, ¬chars);
- ioctl(0, TIOCSLTC, &noltchars);
- stbuf.sg_kill = 0377;
- stbuf.sg_erase = 0377;
+ ioctl(0, TIOCSETC, (char *)¬chars);
+ ioctl(0, TIOCSLTC, (char *)&noltchars);
+ stbuf.sg_kill = -1;
+ stbuf.sg_erase = -1;
}
if (f == 2) {
stbuf.sg_flags &= ~CBREAK;
stbuf.sg_flags &= ~(ECHO|CRMOD);
- ioctl(0, TIOCSETC, &deftchars);
- ioctl(0, TIOCSLTC, &defltchars);
- stbuf.sg_kill = 0377;
- stbuf.sg_erase = 0377;
+ ioctl(0, TIOCSETC, (char *)&deftchars);
+ ioctl(0, TIOCSLTC, (char *)&defltchars);
+ stbuf.sg_kill = -1;
+ stbuf.sg_erase = -1;
}
- ioctl(0, TIOCSETN, &stbuf);
-}
-
-echo(s)
-char *s;
-{
- char *p;
- for (p=s;*p;p++);
- if (p>s) write(0,s,p-s);
- write(0,CRLF, sizeof(CRLF));
+ ioctl(0, TIOCSETN, (char *)&stbuf);
}
+/*VARARGS*/
prf(f, a1, a2, a3)
-char *f;
+ char *f;
{
fprintf(stderr, f, a1, a2, a3);
fprintf(stderr, CRLF);
}
-exists(devname)
-char *devname;
-{
- if (access(devname, 0)==0)
- return(1);
- prf("%s does not exist", devname);
- return(0);
-}
-
-rdc(ds)
-{
-
- ds=read(ds,&c,1);
- oc = c;
- if (eight == 0)
- c &= 0177;
- return (ds);
-}
-
-sig2()
+lostpeer()
{
- signal(SIGINT, SIG_IGN);
- intr = 1;
+ signal(SIGPIPE, SIG_IGN);
+ prf("\007Lost connection");
+ done();
}