|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/ttyio.h>
3: #include <sys/nttyio.h>
4: #include <sys/filio.h>
5:
6: #define CTRL(x) (x&037)
7:
8: extern int errno, ntty_ld, tty_ld;
9: #define NOLD (-1)
10: int ttyfd;
11:
12: struct {
13: char *s_name;
14: int s_define;
15: int s_speed;
16: } speeds[] = {
17: "0", B0, 0,
18: "50", B50, 50,
19: "75", B75, 75,
20: "110", B110, 110,
21: "134", B134, 134,
22: "150", B150, 150,
23: "200", B200, 200,
24: "300", B300, 300,
25: "600", B600, 600,
26: "1200", B1200, 1200,
27: "1800", B1800, 1800,
28: "2400", B2400, 2400,
29: "4800", B4800, 4800,
30: "9600", B9600, 9600,
31: "exta", EXTA, 19200,
32: "extb", EXTB, 0,
33: "19200", EXTA, 19200, /* must follow extb */
34: 0,
35: };
36:
37: #define SGTTY 0
38: #define TTYDEV 1
39: #define NTTY 2
40:
41: struct {
42: char *string;
43: int set;
44: int reset;
45: int where;
46: } modes[] = {
47: { "raw", RAW, 0, SGTTY},
48: { "-raw", 0, RAW, SGTTY},
49: { "cooked", 0, RAW, SGTTY},
50: { "-nl", CRMOD, 0, SGTTY},
51: { "nl", 0, CRMOD, SGTTY},
52: { "echo", ECHO, 0, SGTTY},
53: { "-echo", 0, ECHO, SGTTY},
54: { "LCASE", LCASE, 0, SGTTY},
55: { "lcase", LCASE, 0, SGTTY},
56: { "-LCASE", 0, LCASE, SGTTY},
57: { "-lcase", 0, LCASE, SGTTY},
58: { "-tabs", XTABS, 0, SGTTY},
59: { "tabs", 0, XTABS, SGTTY},
60: { "tandem", TANDEM, 0, SGTTY},
61: { "-tandem", 0, TANDEM, SGTTY},
62: { "cbreak", CBREAK, 0, SGTTY},
63: { "-cbreak", 0, CBREAK, SGTTY},
64: { "cr0", CR0, CR3, SGTTY},
65: { "cr1", CR1, CR3, SGTTY},
66: { "cr2", CR2, CR3, SGTTY},
67: { "cr3", CR3, CR3, SGTTY},
68: { "tab0", TAB0, XTABS, SGTTY},
69: { "tab1", TAB1, XTABS, SGTTY},
70: { "tab2", TAB2, XTABS, SGTTY},
71: { "nl0", NL0, NL3, SGTTY},
72: { "nl1", NL1, NL3, SGTTY},
73: { "nl2", NL2, NL3, SGTTY},
74: { "nl3", NL3, NL3, SGTTY},
75: { "ff0", FF0, FF1, SGTTY},
76: { "ff1", FF1, FF1, SGTTY},
77: { "bs0", BS0, BS1, SGTTY},
78: { "bs1", BS1, BS1, SGTTY},
79: { "8bit", F8BIT, 0, TTYDEV},
80: { "-8bit", 0, F8BIT, TTYDEV},
81: { "even", EVENP, 0, TTYDEV},
82: { "-even", 0, EVENP, TTYDEV},
83: { "odd", ODDP, 0, TTYDEV},
84: { "-odd", 0, ODDP, TTYDEV},
85: { "crtbs", LCRTBS, LPRTERA, NTTY},
86: { "-crtbs", 0, LCRTBS, NTTY},
87: { "prterase", LPRTERA, LCRTBS+LCRTKIL+LCRTERA, NTTY},
88: { "-prterase", 0, LPRTERA, NTTY},
89: { "crterase", LCRTERA, LPRTERA, NTTY},
90: { "-crterase", 0, LCRTERA, NTTY},
91: { "crtkill", LCRTKIL, LPRTERA, NTTY},
92: { "-crtkill", 0, LCRTKIL, NTTY},
93: { "ctlecho", LCTLECH, 0, NTTY},
94: { "-ctlecho", 0, LCTLECH, NTTY},
95: { "tilde", LTILDE, 0, NTTY},
96: { "-tilde", 0, LTILDE, NTTY},
97: { "litout", LLITOUT, 0, NTTY},
98: { "-litout", 0, LLITOUT, NTTY},
99: { "flusho", LFLUSHO, 0, NTTY},
100: { "-flusho", 0, LFLUSHO, NTTY},
101: { "nohang", LNOHANG, 0, NTTY},
102: { "-nohang", 0, LNOHANG, NTTY},
103: { "decctq", LDECCTQ, 0, NTTY},
104: { "-decctq", 0, LDECCTQ, NTTY},
105: 0,
106: };
107:
108: struct sgttyb mode;
109: struct ttydevb speed;
110: struct tchars tc;
111: struct ltchars ltc;
112: struct luchars luc;
113:
114: struct special {
115: char *name;
116: char *cp;
117: char def;
118: } special[] = {
119: "erase", &mode.sg_erase, CTRL('h'),
120: "kill", &mode.sg_kill, '@',
121: "intr", &tc.t_intrc, 0177,
122: "quit", &tc.t_quitc, CTRL('\\'),
123: "start", &tc.t_startc, CTRL('q'),
124: "stop", &tc.t_stopc, CTRL('s'),
125: "eof", &tc.t_eofc, CTRL('d'),
126: "brk", &tc.t_brkc, 0377,
127:
128: "susp", <c.t_suspc, CTRL('z'),
129: "dsusp", <c.t_dsuspc, CTRL('y'),
130: "rprnt", <c.t_rprntc, CTRL('r'),
131: "flush", <c.t_flushc, CTRL('o'),
132: "werase", <c.t_werasc, CTRL('w'),
133: "lnext", <c.t_lnextc, CTRL('v'),
134:
135: "undo", &luc.t_undoc, 0377,
136: "urot", &luc.t_urotc, 0377,
137: 0
138: };
139:
140: char *ego;
141: int ldisc; /* current line disc */
142: int lmode; /* new tty local mode bits */
143:
144: main (argc, argv)
145: int argc;
146: char *argv[];
147: {
148: char *arg, obuf[BUFSIZ];
149: int i;
150: struct special *sp;
151:
152: ego = argv[0];
153: setbuf(stdout, obuf);
154: if ((ttyfd = open("/dev/tty", 1)) < 0) {
155: fprintf(stderr, "%s: can't open /dev/tty\n", ego);
156: exit(1);
157: }
158: (void) getmodes();
159: if (argc < 2) {
160: prmodes();
161: exit (0);
162: }
163: for (arg = *++argv; --argc > 0; arg = *++argv) {
164:
165: #define eq(x) (strcmp(arg, x)==0)
166:
167: if (eq ("all")) {
168: prmodes();
169: continue;
170: }
171: if (eq ("old") || eq ("-new")) {
172: if (swdisc(tty_ld, 0))
173: goto done1;
174: continue;
175: }
176: if (eq ("new")) {
177: if (swdisc(ntty_ld, 0))
178: goto done1;
179: continue;
180: }
181: if (eq("old!") || eq("tty!")) {
182: if (swdisc(tty_ld, 1))
183: goto done1;
184: continue;
185: }
186: if (eq("notty")) {
187: if (swdisc(NOLD, 0))
188: goto done1;
189: continue;
190: }
191: if (eq ("crt")) {
192: lmode |= LCRTBS | LCTLECH;
193: if (speeds[mode.sg_ispeed].s_speed >= 1200)
194: lmode |= LCRTERA | LCRTKIL;
195: continue;
196: }
197: if (eq ("ek")) {
198: mode.sg_erase = '#';
199: mode.sg_kill = '@';
200: continue;
201: }
202: if (eq ("hup")) {
203: (void) ioctl (ttyfd, TIOCHPCL, NULL);
204: continue;
205: }
206: for (sp = special; sp->name; sp++)
207: if (eq (sp->name)) {
208: if (--argc > 0) {
209: arg = *++argv;
210: if (*arg == 'u')
211: *sp->cp = 0377;
212: else if (*arg == '^')
213: *sp->cp = (arg[1] == '?') ?
214: 0177 : arg[1] & 037;
215: else *sp->cp = *arg;
216: goto cont;
217: }
218: fprintf(stderr, "%s: missing %s character\n",
219: ego, arg);
220: goto done1;
221: }
222: for (i = 0; speeds[i].s_name; i++)
223: if (eq (speeds[i].s_name)) {
224: mode.sg_ispeed = mode.sg_ospeed =
225: speeds[i].s_define; /* temp compat */
226: speed.ispeed = speed.ospeed = speeds[i].s_define;
227: goto cont;
228: }
229: for (i = 0; modes[i].string; i++)
230: if (eq (modes[i].string))
231: switch (modes[i].where) {
232: case SGTTY:
233: mode.sg_flags &=~ modes[i].reset;
234: mode.sg_flags |= modes[i].set;
235: goto cont;
236:
237: case TTYDEV:
238: speed.flags &=~ modes[i].reset;
239: speed.flags |= modes[i].set;
240: goto cont;
241:
242: case NTTY:
243: lmode &=~ modes[i].reset;
244: lmode |= modes[i].set;
245: goto cont;
246: }
247: fprintf(stderr, "%s: %s: unknown mode\n", ego, arg);
248: done1:
249: setmodes();
250: exit(1);
251: cont:
252: ;
253: }
254: setmodes();
255: exit(0);
256: }
257:
258: getmodes()
259: {
260: int ret;
261: ldisc = ioctl (ttyfd, FIOLOOKLD, 0);
262: ret = ioctl (ttyfd, TIOCGETP, &mode) == -1;
263: if (ioctl(ttyfd, TIOCGDEV, &speed) < 0) {
264: speed.ispeed = mode.sg_ispeed;
265: speed.ospeed = mode.sg_ospeed;
266: speed.flags = mode.sg_flags & (EVENP|ODDP);
267: }
268: (void) ioctl (ttyfd, TIOCGETC, &tc);
269: if (ldisc == ntty_ld) {
270: if (ioctl(ttyfd, TIOCLGET, &lmode) < 0)
271: perror("TIOCLGET");
272: if (ioctl(ttyfd, TIOCGLTC, <c) < 0)
273: perror("TIOCGLTC");
274: }
275: return ret;
276: }
277:
278: pit (what, itsname, sep)
279: unsigned char what;
280: char *itsname, *sep;
281: {
282: printf("%s", itsname);
283: if (what == 0377) {
284: printf(" <undef>%s", sep);
285: return;
286: }
287: printf(" = ");
288: if (what & 0200) {
289: printf("M-");
290: what &= ~ 0200;
291: }
292: if (what == 0177) {
293: printf("^");
294: what = '?';
295: }
296: else if (what < ' ') {
297: printf("^");
298: what += '@';
299: }
300: printf("%c%s", what, sep);
301: return;
302: }
303:
304:
305: prmodes()
306: {
307: register int m;
308:
309: if (speed.ispeed != speed.ospeed)
310: printf("input speed: %d baud, output speed: %d baud\n",
311: speeds[speed.ispeed].s_speed,
312: speeds[speed.ospeed].s_speed);
313: else
314: printf("speed: %d baud\n",
315: speeds[speed.ispeed].s_speed);
316: pit (mode.sg_erase, "erase", "; ");
317: pit (mode.sg_kill, "kill", "; ");
318: pit (tc.t_intrc, "intr", "; ");
319: pit (tc.t_quitc, "quit", "\n");
320: pit (tc.t_startc, "start", "; ");
321: pit (tc.t_stopc, "stop", "; ");
322: pit (tc.t_eofc, "eof", "; ");
323: pit (tc.t_brkc, "brk", "\n");
324:
325: if (ldisc == ntty_ld) {
326: pit (ltc.t_werasc, "werase", "; ");
327: pit (ltc.t_rprntc, "rprnt", "; ");
328: pit (ltc.t_flushc, "flush", "; ");
329: pit (ltc.t_lnextc, "lnext", "\n");
330: pit (ltc.t_suspc, "susp", "; ");
331: pit (ltc.t_dsuspc, "dsusp", "; ");
332: pit (luc.t_undoc, "undo", "; ");
333: pit (luc.t_urotc, "urot", "\n");
334: }
335: if (ldisc == tty_ld)
336: printf("old ");
337: else if (ldisc == ntty_ld)
338: printf("new ");
339: if (speed.flags & EVENP)
340: printf("even ");
341: if (speed.flags & ODDP)
342: printf("odd ");
343: if (speed.flags & F8BIT)
344: printf("8bit ");
345: m = mode.sg_flags;
346: #define mpit(what,str) printf(str + ((m & what) != 0))
347: mpit (RAW, "-raw ");
348: printf("-nl " + ((m & CRMOD) == 0));
349: mpit (ECHO, "-echo ");
350: mpit (LCASE, "-lcase ");
351: printf("-tabs " + ((m & XTABS) != XTABS));
352: mpit (CBREAK, "-cbreak ");
353: mpit (TANDEM, "-tandem ");
354: #define delay(x,y) if (x) printf("%s%d ", y, x)
355: delay ((m & NLDELAY) / NL1, "nl");
356: if ((m & TBDELAY) != XTABS)
357: delay ((m & TBDELAY) / TAB1, "tab");
358: delay ((m & CRDELAY) / CR1, "cr");
359: delay ((m & VTDELAY) / FF1, "ff");
360: delay ((m & BSDELAY) / BS1, "bs");
361: printf("\n");
362:
363: if (ldisc == ntty_ld) {
364: m = lmode;
365: mpit (LCRTBS, "-crtbs ");
366: mpit (LCRTERA, "-crterase ");
367: mpit (LCRTKIL, "-crtkill ");
368: mpit (LCTLECH, "-ctlecho ");
369: mpit (LPRTERA, "-prterase ");
370: printf("\n");
371:
372: mpit (LTILDE, "-tilde ");
373: mpit (LFLUSHO, "-flusho ");
374: mpit (LLITOUT, "-litout ");
375: mpit (LNOHANG, "-nohang ");
376: mpit (LDECCTQ, "-decctq ");
377: printf("\n");
378: }
379: }
380:
381: /*
382: * it's wrong to ignore returns, but as long as we ignore
383: * them when we get modes, it is less surprising and leads
384: * to fewer bugs, e.g. when no tty driver is present
385: */
386: setmodes()
387: {
388: (void)ioctl(ttyfd, TIOCSETN, &mode);
389: (void)ioctl(ttyfd, TIOCSDEV, &speed);
390: (void)ioctl(ttyfd, TIOCSETC, &tc);
391: if (ldisc == ntty_ld) {
392: if (ioctl(ttyfd, TIOCSLTC, <c) < 0)
393: perror("TIOCSLTC");
394: if (ioctl(ttyfd, TIOCLSET, &lmode) < 0)
395: perror("TIOCLSET");
396: }
397: }
398:
399: int
400: swdisc(newld, force)
401: int newld, force;
402: {
403: int curld = ioctl(ttyfd, FIOLOOKLD, 0);
404:
405: if (force == 0 && curld != tty_ld && curld != ntty_ld)
406: return (0); /* silly but less confusing */
407: if (curld == tty_ld || curld == ntty_ld || curld == newld) {
408: if (ioctl(ttyfd, FIOPOPLD, 0) < 0) {
409: fprintf(stderr, "%s: can't pop line discipline\n", ego);
410: return (-1);
411: }
412: }
413: if (newld == NOLD)
414: return (0);
415: if (ioctl(ttyfd, FIOPUSHLD, &newld) < 0) {
416: if (ioctl(ttyfd, FIOPUSHLD, &ldisc) < 0)
417: perror("FIOPUSHLD");
418: fprintf(stderr, "%s: can't push line discipline\n", ego);
419: return (-1);
420: }
421: /* what follows is a bit silly */
422: if (ioctl(ttyfd, TIOCSETN, &mode) < 0)
423: perror("TIOCSETN");
424: if (ioctl(ttyfd, TIOCSETC, &tc) < 0)
425: perror("TIOCSETC");
426: getmodes();
427: return (0);
428: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.