xref: /csrg-svn/usr.bin/rlogin/rlogin.c (revision 9207)
16444Swnj #ifndef lint
2*9207Ssam static char sccsid[] = "@(#)rlogin.c	4.3 82/11/14";
36444Swnj #endif
46444Swnj 
56444Swnj #include <stdio.h>
66444Swnj #include <sgtty.h>
76444Swnj #include <sys/types.h>
86444Swnj #include <sys/socket.h>
9*9207Ssam #include <netinet/in.h>
106444Swnj #include <errno.h>
116444Swnj #include <pwd.h>
126444Swnj 
136444Swnj /*
146444Swnj  * rlogin - remote login; this is a hacked version of cu
156444Swnj  */
166444Swnj char	*index(), *rindex(), *malloc(), *getenv();
176444Swnj struct	passwd *getpwuid();
186444Swnj struct	passwd *pwd;
196444Swnj char	*name, *pass;
206444Swnj int	rem;
216444Swnj char	cmdchar = '~';
226444Swnj int	rcmdoptions = 0;
236444Swnj int	eight;
246444Swnj char	*speeds[] =
256444Swnj     { "0", "50", "75", "110", "134", "150", "200", "300",
266444Swnj       "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
276444Swnj char	term[64];
286444Swnj 
296444Swnj main(argc, argv)
306444Swnj 	int argc;
316444Swnj 	char **argv;
326444Swnj {
336444Swnj 	int pid;
346444Swnj 	char *host, *cp, **ap, buf[BUFSIZ];
356444Swnj 	register int cc;
366444Swnj 	struct sgttyb ttyb;
376444Swnj 	struct passwd *pwd;
386444Swnj 
396444Swnj 	host = rindex(argv[0], '/');
406444Swnj 	if (host)
416444Swnj 		host++;
426444Swnj 	else
436444Swnj 		host = argv[0];
446444Swnj 	argv++, --argc;
456444Swnj 	if (!strcmp(host, "rlogin"))
466444Swnj 		host = *argv++, --argc;
476444Swnj another:
486444Swnj 	if (!strcmp(*argv, "-d")) {
496444Swnj 		argv++, argc--;
506444Swnj 		rcmdoptions |= SO_DEBUG;
516444Swnj 		goto another;
526444Swnj 	}
536444Swnj 	if (!strcmp(*argv, "-l")) {
546444Swnj 		argv++, argc--;
556444Swnj 		if (argc == 0)
566444Swnj 			goto usage;
576444Swnj 		name = *argv++; argc--;
586444Swnj 		goto another;
596444Swnj 	}
606444Swnj 	if (!strncmp(*argv, "-e", 2)) {
616444Swnj 		cmdchar = argv[0][2];
626444Swnj 		argv++, argc--;
636444Swnj 		goto another;
646444Swnj 	}
656444Swnj 	if (!strcmp(*argv, "-8")) {
666444Swnj 		eight = 1;
676444Swnj 		argv++, argc--;
686444Swnj 		goto another;
696444Swnj 	}
706444Swnj 	if (host == 0)
716444Swnj 		goto usage;
726444Swnj 	if (argc > 0)
736444Swnj 		goto usage;
746444Swnj 	pwd = getpwuid(getuid());
756444Swnj 	if (pwd == 0) {
766444Swnj 		fprintf(stderr, "Who are you?\n");
776444Swnj 		exit(1);
786444Swnj 	}
796444Swnj 	cc = 0;
806444Swnj 	strcpy(term, getenv("TERM"));
816444Swnj 	if (gtty(0, &ttyb)==0) {
826444Swnj 		strcat(term, "/");
836444Swnj 		strcat(term, speeds[ttyb.sg_ospeed]);
846444Swnj 	}
856444Swnj         rem = rcmd(&host, IPPORT_LOGINSERVER, pwd->pw_name,
866444Swnj 	    name ? name : pwd->pw_name, term, 0);
876444Swnj         if (rem < 0)
886444Swnj                 exit(1);
896444Swnj 	setuid(getuid());
906444Swnj 	cumain();
916444Swnj 	exit(0);
926444Swnj usage:
936444Swnj 	fprintf(stderr,
946444Swnj 	    "usage: rlogin host [ -ex ] [ -l username ]\n");
956444Swnj 	exit(1);
966444Swnj }
976444Swnj 
986444Swnj #include <ctype.h>
996444Swnj #include <signal.h>
1006444Swnj 
1016444Swnj #define CRLF "\r\n"
1026444Swnj #define wrc(ds) write(ds,&c,1)
1036444Swnj 
1046444Swnj char	tkill, terase;	/* current input kill & erase */
1056444Swnj int	efk;		/* process of id of listener  */
1066444Swnj char	c, oc;
1076444Swnj int	pipes[] = {-1,-1};
1086444Swnj int	intr, sig2();
1096444Swnj int	parent;
1106444Swnj 
1116444Swnj int	nhup;
1126444Swnj int	done();
1136444Swnj 
1146444Swnj struct tchars deftchars;
1156444Swnj struct tchars notchars = { 0377, 0377, 'q'&037, 's'&037, 0377, 0377 };
1166444Swnj struct ltchars defltchars;
1176444Swnj struct ltchars noltchars = { 0377, 0377, 0377, 0377, 0377, 0377 };
1186481Sjkf char defkill, deferase, defflags;
1196444Swnj 
1206444Swnj cumain()
1216444Swnj {
1226444Swnj 	int fk;
1236444Swnj 	int speed;
1246444Swnj 	char *telno;
1256444Swnj 	struct sgttyb stbuf;
1266444Swnj 	int exit();
1276444Swnj 
1286444Swnj 	gtty(0, &stbuf);
1296444Swnj 	defkill = stbuf.sg_kill;
1306444Swnj 	deferase = stbuf.sg_erase;
1316481Sjkf 	defflags = stbuf.sg_flags & (ECHO | CRMOD);
1326444Swnj 	ioctl(0, TIOCGETC, &deftchars);
1336444Swnj 	ioctl(0, TIOCGLTC, &defltchars);
1346444Swnj 	signal(SIGINT, exit);
1356444Swnj 	signal(SIGHUP, exit);
1366444Swnj 	signal(SIGQUIT, exit);
1376444Swnj 	pipe(pipes);
1386444Swnj 	parent = getpid();
1396444Swnj 	fk = fork();
1406444Swnj 	nhup = (int)signal(SIGINT, SIG_IGN);
1416444Swnj 	if (fk == 0) {
1426444Swnj 		rd();
1436444Swnj 		sleep(1);
1446444Swnj 		prf("\007Lost connection.");
1456444Swnj 		exit(3);
1466444Swnj 	}
1476444Swnj 	signal(SIGCHLD, done);
1486444Swnj 	mode(1);
1496444Swnj 	efk = fk;
1506444Swnj 	wr();
1516444Swnj 	if (fk != -1) kill(fk, SIGKILL);
1526444Swnj 	prf("Disconnected.");
1536444Swnj 	done();
1546444Swnj }
1556444Swnj 
1566444Swnj done()
1576444Swnj {
1586444Swnj 
1596444Swnj 	mode(0);
1606444Swnj 	wait((int *)NULL);
1616444Swnj 	exit(0);
1626444Swnj }
1636444Swnj 
1646444Swnj /*
1656444Swnj  *	wr: write to remote: 0 -> line.
1666444Swnj  *	~.	terminate
1676444Swnj  *	~<file	send file
1686444Swnj  *	~!	local login-style shell
1696444Swnj  *	~!cmd	execute cmd locally
1706444Swnj  *	~$proc	execute proc locally, send output to line
1716444Swnj  *	~%cmd	execute builtin cmd (put and take)
1726444Swnj  *	~^Z	suspend cu process.
1736444Swnj  */
1746444Swnj 
1756444Swnj wr()
1766444Swnj {
1776444Swnj 	int ds,fk,lcl,x;
1786444Swnj 	char *p,b[600];
1796444Swnj 	for (;;) {
1806444Swnj 		p=b;
1816444Swnj 		while (rdc(0) == 1) {
1826444Swnj 			if (p == b) lcl=(c == cmdchar);
1836444Swnj 			if (p == b+1 && b[0] == cmdchar) lcl=(c!=cmdchar);
1846444Swnj 			if (!lcl) {
1856444Swnj 				c = oc;
1866444Swnj 				if (wrc(rem) == 0) {
1876444Swnj 					prf("line gone"); return;
1886444Swnj 				}
1896444Swnj 				if (eight == 0)
1906444Swnj 					c &= 0177;
1916444Swnj 			}
1926444Swnj 			if (lcl) {
1936444Swnj 				if (c == 0177) c=tkill;
1946444Swnj 				if (c == '\r' || c == '\n') goto A;
1956444Swnj 				wrc(0);
1966444Swnj 			}
1976444Swnj 			*p++=c;
1986444Swnj 			if (c == terase) {
1996444Swnj 				p=p-2;
2006444Swnj 				if (p<b) p=b;
2016444Swnj 			}
2026444Swnj 			if (c == tkill || c == 0177 || c == '\4' || c == '\r' || c == '\n') p=b;
2036444Swnj 		}
2046444Swnj 		return;
2056444Swnj A:
2066444Swnj 		echo("");
2076444Swnj 		*p=0;
2086444Swnj 		switch (b[1]) {
2096444Swnj 		case '.':
2106444Swnj 		case '\004':
2116444Swnj 			return;
2126444Swnj 		case '!':
2136444Swnj 		case '$':
2146444Swnj 			fk = fork();
2156444Swnj 			signal(SIGCHLD, SIG_DFL);
2166444Swnj 			if (fk == 0) {
2176444Swnj 				char *shell = getenv("SHELL");
2186444Swnj 				if (shell == 0) shell = "/bin/sh";
2196444Swnj 				close(1);
2206444Swnj 				dup(b[1] == '$'? rem:2);
2216444Swnj 				close(rem);
2226444Swnj 				mode(0);
2236444Swnj 				if (!nhup) signal(SIGINT, SIG_DFL);
2246444Swnj 				if (b[2] == 0) execl(shell,shell,0);
2256444Swnj 				/* if (b[2] == 0) execl(shell,"-",0); */
2266444Swnj 				else execl(shell,"sh","-c",b+2,0);
2276444Swnj 				prf("Can't execute shell");
2286444Swnj 				exit(~0);
2296444Swnj 			}
2306444Swnj 			if (fk!=(-1)) {
2316444Swnj 				while (wait(&x)!=fk);
2326444Swnj 			}
2336444Swnj 			signal(SIGCHLD, done);
2346444Swnj 			mode(1);
2356444Swnj 			if (b[1] == '!') echo("!");
2366444Swnj 			break;
2376444Swnj 		case '<':
2386444Swnj 			if (b[2] == 0) break;
2396444Swnj 			if ((ds=open(b+2,0))<0) {
2406444Swnj 				prf("Can't divert %s",b+1);
2416444Swnj 				break;
2426444Swnj 			}
2436444Swnj 			intr=x=0;
2446444Swnj 			mode(2);
2456444Swnj 			if (!nhup) signal(SIGINT, sig2);
2466444Swnj 			while (!intr && rdc(ds) == 1) {
2476444Swnj 				if (wrc(rem) == 0) {
2486444Swnj 					x=1;
2496444Swnj 					break;
2506444Swnj 				}
2516444Swnj 			}
2526444Swnj 			signal(SIGINT, SIG_IGN);
2536444Swnj 			close(ds);
2546444Swnj 			mode(1);
2556444Swnj 			if (x) return;
2566444Swnj 			break;
2576444Swnj 		case '>':
2586444Swnj 		case ':':
2596444Swnj 			{
2606444Swnj 			register char *q;
2616444Swnj 
2626444Swnj 			q = b+1;
2636444Swnj 			if(*q=='>') q++;
2646444Swnj 			write(pipes[1],q,strlen(q)+1);
2656444Swnj 			if (efk != -1) kill(efk,SIGEMT);
2666444Swnj 			}
2676444Swnj 			break;
2686444Swnj #ifdef SIGTSTP
2696444Swnj #define CTRLZ	26
2706444Swnj 		case CTRLZ:
2716444Swnj 			mode(0);
2726444Swnj 			signal(SIGCHLD, SIG_IGN);
2736444Swnj 			kill(0, SIGTSTP);
2746444Swnj 			signal(SIGCHLD, done);
2756444Swnj 			mode(1);
2766444Swnj 			break;
2776444Swnj #endif
2786444Swnj 		case '%':
2796444Swnj 			dopercen(&b[2]);
2806444Swnj 			break;
2816444Swnj 		default:
2826444Swnj 			prf("Use `%c%c' to start line with `%c'", cmdchar, cmdchar, cmdchar);
2836444Swnj 		}
2846444Swnj 		continue;
2856444Swnj 	}
2866444Swnj }
2876444Swnj 
2886444Swnj dopercen(line)
2896444Swnj register char *line;
2906444Swnj {
2916444Swnj 	char *args[10];
2926444Swnj 	register narg, f;
2936444Swnj 	int rcount;
2946444Swnj 	for (narg = 0; narg < 10;) {
2956444Swnj 		while(*line == ' ' || *line == '\t')
2966444Swnj 			line++;
2976444Swnj 		if (*line == '\0')
2986444Swnj 			break;
2996444Swnj 		args[narg++] = line;
3006444Swnj 		while(*line != '\0' && *line != ' ' && *line != '\t')
3016444Swnj 			line++;
3026444Swnj 		if (*line == '\0')
3036444Swnj 			break;
3046444Swnj 		*line++ = '\0';
3056444Swnj 	}
3066444Swnj 	if (equal(args[0], "take")) {
3076444Swnj 		if (narg < 2) {
3086444Swnj 			prf("usage: %c%%take from [to]", cmdchar);
3096444Swnj 			return;
3106444Swnj 		}
3116444Swnj 		if (narg < 3)
3126444Swnj 			args[2] = args[1];
3136444Swnj 		write(pipes[1], ">/dev/null",sizeof(">/dev/null"));
3146444Swnj 		if (efk != -1) kill(efk,SIGEMT);
3156444Swnj 		sleep(5);
3166444Swnj 		wrln("echo '%c>:", cmdchar);
3176444Swnj 		wrln(args[2]);
3186444Swnj 		wrln("'; tee /dev/null <");
3196444Swnj 		wrln(args[1]);
3206444Swnj 		wrln(";echo '%c>'\n", cmdchar);
3216444Swnj 		return;
3226444Swnj 	} else if (equal(args[0], "put")) {
3236444Swnj 		prf("%c%%put doesn't work yet (use rsh)", cmdchar);
3246444Swnj 		return;
3256444Swnj /*
3266444Swnj 		if (narg < 2) {
3276444Swnj 			prf("usage: %c%%put from [to]", cmdchar);
3286444Swnj 			return;
3296444Swnj 		}
3306444Swnj 		if (narg < 3)
3316444Swnj 			args[2] = args[1];
3326444Swnj 		if ((f = open(args[1], 0)) < 0) {
3336444Swnj 			prf("cannot open: %s", args[1]);
3346444Swnj 			return;
3356444Swnj 		}
3366444Swnj 		wrln("stty -echo;cat >");
3376444Swnj 		wrln(args[2]);
3386444Swnj 		wrln(";stty echo\n");
3396444Swnj 		sleep(5);
3406444Swnj 		intr = 0;
3416444Swnj 		if (!nhup)
3426444Swnj 			signal(SIGINT, sig2);
3436444Swnj 		mode(2);
3446444Swnj 		rcount = 0;
3456444Swnj 		while(!intr && rdc(f) == 1) {
3466444Swnj 			rcount++;
3476444Swnj 			if (c == tkill || c == terase)
3486444Swnj 				wrln("\\");
3496444Swnj 			if (wrc(rem) != 1) {
3506444Swnj 				sleep(2);
3516444Swnj 				if (wrc(rem) != 1) {
3526444Swnj 					prf("character missed");
3536444Swnj 					intr = 1;
3546444Swnj 					break;
3556444Swnj 				}
3566444Swnj 			}
3576444Swnj 		}
3586444Swnj 		signal(SIGINT, SIG_IGN);
3596444Swnj 		close(f);
3606444Swnj 		if (intr) {
3616444Swnj 			wrln("\n");
3626444Swnj 			prf("stopped after %d bytes", rcount);
3636444Swnj 		}
3646444Swnj 		wrln("\004");
3656444Swnj 		sleep(5);
3666444Swnj 		mode(1);
3676444Swnj 		return;
3686444Swnj */
3696444Swnj 	}
3706444Swnj 	prf("%c%%%s unknown\n", cmdchar, args[0]);
3716444Swnj }
3726444Swnj 
3736444Swnj equal(s1, s2)
3746444Swnj register char *s1, *s2;
3756444Swnj {
3766444Swnj 	while (*s1++ == *s2)
3776444Swnj 		if (*s2++ == '\0')
3786444Swnj 			return(1);
3796444Swnj 	return(0);
3806444Swnj }
3816444Swnj 
3826444Swnj wrln(s, p1, p2, p3)
3836444Swnj register char *s;
3846444Swnj int p1, p2, p3;
3856444Swnj {
3866444Swnj 	char wbuf[256];
3876444Swnj 
3886444Swnj 	sprintf(wbuf, s, p1, p2, p3);
3896444Swnj 	s = wbuf;
3906444Swnj 	while (*s)
3916444Swnj 		write(rem, s++, 1);
3926444Swnj }
3936444Swnj int ds,slnt;
3946444Swnj int justrung;
3956444Swnj 
3966444Swnj /*
3976444Swnj  *	rd: read from remote: line -> 1
3986444Swnj  *	catch:
3996444Swnj  *	~>[>][:][file]
4006444Swnj  *	stuff from file...
4016444Swnj  *	~>	(ends diversion)
4026444Swnj  */
4036444Swnj 
4046444Swnj int ds,slnt,taking;
4056444Swnj int justrung;
4066444Swnj readmsg(){
4076444Swnj 	static char dobuff[128], morejunk[256];
4086444Swnj 	int n;
4096444Swnj 	justrung = 1;
4106444Swnj 	signal(SIGEMT,readmsg);
4116444Swnj 	n = read(pipes[0],morejunk,256);
4126444Swnj 	dodiver(morejunk);
4136444Swnj }
4146444Swnj 
4156444Swnj dodiver(msg)
4166444Swnj char *msg;
4176444Swnj {
4186444Swnj 	register char *cp = msg;
4196444Swnj 
4206444Swnj 	if (*cp=='>') cp++;
4216444Swnj 	if (*cp==':') {
4226444Swnj 		cp++;
4236444Swnj 		if(*cp==0) {
4246444Swnj 			slnt ^= 1;
4256444Swnj 			return;
4266444Swnj 		} else  {
4276444Swnj 			slnt = 1;
4286444Swnj 		}
4296444Swnj 	}
4306444Swnj 	if (ds >= 0) close(ds);
4316444Swnj 	if (*cp==0) {
4326444Swnj 		slnt = 0;
4336444Swnj 		ds = -1;
4346444Swnj 		return;
4356444Swnj 	}
4366444Swnj 	if (*msg!='>' || (ds=open(cp,1))<0) ds=creat(cp,0644);
4376444Swnj 	lseek(ds, (long)0, 2);
4386444Swnj 	if(ds < 0) prf("Creat failed:"), prf(cp);
4396444Swnj 	if (ds<0) prf("Can't divert %s",cp+1);
4406444Swnj }
4416444Swnj 
4426444Swnj 
4436444Swnj /*
4446444Swnj  *	rd: read from remote: line -> 1
4456444Swnj  *	catch: diversion caught by interrupt routine
4466444Swnj  */
4476444Swnj 
4486444Swnj #define ORDIN 0
4496444Swnj #define SAWCR 1
4506444Swnj #define EOL   2
4516444Swnj #define SAWTL 3
4526444Swnj #define DIVER 4
4536444Swnj 
4546444Swnj oob()
4556444Swnj {
4566444Swnj 	int mark, cc, out = 1+1;
4576444Swnj 	char waste[512];
4586444Swnj 
4596444Swnj 	signal(SIGURG, oob);
4606444Swnj 	ioctl(1, TIOCFLUSH, &out);
4616444Swnj 	for (;;) {
4626444Swnj 		if (ioctl(rem, SIOCATMARK, &mark) < 0) {
4636444Swnj 			perror("ioctl");
4646444Swnj 			break;
4656444Swnj 		}
4666444Swnj 		if (mark)
4676444Swnj 			break;
4686444Swnj 		cc = read(rem, waste, 512);
4696444Swnj 	}
470*9207Ssam 	recv(rem, &mark, 1, SOF_OOB);
4716444Swnj 	if (mark & TIOCPKT_NOSTOP) {
4726444Swnj 		notchars.t_stopc = 0377;
4736444Swnj 		notchars.t_startc = 0377;
4746444Swnj 		ioctl(0, TIOCSETC, &notchars);
4756444Swnj 	}
4766444Swnj 	if (mark & TIOCPKT_DOSTOP) {
4776444Swnj 		notchars.t_stopc = 's'&037;
4786444Swnj 		notchars.t_startc = 'q'&037;
4796444Swnj 		ioctl(0, TIOCSETC, &notchars);
4806444Swnj 	}
4816444Swnj }
4826444Swnj 
4836444Swnj rd()
4846444Swnj {
4856444Swnj 	extern int ds,slnt;
4866444Swnj 	char rb[600], lb[600], *rlim, *llim, c;
4876444Swnj 	register char *p,*q;
4886444Swnj 	int cnt, state = 0, mustecho, oldslnt, readmsg();
4896444Swnj 
4906444Swnj 	signal(SIGEMT,readmsg);  /* set up child for catching diversion msgs
4916444Swnj 				    from parent */
4926444Swnj 	signal(SIGURG,oob);
4936444Swnj 	{ int pid = -getpid();
4946444Swnj 	  ioctl(rem, SIOCSPGRP, &pid); }
4956444Swnj 	ds=(-1);
4966444Swnj 	p = lb; llim = lb+600;
4976444Swnj agin:
4986444Swnj 	for (;;) {
4996444Swnj 		extern errno;
5006444Swnj 		errno = 0;
5016444Swnj 		cnt = read(rem,rb,600);
5026444Swnj 		if (cnt <= 0) {
5036444Swnj 			if (errno == EINTR) {
5046444Swnj 				errno = 0;
5056444Swnj 				continue;
5066444Swnj 			}
5076444Swnj 			break;
5086444Swnj 		}
5096444Swnj 		if(!slnt) write(1,rb,cnt);
5106444Swnj 		if(ds < 0) continue;
5116444Swnj 		oldslnt = slnt;
5126444Swnj 		for( q=rb, rlim = rb + cnt - 1; q <= rlim; ) {
5136444Swnj 			if (eight == 0)
5146444Swnj 			c &= 0177;
5156444Swnj 			if(p < llim) *p++ = c;
5166444Swnj 			switch(state) {
5176444Swnj 			case ORDIN:
5186444Swnj 				if(c=='\r') state = SAWCR;
5196444Swnj 				break;
5206444Swnj 			case SAWCR:
5216444Swnj 				if(c=='\n') {
5226444Swnj 					state = EOL;
5236444Swnj 					p--;
5246444Swnj 					p[-1] = '\n';
5256444Swnj 				} else state = ORDIN;
5266444Swnj 				break;
5276444Swnj 			case EOL:
5286444Swnj 				state = (c==cmdchar ? SAWTL :
5296444Swnj 					 (c=='\r' ? SAWCR : ORDIN));
5306444Swnj 				break;
5316444Swnj 			case SAWTL:
5326444Swnj 				state = (c=='>' ? DIVER :
5336444Swnj 					 (c=='\r' ? SAWCR : ORDIN));
5346444Swnj 				break;
5356444Swnj 			case DIVER:
5366444Swnj 				if(c=='\r') {
5376444Swnj 					p--;
5386444Swnj 				} else if (c=='\n') {
5396444Swnj 					state = ORDIN;
5406444Swnj 					p[-1] = 0;
5416444Swnj 					dodiver(lb+2);
5426444Swnj 					c = 0; p = lb;
5436444Swnj 				}
5446444Swnj 			}
5456444Swnj 			if(slnt==0 && oldslnt) {
5466444Swnj 				if(c=='\n') {
5476444Swnj 					write(rem,lb,p-lb-1);
5486444Swnj 					write(rem,CRLF,sizeof(CRLF));
5496444Swnj 				} else if(q==rlim) {
5506444Swnj 					write(rem,lb,p-lb);
5516444Swnj 					c = '\n';  /*force flush to file*/
5526444Swnj 				}
5536444Swnj 			}
5546444Swnj 			if(c=='\n') {
5556444Swnj 				if(ds >= 0)
5566444Swnj 					write(ds,lb,p-lb);
5576444Swnj 				p = lb;
5586444Swnj 			}
5596444Swnj 		}
5606444Swnj 	}
5616444Swnj 	if(justrung) {
5626444Swnj 		justrung = 0;
5636444Swnj 		goto agin;
5646444Swnj 	}
5656444Swnj }
5666444Swnj 
5676444Swnj struct {char lobyte; char hibyte;};
5686444Swnj mode(f)
5696444Swnj {
5706444Swnj 	struct sgttyb stbuf;
5716444Swnj 	ioctl(0, TIOCGETP, &stbuf);
5726444Swnj 	if (f == 0) {
5736444Swnj 		stbuf.sg_flags &= ~CBREAK;
5746481Sjkf 		stbuf.sg_flags |= defflags;
5756444Swnj 		ioctl(0, TIOCSETC, &deftchars);
5766444Swnj 		ioctl(0, TIOCSLTC, &defltchars);
5776444Swnj 		stbuf.sg_kill = defkill;
5786444Swnj 		stbuf.sg_erase = deferase;
5796444Swnj 	}
5806444Swnj 	if (f == 1) {
5816444Swnj 		stbuf.sg_flags |= CBREAK;
5826444Swnj 		stbuf.sg_flags &= ~(ECHO|CRMOD);
5836444Swnj 		ioctl(0, TIOCSETC, &notchars);
5846444Swnj 		ioctl(0, TIOCSLTC, &noltchars);
5856444Swnj 		stbuf.sg_kill = 0377;
5866444Swnj 		stbuf.sg_erase = 0377;
5876444Swnj 	}
5886444Swnj 	if (f == 2) {
5896444Swnj 		stbuf.sg_flags &= ~CBREAK;
5906444Swnj 		stbuf.sg_flags &= ~(ECHO|CRMOD);
5916444Swnj 		ioctl(0, TIOCSETC, &deftchars);
5926444Swnj 		ioctl(0, TIOCSLTC, &defltchars);
5936444Swnj 		stbuf.sg_kill = 0377;
5946444Swnj 		stbuf.sg_erase = 0377;
5956444Swnj 	}
5966444Swnj 	ioctl(0, TIOCSETN, &stbuf);
5976444Swnj }
5986444Swnj 
5996444Swnj echo(s)
6006444Swnj char *s;
6016444Swnj {
6026444Swnj 	char *p;
6036444Swnj 	for (p=s;*p;p++);
6046444Swnj 	if (p>s) write(0,s,p-s);
6056444Swnj 	write(0,CRLF, sizeof(CRLF));
6066444Swnj }
6076444Swnj 
6086444Swnj prf(f, a1, a2, a3)
6096444Swnj char *f;
6106444Swnj {
6116444Swnj 	fprintf(stderr, f, a1, a2, a3);
6126444Swnj 	fprintf(stderr, CRLF);
6136444Swnj }
6146444Swnj 
6156444Swnj exists(devname)
6166444Swnj char *devname;
6176444Swnj {
6186444Swnj 	if (access(devname, 0)==0)
6196444Swnj 		return(1);
6206444Swnj 	prf("%s does not exist", devname);
6216444Swnj 	return(0);
6226444Swnj }
6236444Swnj 
6246444Swnj rdc(ds)
6256444Swnj {
6266444Swnj 
6276444Swnj 	ds=read(ds,&c,1);
6286444Swnj 	oc = c;
6296444Swnj 	if (eight == 0)
6306444Swnj 		c &= 0177;
6316444Swnj 	return (ds);
6326444Swnj }
6336444Swnj 
6346444Swnj sig2()
6356444Swnj {
6366444Swnj 	signal(SIGINT, SIG_IGN);
6376444Swnj 	intr = 1;
6386444Swnj }
639