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