|
|
1.1 root 1: /*
2: * Set options for the current output terminal.
3: */
4:
5: #include <stdio.h>
6: #include <sgtty.h>
7:
8: #define ON 1
9: #define OFF 2
10: #define NONE (-1) /* Disabled character */
11: #define NEXT (-2) /* Get next arg */
12: #define DEL 0177 /* Del/rubout in ASCII */
13:
14: /* Functions to set and reset parameters */
15: int smode();
16: int sspeed();
17: int sedit();
18: int stchars();
19: int sflag();
20: int sane();
21:
22: struct sgttyb sgttyb;
23: struct tchars tchars;
24:
25: int hupflag; /* Set hangup on close mode */
26: int exclflag; /* Set exclusive mode */
27: int allflag; /* Display all modes */
28: int scmd = TIOCSETP; /* Ordinary stty command */
29: int printflag; /* On for printing modes */
30:
31: #define NOPTS (sizeof(sopts)/sizeof(struct sopts))
32:
33: struct sopts {
34: char *s_opt;
35: int (*s_func)(); /* Function takes arg1 & arg2 */
36: char *s_arg1;
37: int s_arg2;
38: int s_arg3;
39: } sopts[] = {
40: "flush", sflag, &scmd, TIOCSETP, 0,
41: "-flush", sflag, &scmd, TIOCSETN, 0,
42: "even", smode, NULL, EVENP, 0,
43: "-even", smode, NULL, 0, EVENP,
44: "odd", smode, NULL, ODDP, 0,
45: "-odd", smode, NULL, 0, ODDP,
46: "raw", smode, NULL, RAW, 0,
47: "-raw", smode, NULL, 0, RAW,
48: "cooked", smode, NULL, 0, RAW,
49: "rawin", smode, NULL, RAWIN, 0,
50: "-rawin", smode, NULL, 0, RAWIN,
51: "rawout", smode, NULL, RAWOUT, 0,
52: "-rawout", smode, NULL, 0, RAWOUT,
53: "cbreak", smode, NULL, CBREAK, 0,
54: "-cbreak", smode, NULL, 0, CBREAK,
55: "-nl", smode, NULL, CRMOD, 0,
56: "nl", smode, NULL, 0, CRMOD,
57: "echo", smode, NULL, ECHO, 0,
58: "-echo", smode, NULL, 0, ECHO,
59: "lcase", smode, NULL, LCASE, 0,
60: "-lcase", smode, NULL, 0, LCASE,
61: "-tabs", smode, NULL, XTABS, 0,
62: "tabs", smode, NULL, 0, XTABS,
63: "tandem", smode, NULL, TANDEM, 0,
64: "-tandem", smode, NULL, 0, TANDEM,
65: "crt", smode, NULL, CRT, 0,
66: "-crt", smode, NULL, 0, CRT,
67: "ek", sedit, NULL, '#', '@',
68: #if DELAY
69: "cr0", smode, NULL, CR0, CRDELAY,
70: "cr1", smode, NULL, CR1, CRDELAY,
71: "cr2", smode, NULL, CR2, CRDELAY,
72: "cr3", smode, NULL, CR3, CRDELAY,
73: "nl0", smode, NULL, NL0, NLDELAY,
74: "nl1", smode, NULL, NL1, NLDELAY,
75: "nl2", smode, NULL, NL2, NLDELAY,
76: "nl3", smode, NULL, NL3, NLDELAY,
77: "ff0", smode, NULL, FF0, VTDELAY,
78: "ff1", smode, NULL, FF1, VTDELAY,
79: "bs0", smode, NULL, BS0, BSDELAY,
80: "bs1", smode, NULL, BS1, BSDELAY,
81: "tab0", smode, NULL, TAB0, TBDELAY,
82: "tab1", smode, NULL, TAB1, TBDELAY,
83: "tab2", smode, NULL, TAB2, TBDELAY,
84: "tab3", smode, NULL, TAB3, TBDELAY,
85: #endif
86: "0", sspeed, NULL, B0, B0,
87: "50", sspeed, NULL, B50, B50,
88: "75", sspeed, NULL, B75, B75,
89: "110", sspeed, NULL, B110, B110,
90: "134", sspeed, NULL, B134, B134,
91: "134.5", sspeed, NULL, B134, B134,
92: "150", sspeed, NULL, B150, B150,
93: "200", sspeed, NULL, B200, B200,
94: "300", sspeed, NULL, B300, B300,
95: "600", sspeed, NULL, B600, B600,
96: "1200", sspeed, NULL, B1200, B1200,
97: "1800", sspeed, NULL, B1800, B1800,
98: "2000", sspeed, NULL, B2000, B2000,
99: "2400", sspeed, NULL, B2400, B2400,
100: "3600", sspeed, NULL, B3600, B3600,
101: "4800", sspeed, NULL, B4800, B4800,
102: "7200", sspeed, NULL, B7200, B7200,
103: "9600", sspeed, NULL, B9600, B9600,
104: "19200", sspeed, NULL, B19200, B19200,
105: "exta", sspeed, NULL, EXTA, EXTA,
106: "extb", sspeed, NULL, EXTB, EXTB,
107: "hup", sflag, &hupflag, TIOCHPCL, 0,
108: "-hup", sflag, &hupflag, TIOCCHPCL, 0,
109: "excl", sflag, &exclflag, TIOCEXCL, 0,
110: "-excl", sflag, &exclflag, TIOCNXCL, 0,
111: "print", sflag, &printflag, 1, 0,
112: "erase", sedit, NULL, NEXT, 0,
113: "kill", sedit, NULL, 0, NEXT,
114: "start", stchars, &tchars.t_startc, 0, 0,
115: "stop", stchars, &tchars.t_stopc, 0, 0,
116: "eof", stchars, &tchars.t_eofc, 0, 0,
117: "break", stchars, &tchars.t_brkc, 0, 0,
118: "quit", stchars, &tchars.t_quitc, 0, 0,
119: "intr", stchars, &tchars.t_intrc, 0, 0, /* compatibility */
120: "int", stchars, &tchars.t_intrc, 0, 0,
121: "sane", sane, NULL, 0, 0
122: };
123:
124: /*
125: * Names of the speeds
126: */
127: char *speeds[] = {
128: "(hang up line)",
129: "50 baud",
130: "75 baud",
131: "110 baud",
132: "134.5 baud",
133: "150 baud",
134: "200 baud",
135: "300 baud",
136: "600 baud",
137: "1200 baud",
138: "1800 baud",
139: "2000 baud",
140: "2400 baud",
141: "3600 baud",
142: "4800 baud",
143: "7200 baud",
144: "9600 baud",
145: "19.2 Kbaud",
146: "exta",
147: "extb",
148: };
149:
150: int sgtflag; /* Says need sgtty */
151: int tcflag; /* Set terminal characters */
152: int ttyfd; /* Fd for setting attributes */
153:
154: int gargc;
155: char **gargv;
156: char *argv0; /* For usage() */
157:
158: /*
159: * Main routine reads options and
160: * calls appropriate mode setting routines.
161: */
162: main(argc, argv)
163: char *argv[];
164: {
165: char ttyname[40];
166: register struct sopts *sp;
167: register char *ap;
168:
169: ttyfd = fileno(stdout);
170: gargc = argc;
171: gargv = argv;
172: argv0 = argv[0];
173: while (argc > 1) {
174: if (argv[1][0] == '-') {
175: if (argv[1][1] == 't') {
176: sprintf(ttyname, "/dev/%s", &argv[1][2]);
177: if ((ttyfd = open(ttyname, 1)) >= 0) {
178: argv++;
179: gargv++;
180: argc--;
181: gargc--;
182: } else {
183: ttyfd = fileno(stdout);
184: argv++;
185: argc--;
186: }
187: } else if (argv[1][1] == 'a') {
188: allflag = 1;
189: argv++;
190: gargv++;
191: argc--;
192: gargc--;
193: } else {
194: argv++;
195: argc--;
196: }
197: } else {
198: argv++;
199: argc--;
200: }
201: }
202: getmodes();
203: if (gargc <= 1)
204: prmodes();
205: else
206: while (gargc-- > 1) {
207: ap = *++gargv;
208: for (sp = sopts; sp < &sopts[NOPTS]; sp++)
209: if (strcmp(sp->s_opt, ap) == 0) {
210: (*sp->s_func)(sp->s_arg1, sp->s_arg2,
211: sp->s_arg3);
212: break;
213: }
214: if (sp == &sopts[NOPTS])
215: sterr("bad mode `%s'", ap);
216: }
217: setmodes();
218: if (printflag)
219: prmodes();
220: exit(0);
221: }
222:
223: /*
224: * smode - sets mode part of TIOCSETP structure.
225: * First clears out bits in `reset' and then
226: * sets bits in `set'.
227: */
228: smode(junkp, set, reset)
229: char *junkp;
230: int set, reset;
231: {
232: sgtflag = 1;
233: sgttyb.sg_flags &= ~reset;
234: sgttyb.sg_flags |= set;
235: }
236:
237: /*
238: * Set input and output speeds into sgttyb.
239: */
240: sspeed(junkp, ispeed, ospeed)
241: char *junkp;
242: int ispeed, ospeed;
243: {
244: sgtflag = 1;
245: sgttyb.sg_ispeed = ispeed;
246: sgttyb.sg_ospeed = ospeed;
247: }
248:
249: /*
250: * Set up erase and kill line editing
251: * characters.
252: */
253: sedit(junkp, erase, kill)
254: char *junkp;
255: int erase, kill;
256: {
257: sgtflag = 1;
258: if (erase != 0)
259: if (erase == NEXT)
260: sgttyb.sg_erase = cget(); else
261: sgttyb.sg_erase = erase;
262: if (kill != 0)
263: if (kill == NEXT)
264: sgttyb.sg_kill = cget(); else
265: sgttyb.sg_kill = kill;
266: }
267:
268: /*
269: * set a flag
270: * (e.g. hup, excl, flush)
271: */
272: sflag(flagp, val, junk)
273: int *flagp;
274: int val, junk;
275: {
276: *flagp = val;
277: }
278:
279: /*
280: * Set one of the terminal chars.
281: */
282: /* ARGSUSED */
283: stchars(cp, junk, morejunk)
284: char *cp;
285: int junk, morejunk;
286: {
287: tcflag = 1;
288: *cp = cget();
289: }
290:
291: /*
292: * Print out the attributes
293: * of the terminal.
294: */
295: prmodes()
296: {
297: prchar("Erase = ", sgttyb.sg_erase);
298: prchar(", kill = ", sgttyb.sg_kill);
299: putc('\n', stderr);
300: prchar("Interrupt = ", tchars.t_intrc);
301: prchar(", quit = ", tchars.t_quitc);
302: prchar(", break = ", tchars.t_brkc);
303: putc('\n', stderr);
304: prchar("Start = ", tchars.t_startc);
305: prchar(", stop = ", tchars.t_stopc);
306: prchar(", eof = ", tchars.t_eofc);
307: putc('\n', stderr);
308: if (sgttyb.sg_ispeed == sgttyb.sg_ospeed)
309: fprintf(stderr, "Speed: %s\n", speeds[sgttyb.sg_ispeed]);
310: else
311: fprintf(stderr, "Speed: %s (in), %s (out)\n",
312: speeds[sgttyb.sg_ispeed],
313: speeds[sgttyb.sg_ospeed]);
314: fprintf(stderr, "Modes:");
315: prflag(EVENP, "even", NULL);
316: prflag(ODDP, "odd", NULL);
317: prdelay(RAW, "rawin", "rawout", "raw");
318: if (allflag) {
319: prflag(CRMOD, "-nl", "nl");
320: prflag(ECHO, "echo", "-echo");
321: prflag(LCASE, "lcase", "-lcase");
322: prflag(CBREAK, "cbreak", "-cbreak");
323: prflag(TANDEM, "tandem", "-tandem");
324: prflag(CRT, "crt", "-crt");
325: /* The following code gives misinformation. Removed 91/11/17 - hws */
326: #if 0
327: if (exclflag)
328: fprintf(stderr, " excl");
329: else
330: fprintf(stderr, " -excl");
331: if (hupflag)
332: fprintf(stderr, " hup");
333: else
334: fprintf(stderr, " -hup");
335: #endif
336: } else {
337: prflag(CRMOD, NULL, "nl");
338: prflag(ECHO, "echo", NULL);
339: prflag(LCASE, "lcase", NULL);
340: prflag(CBREAK, "cbreak", NULL);
341: prflag(TANDEM, "tandem", NULL);
342: prflag(CRT, "crt", NULL);
343: }
344: /* Delays not supported but should be included here */
345: prflag(XTABS, "-tabs", "tabs");
346: putc('\n', stderr);
347: }
348:
349: /*
350: * Print out a single flag
351: */
352: prflag(mask, ons, offs)
353: int mask;
354: char *ons, *offs;
355: {
356: if (sgttyb.sg_flags & mask) {
357: if (ons != NULL)
358: fprintf(stderr, " %s", ons);
359: } else
360: if (offs != NULL)
361: fprintf(stderr, " %s", offs);
362: }
363:
364: /*
365: * Print out a 4-value delay-type (or raw)
366: * flag.
367: */
368: prdelay(mask, s1, s2, s3)
369: register int mask;
370: char *s1, *s2, *s3;
371: {
372: register int t;
373: register int mode;
374: register char *s = NULL;
375:
376: mode = sgttyb.sg_flags;
377: while ((mask & 01) == 0) {
378: mask >>= 1;
379: mode >>= 1;
380: }
381: t = mode&mask;
382: if (t == 1)
383: s = s1;
384: else if (t == 2)
385: s = s2;
386: else if (t == 3)
387: s = s3;
388: if (s != NULL)
389: fprintf(stderr, " %s", s);
390: }
391:
392: /*
393: * Print out a character taking into
394: * account special characters.
395: */
396: prchar(s, c)
397: char *s;
398: register unsigned char c;
399: {
400: fprintf(stderr, "%s", s);
401: if (c == -1)
402: fprintf(stderr, "off");
403: else if (c == DEL)
404: fprintf(stderr, "DEL");
405: else if (c < ' ')
406: fprintf(stderr, "ctrl-%c", c+'A'-1);
407: else if (c > DEL)
408: fprintf(stderr, "'\\%3o'", c&0377);
409: else
410: fprintf(stderr, "'%c'", c);
411: }
412:
413: /*
414: * Get the modes and tchars value.
415: */
416: getmodes()
417: {
418: if (ioctl(ttyfd, TIOCGETC, &tchars) < 0
419: || ioctl(ttyfd, TIOCGETP, &sgttyb) < 0)
420: sterr("not a terminal");
421: }
422:
423: /*
424: * Set the modes as appropriate
425: * for the commands given.
426: */
427: setmodes()
428: {
429: if (sgtflag)
430: ioctl(ttyfd, scmd, &sgttyb);
431: if (tcflag)
432: ioctl(ttyfd, TIOCSETC, &tchars);
433: if (hupflag)
434: ioctl(ttyfd, hupflag, 0);
435: if (exclflag)
436: ioctl(ttyfd, exclflag, 0);
437: }
438:
439: /*
440: * Get another character from
441: * the command line (e.g. stty erase x)
442: */
443: cget()
444: {
445: register char *ap;
446:
447: if (gargc < 2)
448: usage();
449: ap = gargv[1];
450: gargv++;
451: gargc--;
452: if (strcmp(ap, "off") == 0)
453: return (NONE);
454: if (strcmp(ap, "DEL") == 0)
455: return (DEL);
456: if (strncmp(ap, "ctrl-", 5)==0 && ap[5]!='\0' && ap[6]=='\0')
457: return (ap[5]&~0140);
458: if (*ap=='\\' && ap[1]>='0' && ap[1]<='7') {
459: register char *cp;
460: register int n;
461:
462: n = 0;
463: cp = ap+1;
464: while (*cp>='0' && *cp<='7')
465: n = n*8 + *cp++-'0';
466: if (*cp == '\0')
467: return (n);
468: }
469: if (*ap=='^' && ap[1]!='\0') {
470: if (ap[2]=='\0' && ap[1]&0100)
471: return (ap[1]&~0140);
472: } else if (*ap!='\0' && ap[1]=='\0')
473: return (*ap);
474: sterr("Badly-formed character `%s'", ap);
475: }
476:
477: /*
478: * Print out usage message
479: */
480: usage()
481: {
482: fprintf(stderr, "Usage: %s [-a] [-tttyname] [modes|speeds|chars|]\n",
483: argv0);
484: exit(1);
485: }
486:
487: /*
488: * Error messages with exit from stty.
489: */
490: /* VARARGS */
491: sterr(x)
492: {
493: if (isatty(fileno(stdout)))
494: fprintf(stderr, "stty: ");
495: fprintf(stderr, "%r", &x);
496: fprintf(stderr, "\n");
497: exit (1);
498: }
499:
500: /*
501: * Set terminal parameters to something reasonable.
502: */
503: sane()
504: {
505: sgtflag = 1;
506: sgttyb.sg_flags &= ~(RAW | CBREAK); /* cooked -cbreak */
507: sgttyb.sg_flags |= (CRMOD | ECHO); /* -nl echo */
508: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.