Ultrix-3.1/src/cmd/stty.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

 char *Sccsid ="@(#)stty.c	3.1	1/13/88";
/* Based on:    stty.c	4.7  (2.9BSD)   7/18/81  */
/*
 * set teletype modes
 *
 * Changes for min and time (VMIN and VTIME: SYSTEM V)
 * George Mathew: 7/18/85
 */

#include <whoami.h>
#include <stdio.h>
#include <sgtty.h>

#ifndef HUPCLS
#define HUPCLS	01000
#endif

#ifndef	CMIN
#define	CMIN	6
#define	CTIME	1
#endif

struct
{
	char	*string;
	int	speed;
} speeds[] = {
	"0",	B0,
	"50",	B50,
	"75",	B75,
	"110",	B110,
	"134",	B134,
	"134.5",B134,
	"150",	B150,
	"200",	B200,
	"300",	B300,
	"600",	B600,
	"1200",	B1200,
	"1800",	B1800,
	"2400",	B2400,
	"4800",	B4800,
	"9600",	B9600,
	"exta",	EXTA,
	"extb",	EXTB,
	0,
};
struct
{
	char	*string;
	int	set;
	int	reset;
	int	lset;
	int	lreset;
} modes[] = {
	"even",		EVENP, 0, 0, 0,
	"-even",	0, EVENP, 0, 0,
	"odd",		ODDP, 0, 0, 0,
	"-odd",		0, ODDP, 0, 0,
	"raw",		RAW, 0, 0, 0,
	"-raw",		0, RAW, 0, 0,
	"cooked",	0, RAW, 0, 0,
	"-nl",		CRMOD, 0, 0, 0,
	"nl",		0, CRMOD, 0, 0,
	"echo",		ECHO, 0, 0, 0,
	"-echo",	0, ECHO, 0, 0,
	"LCASE",	LCASE, 0, 0, 0,
	"lcase",	LCASE, 0, 0, 0,
	"-LCASE",	0, LCASE, 0, 0,
	"-lcase",	0, LCASE, 0, 0,
	"-tabs",	XTABS, 0, 0, 0,
	"tabs",		0, XTABS, 0, 0,
	"tandem",	TANDEM, 0, 0, 0,
	"-tandem",	0, TANDEM, 0, 0,
	"cbreak",	CBREAK, 0, 0, 0,
	"-cbreak",	0, CBREAK, 0, 0,
	"cr0",		CR0, CR3, 0, 0,
	"cr1",		CR1, CR3, 0, 0,
	"cr2",		CR2, CR3, 0, 0,
	"cr3",		CR3, CR3, 0, 0,
	"tab0",		TAB0, XTABS, 0, 0,
	"tab1",		TAB1, XTABS, 0, 0,
	"tab2",		TAB2, XTABS, 0, 0,
	"nl0",		NL0, NL3, 0, 0,
	"nl1",		NL1, NL3, 0, 0,
	"nl2",		NL2, NL3, 0, 0,
	"nl3",		NL3, NL3, 0, 0,
	"ff0",		FF0, FF1, 0, 0,
	"ff1",		FF1, FF1, 0, 0,
	"bs0",		BS0, BS1, 0, 0,
	"bs1",		BS1, BS1, 0, 0,
	"33",		CR1, ALLDELAY, 0, 0,
	"tty33",	CR1, ALLDELAY, 0, 0,
	"37",		FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0,
	"tty37",	FF1+CR2+TAB1+NL1, ALLDELAY, 0, 0,
	"05",		NL2, ALLDELAY, 0, 0,
	"vt05",		NL2, ALLDELAY, 0, 0,
	"tn",		CR1, ALLDELAY, 0, 0,
	"tn300",	CR1, ALLDELAY, 0, 0,
	"ti",		CR2, ALLDELAY, 0, 0,
	"ti700",	CR2, ALLDELAY, 0, 0,
	"tek",		FF1, ALLDELAY, 0, 0,
	"crtbs",	0, 0, LCRTBS, LPRTERA,
	"-crtbs",	0, 0, 0, LCRTBS,
	"prterase",	0, 0, LPRTERA, LCRTBS+LCRTKIL+LCRTERA,
	"-prterase",	0, 0, 0, LPRTERA,
	"crterase",	0, 0, LCRTERA, LPRTERA,
	"-crterase",	0, 0, 0, LCRTERA,
	"crtkill",	0, 0, LCRTKIL, LPRTERA,
	"-crtkill",	0, 0, 0, LCRTKIL,
	"tilde",	0, 0, LTILDE, 0,
	"-tilde",	0, 0, 0, LTILDE,
	"mdmbuf",	0, 0, LMDMBUF, 0,
	"-mdmbuf",	0, 0, 0, LMDMBUF,
	"litout",	0, 0, LLITOUT, 0,
	"-litout",	0, 0, 0, LLITOUT,
	"tostop",	0, 0, LTOSTOP, 0,
	"-tostop",	0, 0, 0, LTOSTOP,
	"flusho",	0, 0, LFLUSHO, 0,
	"-flusho",	0, 0, 0, LFLUSHO,
	"etxack",	0, 0, LETXACK, 0,
	"-etxack",	0, 0, 0, LETXACK,
	"intrup",	0, 0, LINTRUP, 0,
	"-intrup",	0, 0, 0, LINTRUP,
	"ctlecho",	0, 0, LCTLECH, 0,
	"-ctlecho",	0, 0, 0, LCTLECH,
	"pendin",	0, 0, LPENDIN, 0,
	"-pendin",	0, 0, 0, LPENDIN,
	"decctlq",	0, 0, LDECCTQ, 0,
	"-decctlq",	0, 0, 0, LDECCTQ,
	"noflsh",	0, 0, LNOFLSH, 0,
	"-noflsh",	0, 0, 0, LNOFLSH,
	0,
};

