xref: /titanic_44/usr/src/cmd/bnu/setmode.c (revision b7f45089ccbe01bab3d7c7377b49d80d2ae18a69)
1 /*
2  * Copyright (c) 1988,1989,1999 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * Copyright (c) 1983 Regents of the University of California.
8  * All rights reserved. The Berkeley software License Agreement
9  * specifies the terms and conditions for redistribution.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 /*
15  * Stolen from ucb/lpr/printjob.c
16  */
17 
18 #include <string.h>
19 #include "uucp.h"
20 
21 static struct termios termios_set;
22 static struct termios termios_clear;
23 
24 setmode(modes, fd)
25 	char *modes;
26 	int fd;
27 {
28 	if (parse_modes(modes))
29 		setty(fd);
30 }
31 
32 struct mds {
33 	char	*string;
34 	unsigned long	set;
35 	unsigned long	reset;
36 };
37 						/* Control Modes */
38 static struct mds cmodes[] = {
39 	"-parity", CS8, PARENB|CSIZE,
40 	"-evenp", CS8, PARENB|CSIZE,
41 	"-oddp", CS8, PARENB|PARODD|CSIZE,
42 	"parity", PARENB|CS7, PARODD|CSIZE,
43 	"evenp", PARENB|CS7, PARODD|CSIZE,
44 	"oddp", PARENB|PARODD|CS7, CSIZE,
45 	"parenb", PARENB, 0,
46 	"-parenb", 0, PARENB,
47 	"parodd", PARODD, 0,
48 	"-parodd", 0, PARODD,
49 	"cs8", CS8, CSIZE,
50 	"cs7", CS7, CSIZE,
51 	"cs6", CS6, CSIZE,
52 	"cs5", CS5, CSIZE,
53 	"cstopb", CSTOPB, 0,
54 	"-cstopb", 0, CSTOPB,
55 	"stopb", CSTOPB, 0,
56 	"-stopb", 0, CSTOPB,
57 	"hupcl", HUPCL, 0,
58 	"hup", HUPCL, 0,
59 	"-hupcl", 0, HUPCL,
60 	"-hup", 0, HUPCL,
61 	"clocal", CLOCAL, 0,
62 	"-clocal", 0, CLOCAL,
63 	"nohang", CLOCAL, 0,
64 	"-nohang", 0, CLOCAL,
65 #if 0		/* this bit isn't supported */
66 	"loblk", LOBLK, 0,
67 	"-loblk", 0, LOBLK,
68 #endif
69 	"cread", CREAD, 0,
70 	"-cread", 0, CREAD,
71 #ifndef CRTSCTS
72 #define	CRTSCTS	0x80000000
73 #endif
74 	"crtscts", CRTSCTS, 0,
75 	"-crtscts", 0, CRTSCTS,
76 #ifndef CRTSXOFF
77 #define	CRTSXOFF 0x40000000
78 #endif
79 	"crtsxoff", CRTSXOFF, 0,
80 	"-crtsxoff", 0, CRTSXOFF,
81 	"litout", CS8, (CSIZE|PARENB),
82 	"-litout", (CS7|PARENB), CSIZE,
83 	"pass8", CS8, (CSIZE|PARENB),
84 	"-pass8", (CS7|PARENB), CSIZE,
85 	"raw", CS8, (CSIZE|PARENB),
86 	"-raw", (CS7|PARENB), CSIZE,
87 	"cooked", (CS7|PARENB), CSIZE,
88 	"sane", (CS7|PARENB|CREAD), (CSIZE|PARODD|CLOCAL),
89 	0
90 };
91 						/* Input Modes */
92 static struct mds imodes[] = {
93 	"ignbrk", IGNBRK, 0,
94 	"-ignbrk", 0, IGNBRK,
95 	"brkint", BRKINT, 0,
96 	"-brkint", 0, BRKINT,
97 	"ignpar", IGNPAR, 0,
98 	"-ignpar", 0, IGNPAR,
99 	"parmrk", PARMRK, 0,
100 	"-parmrk", 0, PARMRK,
101 	"inpck", INPCK, 0,
102 	"-inpck", 0, INPCK,
103 	"istrip", ISTRIP, 0,
104 	"-istrip", 0, ISTRIP,
105 	"inlcr", INLCR, 0,
106 	"-inlcr", 0, INLCR,
107 	"igncr", IGNCR, 0,
108 	"-igncr", 0, IGNCR,
109 	"icrnl", ICRNL, 0,
110 	"-icrnl", 0, ICRNL,
111 	"-nl", ICRNL, (INLCR|IGNCR),
112 	"nl", 0, ICRNL,
113 	"iuclc", IUCLC, 0,
114 	"-iuclc", 0, IUCLC,
115 	"lcase", IUCLC, 0,
116 	"-lcase", 0, IUCLC,
117 	"LCASE", IUCLC, 0,
118 	"-LCASE", 0, IUCLC,
119 	"ixon", IXON, 0,
120 	"-ixon", 0, IXON,
121 	"ixany", IXANY, 0,
122 	"-ixany", 0, IXANY,
123 	"decctlq", 0, IXANY,
124 	"-decctlq", IXANY, 0,
125 	"ixoff", IXOFF, 0,
126 	"-ixoff", 0, IXOFF,
127 	"tandem", IXOFF, 0,
128 	"-tandem", 0, IXOFF,
129 	"imaxbel", IMAXBEL, 0,
130 	"-imaxbel", 0, IMAXBEL,
131 	"pass8", 0, ISTRIP,
132 	"-pass8", ISTRIP, 0,
133 	"raw", 0, (unsigned long)-1,
134 	"-raw", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL), 0,
135 	"cooked", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON), 0,
136 	"sane", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL),
137 		(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF),
138 	0
139 };
140 						/* Local Modes */
141 static struct mds lmodes[] = {
142 	"isig", ISIG, 0,
143 	"-isig", 0, ISIG,
144 	"noisig", 0, ISIG,
145 	"-noisig", ISIG, 0,
146 	"iexten", IEXTEN, 0,
147 	"-iexten", 0, IEXTEN,
148 	"icanon", ICANON, 0,
149 	"-icanon", 0, ICANON,
150 	"cbreak", 0, ICANON,
151 	"-cbreak", ICANON, 0,
152 	"xcase", XCASE, 0,
153 	"-xcase", 0, XCASE,
154 	"lcase", XCASE, 0,
155 	"-lcase", 0, XCASE,
156 	"LCASE", XCASE, 0,
157 	"-LCASE", 0, XCASE,
158 	"echo", ECHO, 0,
159 	"-echo", 0, ECHO,
160 	"echoe", ECHOE, 0,
161 	"-echoe", 0, ECHOE,
162 	"crterase", ECHOE, 0,
163 	"-crterase", 0, ECHOE,
164 	"echok", ECHOK, 0,
165 	"-echok", 0, ECHOK,
166 	"lfkc", ECHOK, 0,
167 	"-lfkc", 0, ECHOK,
168 	"echonl", ECHONL, 0,
169 	"-echonl", 0, ECHONL,
170 	"noflsh", NOFLSH, 0,
171 	"-noflsh", 0, NOFLSH,
172 	"tostop", TOSTOP, 0,
173 	"-tostop", 0, TOSTOP,
174 	"echoctl", ECHOCTL, 0,
175 	"-echoctl", 0, ECHOCTL,
176 	"ctlecho", ECHOCTL, 0,
177 	"-ctlecho", 0, ECHOCTL,
178 	"echoprt", ECHOPRT, 0,
179 	"-echoprt", 0, ECHOPRT,
180 	"prterase", ECHOPRT, 0,
181 	"-prterase", 0, ECHOPRT,
182 	"echoke", ECHOKE, 0,
183 	"-echoke", 0, ECHOKE,
184 	"crtkill", ECHOKE, 0,
185 	"-crtkill", 0, ECHOKE,
186 #if 0		/* this bit isn't supported yet */
187 	"defecho", DEFECHO, 0,
188 	"-defecho", 0, DEFECHO,
189 #endif
190 	"raw", 0, (ISIG|ICANON|XCASE|IEXTEN),
191 	"-raw", (ISIG|ICANON|IEXTEN), 0,
192 	"cooked", (ISIG|ICANON), 0,
193 	"sane", (ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE),
194 		(XCASE|ECHOPRT|ECHONL|NOFLSH),
195 	0,
196 };
197 						/* Output Modes */
198 static struct mds omodes[] = {
199 	"opost", OPOST, 0,
200 	"-opost", 0, OPOST,
201 	"nopost", 0, OPOST,
202 	"-nopost", OPOST, 0,
203 	"olcuc", OLCUC, 0,
204 	"-olcuc", 0, OLCUC,
205 	"lcase", OLCUC, 0,
206 	"-lcase", 0, OLCUC,
207 	"LCASE", OLCUC, 0,
208 	"-LCASE", 0, OLCUC,
209 	"onlcr", ONLCR, 0,
210 	"-onlcr", 0, ONLCR,
211 	"-nl", ONLCR, (OCRNL|ONLRET),
212 	"nl", 0, ONLCR,
213 	"ocrnl", OCRNL, 0,
214 	"-ocrnl", 0, OCRNL,
215 	"onocr", ONOCR, 0,
216 	"-onocr", 0, ONOCR,
217 	"onlret", ONLRET, 0,
218 	"-onlret", 0, ONLRET,
219 	"fill", OFILL, OFDEL,
220 	"-fill", 0, OFILL|OFDEL,
221 	"nul-fill", OFILL, OFDEL,
222 	"del-fill", OFILL|OFDEL, 0,
223 	"ofill", OFILL, 0,
224 	"-ofill", 0, OFILL,
225 	"ofdel", OFDEL, 0,
226 	"-ofdel", 0, OFDEL,
227 	"cr0", CR0, CRDLY,
228 	"cr1", CR1, CRDLY,
229 	"cr2", CR2, CRDLY,
230 	"cr3", CR3, CRDLY,
231 	"tab0", TAB0, TABDLY,
232 	"tabs", TAB0, TABDLY,
233 	"tab1", TAB1, TABDLY,
234 	"tab2", TAB2, TABDLY,
235 	"-tabs", XTABS, TABDLY,
236 	"tab3", XTABS, TABDLY,
237 	"nl0", NL0, NLDLY,
238 	"nl1", NL1, NLDLY,
239 	"ff0", FF0, FFDLY,
240 	"ff1", FF1, FFDLY,
241 	"vt0", VT0, VTDLY,
242 	"vt1", VT1, VTDLY,
243 	"bs0", BS0, BSDLY,
244 	"bs1", BS1, BSDLY,
245 #if 0		/* these bits aren't supported yet */
246 	"pageout", PAGEOUT, 0,
247 	"-pageout", 0, PAGEOUT,
248 	"wrap", WRAP, 0,
249 	"-wrap", 0, WRAP,
250 #endif
251 	"litout", 0, OPOST,
252 	"-litout", OPOST, 0,
253 	"raw", 0, OPOST,
254 	"-raw", OPOST, 0,
255 	"cooked", OPOST, 0,
256 	"33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
257 	"tty33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
258 	"tn", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
259 	"tn300", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
260 	"ti", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
261 	"ti700", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
262 	"05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
263 	"vt05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
264 	"tek", FF1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
265 	"37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
266 	"tty37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
267 	"sane", (OPOST|ONLCR), (OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|
268 			NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
269 	0,
270 };
271 
272 /*
273  * Parse a set of modes.
274  */
275 static int
276 parse_modes(modes)
277 	char *modes;
278 {
279 	register char *curtoken;
280 	register int match;
281 	register int i;
282 
283 	termios_clear.c_iflag = 0;
284 	termios_clear.c_oflag = 0;
285 	termios_clear.c_cflag = 0;
286 	termios_clear.c_lflag = 0;
287 	termios_set.c_iflag = 0;
288 	termios_set.c_oflag = 0;
289 	termios_set.c_cflag = 0;
290 	termios_set.c_lflag = 0;
291 
292 	curtoken = strtok(modes, ",");
293 	while (curtoken != NULL) {
294 		match = 0;
295 		for (i = 0; imodes[i].string != NULL; i++) {
296 			if (strcmp(curtoken, imodes[i].string) == 0) {
297 				match++;
298 				termios_clear.c_iflag |= imodes[i].reset;
299 				termios_set.c_iflag |= imodes[i].set;
300 			}
301 		}
302 		for (i = 0; omodes[i].string != NULL; i++) {
303 			if (strcmp(curtoken, omodes[i].string) == 0) {
304 				match++;
305 				termios_clear.c_oflag |= omodes[i].reset;
306 				termios_set.c_oflag |= omodes[i].set;
307 			}
308 		}
309 		for (i = 0; cmodes[i].string != NULL; i++) {
310 			if (strcmp(curtoken, cmodes[i].string) == 0) {
311 				match++;
312 				termios_clear.c_cflag |= cmodes[i].reset;
313 				termios_set.c_cflag |= cmodes[i].set;
314 			}
315 		}
316 		for (i = 0; lmodes[i].string != NULL; i++) {
317 			if (strcmp(curtoken, lmodes[i].string) == 0) {
318 				match++;
319 				termios_clear.c_lflag |= lmodes[i].reset;
320 				termios_set.c_lflag |= lmodes[i].set;
321 			}
322 		}
323 		if (!match) {
324 			CDEBUG(5, "unknown mode %s in STTY= string", curtoken);
325 			return (0);
326 		}
327 		curtoken = strtok((char *)NULL, ",");
328 	}
329 	return (1);
330 }
331 
332 /*
333  * setup tty lines.
334  */
335 static
336 setty(fd)
337 {
338 	struct termios termios;
339 
340 	if ((*Ioctl)(fd, TCGETS, &termios) < 0) {
341 		CDEBUG(5, "ioctl(TCGETS): %d", errno);
342 		return;
343 	}
344 
345 	termios.c_iflag &= ~termios_clear.c_iflag;
346 	termios.c_iflag |= termios_set.c_iflag;
347 	termios.c_oflag &= ~termios_clear.c_oflag;
348 	termios.c_oflag |= termios_set.c_oflag;
349 	termios.c_cflag &= ~termios_clear.c_cflag;
350 	termios.c_cflag |= termios_set.c_cflag;
351 	termios.c_lflag &= ~termios_clear.c_lflag;
352 	termios.c_lflag |= termios_set.c_lflag;
353 
354 	if ((*Ioctl)(fd, TCSETSF, &termios) < 0) {
355 		CDEBUG(5, "ioctl(TCSETSF): %d", errno);
356 		return;
357 	}
358 }
359