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