struct tchars tc;
struct ltchars ltc;
struct sgttyb mode;
int	lmode;
int	oldisc, ldisc;

#ifndef CTRL(c)
#define	CTRL(c)		('c'&037)
#endif

struct	special {
	char	*name;
	char	*cp;
	char	def;
} special[] = {
	"erase",	&mode.sg_erase,		CTRL(h),
	"kill",		&mode.sg_kill,		'@',
	"intr",		&tc.t_intrc,		0177,
	"quit",		&tc.t_quitc,		CTRL(\\\\),
	"start",	&tc.t_startc,		CTRL(q),
	"stop",		&tc.t_stopc,		CTRL(s),
	"eof",		&tc.t_eofc,		CTRL(d),
	"brk",		&tc.t_brkc,		0377,
	"min",		&tc.t_vmin,		CMIN,
	"time",		&tc.t_vtime,		CTIME,
	"susp",		&ltc.t_suspc,		CTRL(z),
	"dsusp",	&ltc.t_dsuspc,		CTRL(y),
	"rprnt",	&ltc.t_rprntc,		CTRL(r),
	"flush",	&ltc.t_flushc,		CTRL(o),
	"werase",	&ltc.t_werasc,		CTRL(w),
	"lnext",	&ltc.t_lnextc,		CTRL(v),
	0
};
char	*arg;

int	argc;
char	**argv;
main(iargc, iargv)
char	**iargv;
{
	int i, uid, gid;
	char	*termname;		/* hopefully, the user's tty */
	register struct special *sp;
	char obuf[BUFSIZ];
	int tmpmin;

	setbuf(stderr, obuf);
	argc = iargc;
	argv = iargv;
	gtty(1, &mode);
	ioctl(1, TIOCGETD, (struct sgttyb *) &ldisc);
	oldisc = ldisc;
	ioctl(1, TIOCGETC, (struct sgttyb *) &tc);
	ioctl(1, TIOCGETV, &tc);	/* get t_vmin & t_vtime */
	ioctl(1, TIOCLGET, (struct sgttyb *) &lmode);
	ioctl(1, TIOCGLTC, (struct sgttyb *) &ltc);
	if(argc == 1) {
		prmodes(0);
		exit(0);
	}
	if (argc == 2 && !strcmp(argv[1], "all")) {
		prmodes(1);
		exit(0);
	}
	if (argc == 2 && !strcmp(argv[1], "a")) {	/* ULTRIX-11 */
		prmodes(1);
		exit(0);
	}
	if (argc == 2 && !strcmp(argv[1], "everything")) {
		prmodes(2);
		exit(0);
	}
	if (argc == 2 && !strcmp(argv[1], "e")) {	/* ULTRIX-11 */
		prmodes(2);
		exit(0);
	}
/*
	if (argc == 2 && !strcmp(argv[1], "all")) {
		prmodes(2);
		exit(0);
	}
*/
	if ((uid=getuid(1)) == 0)
		;	/* super-user OK */
	else {
		gid=getgid();
		if (isatty(1) < 0) {
			fprintf(stderr, "Not a tty.\n");
			exit(1);
		}
		if ((termname=ttyname(1)) == NULL) {
			fprintf(stderr,"Cannot get ttyname\n");
			exit(1);
		}
		if (access(termname, 4) < 0) {
			fprintf(stderr,"%s: Permission denied\n",termname);
			exit(1);
		}
	}

	while(--argc > 0) {
		arg = *++argv;
		if (eq("ek")){
			mode.sg_erase = '#';
			mode.sg_kill = '@';
			continue;
		}
		if (eq("new")){
			ldisc = NTTYDISC;
			if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0)
				perror("ioctl");
			continue;
		}
		if (eq("newcrt")){
			ldisc = NTTYDISC;
			lmode &= ~LPRTERA;
			lmode |= LCRTBS|LCTLECH;
			if (mode.sg_ospeed >= B1200)
				lmode |= LCRTERA|LCRTKIL;
			if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0)
				perror("ioctl");
			continue;
		}
		if (eq("crt")){
			lmode &= ~LPRTERA;
			lmode |= LCRTBS|LCTLECH;
			if (mode.sg_ospeed >= B1200)
				lmode |= LCRTERA|LCRTKIL;
			continue;
		}
		if (eq("old")){
			ldisc = OTTYDISC;
			if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0)
				perror("ioctl");
			continue;
		}
		if (eq("dec")){
			mode.sg_erase = 0177;
			mode.sg_kill = CTRL(u);
			tc.t_intrc = CTRL(c);
			ldisc = NTTYDISC;
			lmode &= ~LPRTERA;
			lmode |= LCRTBS|LCTLECH|LDECCTQ;
			if (mode.sg_ospeed >= B1200)
				lmode |= LCRTERA|LCRTKIL;
			if (ioctl(1, TIOCSETD, (struct sgttyb *) &ldisc)<0)
				perror("ioctl");
			continue;
		}
		for (sp = special; sp->name; sp++)
			if (eq(sp->name)) {
				if (--argc == 0)
					goto done;
				if( !(strcmp(sp->name,"min")) || !(strcmp(sp->name,"time")) ) {
					tmpmin = atoi(*++argv);
					if ((tmpmin < 0) || (tmpmin >255))
						fprintf(stderr,"min and time should be between 0 and 255\n");
					else
						*sp->cp = 0377 & tmpmin;
				}
				else if (**++argv == 'u')
					*sp->cp = 0377;
				else if (**argv == '^')
					*sp->cp = ((*argv)[1] == '?') ?
					    0177 : (*argv)[1] & 037;
				else
					*sp->cp = **argv;
				goto cont;
			}
		if (eq("gspeed")) {
			mode.sg_ispeed = B300;
			mode.sg_ospeed = B9600;
			continue;
		}
		if (eq("hup")) {
			ioctl(1, TIOCHPCL, (struct sgttyb *) NULL);
			continue;
		}
		if (eq("-hup")) {
			ioctl(1, TIOCCHPCL, (struct sgttyb *) NULL);
			continue;
		}
		if (eq("excl")) {
			ioctl(1, TIOCEXCL, (struct sgttyb *) NULL);
		}
		if (eq("-excl")) {
			ioctl(1, TIOCNXCL, (struct sgttyb *) NULL);
		}

		for(i=0; speeds[i].string; i++)
			if(eq(speeds[i].string)) {
				mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed;
				goto cont;
			}
		if (eq("speed")) {
			gtty(open("/dev/tty", 0), &mode);
			for(i=0; speeds[i].string; i++)
				if (mode.sg_ospeed == speeds[i].speed) {
					printf("%s\n", speeds[i].string);
					exit(0);
				}
			printf("unknown\n");
			exit(1);
		}
		for(i=0; modes[i].string; i++)
			if(eq(modes[i].string)) {
				mode.sg_flags &= ~modes[i].reset;
				mode.sg_flags |= modes[i].set;
				lmode &= ~modes[i].lreset;
				lmode |= modes[i].lset;
			}
		if(arg)
			fprintf(stderr,"unknown mode: %s\n", arg);
cont:
		;
	}
done:
	ioctl(1, TIOCSETN, (struct sgttyb *) &mode);
	ioctl(1, TIOCSETC, (struct sgttyb *) &tc);
	ioctl(1, TIOCSETV, &tc);
	ioctl(1, TIOCSLTC, (struct sgttyb *) &ltc);
	ioctl(1, TIOCLSET, (struct sgttyb *) &lmode);
}

eq(string)
char *string;
{
	int i;

	if(!arg)
		return(0);
	i = 0;
loop:
	if(arg[i] != string[i])
		return(0);
	if(arg[i++] != '\0')
		goto loop;
	arg = 0;
	return(1);
}

prmodes(all)
{
	unsigned tstate;
	register m;
	int any;

	ioctl(1, TIOCGETS, &tstate);

	if(ldisc==NETLDISC)
		fprintf(stderr, "net discipline, ");
	else if(ldisc==NTTYDISC)
		fprintf(stderr, "new tty, ");
	else if(all==2)
		fprintf(stderr, "old tty, ");
	if(mode.sg_ispeed != mode.sg_ospeed) {
		prspeed("input speed ", mode.sg_ispeed);
		prspeed("output speed ", mode.sg_ospeed);
	} else
		prspeed("speed ", mode.sg_ispeed);
	fprintf(stderr, all==2 ? "\n" : "; ");
	m = mode.sg_flags;
	if(all==2 || (m&(EVENP|ODDP))!=(EVENP|ODDP)) {
		if(m & EVENP)	fprintf(stderr,"even ");
		if(m & ODDP)	fprintf(stderr,"odd ");
	}
	if(all==2 || m&RAW)
		fprintf(stderr,"-raw "+((m&RAW)!=0));
	if(all==2 || (m&CRMOD)==0)
		fprintf(stderr,"-nl "+((m&CRMOD)==0));
	if(all==2 || (m&ECHO)==0)
		fprintf(stderr,"-echo "+((m&ECHO)!=0));
	if(all==2 || (m&LCASE))
		fprintf(stderr,"-lcase "+((m&LCASE)!=0));
	if(all==2 || (m&TANDEM))
		fprintf(stderr,"-tandem "+((m&TANDEM)!=0));
	fprintf(stderr,"-tabs "+((m&XTABS)!=XTABS));
	if(all==2 || (m&CBREAK))
		fprintf(stderr,"-cbreak "+((m&CBREAK)!=0));
	if(all==2 || (m&NLDELAY))
		delay((m&NLDELAY)/NL1,	"nl");
	if ((m&TBDELAY)!=XTABS)
		delay((m&TBDELAY)/TAB1,	"tab");
	if(all==2 || (m&CRDELAY))
		delay((m&CRDELAY)/CR1,	"cr");
	if(all==2 || (m&VTDELAY))
		delay((m&VTDELAY)/FF1,	"ff");
	if(all==2 || (m&BSDELAY))
		delay((m&BSDELAY)/BS1,	"bs");
	if (all)
		fprintf(stderr,"\n");
#define	lpit(what,str) \
	if (all==2||(lmode&what)) { \
		fprintf(stderr,str+((lmode&what)!=0)); any++; \
	}
	if (ldisc == NTTYDISC) {
		int newcrt = (lmode&(LCTLECH|LCRTBS)) == (LCTLECH|LCRTBS) &&
		    (lmode&(LCRTERA|LCRTKIL)) ==
		      ((mode.sg_ospeed > B300) ? LCRTERA|LCRTKIL : 0);
		if (newcrt) {
			if (all==2)
				fprintf(stderr, "crt: (crtbs crterase crtkill ctlecho) ");
			else
				fprintf(stderr, "crt ");
			any++;
		} else {
			lpit(LCRTBS, "-crtbs ");
			lpit(LCRTERA, "-crterase ");
			lpit(LCRTKIL, "-crtkill ");
			lpit(LCTLECH, "-ctlecho ");
			lpit(LPRTERA, "-prterase ");
		}
		lpit(LTOSTOP, "-tostop ");
		lpit(LINTRUP, "-intrup ");
		if (all==2) {
			fprintf(stderr, "\n");
			any = 0;
		}
		lpit(LTILDE, "-tilde ");
		lpit(LFLUSHO, "-flusho ");
		lpit(LMDMBUF, "-mdmbuf ");
		lpit(LLITOUT, "-litout ");
		if (all==2||(tstate&XCLUDE)) {		/* exclusive use */
			fprintf(stderr,"-excl "+((tstate&XCLUDE)!=0));
			any++;
		}
		if (all==2||(tstate&HUPCLS)) {		/* hangup last close */
			fprintf(stderr,"-hup "+((tstate&HUPCLS)!=0));
			any++;
		}
		if (any) {
			fprintf(stderr,"\n");
			any = 0;
		}
		lpit(LETXACK, "-etxack ");
		lpit(LPENDIN, "-pendin ");
		lpit(LDECCTQ, "-decctlq ");
		lpit(LNOFLSH, "-noflsh ");
		if (any)
			fprintf(stderr,"\n");
	} else if (!all)
		fprintf(stderr,"\n");
	if (all) {
		switch (ldisc) {

		case OTTYDISC:
			fprintf(stderr,"\
erase  kill   intr   quit   stop   eof\
\n");
			pcol(mode.sg_erase, -1);
			pcol(mode.sg_kill, -1);
			pcol(tc.t_intrc, -1);
			pcol(tc.t_quitc, -1);
			pcol(tc.t_stopc, tc.t_startc);
			pcol(tc.t_eofc, tc.t_brkc);
			fprintf(stderr,"\n");
			fprintf(stderr,"min = %d  time = %d\n",tc.t_vmin,tc.t_vtime);
			break;

		case NTTYDISC:
			fprintf(stderr,"\
erase  kill   werase rprnt  flush  lnext  susp   intr   quit   stop   eof\
\n"); 
			pcol(mode.sg_erase, -1);
			pcol(mode.sg_kill, -1);
			pcol(ltc.t_werasc, -1);
			pcol(ltc.t_rprntc, -1);
			pcol(ltc.t_flushc, -1);
			pcol(ltc.t_lnextc, -1);
			pcol(ltc.t_suspc, ltc.t_dsuspc);
			pcol(tc.t_intrc, -1);
			pcol(tc.t_quitc, -1);
			pcol(tc.t_stopc, tc.t_startc);
			pcol(tc.t_eofc, tc.t_brkc);
			fprintf(stderr,"\n");
			fprintf(stderr,"min = %d  time = %d\n",tc.t_vmin,tc.t_vtime);
			break;
		}
	} else if (ldisc != NETLDISC) {
		register struct special *sp;
		int first = 1;
		for (sp = special; sp->name; sp++) {
			if ((*sp->cp&0377) != (sp->def&0377)) {
				if (!(strcmp(sp->name,"min")) || !(strcmp(sp->name,"time")) )
					fprintf(stderr,"%s%s = %d",first ? "" : ", ",sp->name,(unsigned) (*sp->cp));
				else
					pit((unsigned) (*sp->cp), sp->name, first ? "" : ", ");
				first = 0;
			};
			if (sp->cp == &tc.t_brkc && ldisc == OTTYDISC)
				break;
		}
		if (first == 0)
			fprintf(stderr, "\n");
	}
}

pcol(ch1, ch2)
	int ch1, ch2;
{
	int nout = 0;

	ch1 &= 0377;
	ch2 &= 0377;
	if (ch1 == ch2)
		ch2 = 0377;
	for (; ch1 != 0377 || ch2 != 0377; ch1 = ch2, ch2 = 0377) {
		if (ch1 == 0377)
			continue;
		if (ch1 & 0200) {
			fprintf(stderr, "M-");
			nout += 2;
			ch1 &= ~ 0200;
		}
		if (ch1 == 0177) {
			fprintf(stderr, "^");
			nout++;
			ch1 = '?';
		} else if (ch1 < ' ') {
			fprintf(stderr, "^");
			nout++;
			ch1 += '@';
		}
		fprintf(stderr, "%c", ch1);
		nout++;
		if (ch2 != 0377) {
			fprintf(stderr, "/");
			nout++;
		}
	}
	while (nout < 7) {
		fprintf(stderr, " ");
		nout++;
	}
}

pit(what, itsname, sep)
	unsigned what;
	char *itsname, *sep;
{

	what &= 0377;
	fprintf(stderr, "%s%s", sep, itsname);
	if (what == 0377) {
		fprintf(stderr, " <undef>");
		return;
	}
	fprintf(stderr, " = ");
	if (what & 0200) {
		fprintf(stderr, "M-");
		what &= ~ 0200;
	}
	if (what == 0177) {
		fprintf(stderr, "^");
		what = '?';
	} else if (what < ' ') {
		fprintf(stderr, "^");
		what += '@';
	}
	fprintf(stderr, "%c", what);
}

delay(m, s)
char *s;
{

	if(m)
		fprintf(stderr,"%s%d ", s, m);
}

int	speed[] = {
	0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,0,0
};

prspeed(c, s)
char *c;
{

	fprintf(stderr,"%s%d baud",  c, speed[s]);
}