1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate /*
28*0Sstevel@tonic-gate * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
29*0Sstevel@tonic-gate * All Rights Reserved
30*0Sstevel@tonic-gate *
31*0Sstevel@tonic-gate */
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
34*0Sstevel@tonic-gate
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <unistd.h>
37*0Sstevel@tonic-gate #include <stdlib.h>
38*0Sstevel@tonic-gate #include <libintl.h>
39*0Sstevel@tonic-gate #include <sys/types.h>
40*0Sstevel@tonic-gate #include <ctype.h>
41*0Sstevel@tonic-gate #include <termio.h>
42*0Sstevel@tonic-gate #include <sys/stermio.h>
43*0Sstevel@tonic-gate #include <sys/termiox.h>
44*0Sstevel@tonic-gate #ifdef EUC
45*0Sstevel@tonic-gate #include <sys/param.h>
46*0Sstevel@tonic-gate #include <sys/stropts.h>
47*0Sstevel@tonic-gate #include <sys/eucioctl.h>
48*0Sstevel@tonic-gate #include <sys/csiioctl.h>
49*0Sstevel@tonic-gate #include <sys/stream.h>
50*0Sstevel@tonic-gate #include <sys/termios.h>
51*0Sstevel@tonic-gate #include <sys/ldterm.h>
52*0Sstevel@tonic-gate #include <getwidth.h>
53*0Sstevel@tonic-gate #endif /* EUC */
54*0Sstevel@tonic-gate #include "stty.h"
55*0Sstevel@tonic-gate #include <locale.h>
56*0Sstevel@tonic-gate #include <string.h>
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate static char *s_arg; /* s_arg: ptr to mode to be set */
59*0Sstevel@tonic-gate static int match;
60*0Sstevel@tonic-gate #ifdef EUC
61*0Sstevel@tonic-gate static int parse_encoded(struct termios *, ldterm_cs_data_user_t *, int);
62*0Sstevel@tonic-gate #else
63*0Sstevel@tonic-gate static int parse_encoded(struct termios *);
64*0Sstevel@tonic-gate #endif /* EUC */
65*0Sstevel@tonic-gate static int eq(const char *string);
66*0Sstevel@tonic-gate static int gct(char *cp, int term);
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate /* set terminal modes for supplied options */
69*0Sstevel@tonic-gate char *
sttyparse(int argc,char * argv[],int term,struct termio * ocb,struct termios * cb,struct termiox * termiox,struct winsize * winsize,eucwidth_t * wp,struct eucioc * kwp,ldterm_cs_data_user_t * cswp,ldterm_cs_data_user_t * kcswp)70*0Sstevel@tonic-gate sttyparse(int argc, char *argv[], int term, struct termio *ocb,
71*0Sstevel@tonic-gate struct termios *cb, struct termiox *termiox, struct winsize *winsize
72*0Sstevel@tonic-gate #ifdef EUC
73*0Sstevel@tonic-gate /* */, eucwidth_t *wp, struct eucioc *kwp, ldterm_cs_data_user_t *cswp,
74*0Sstevel@tonic-gate ldterm_cs_data_user_t *kcswp
75*0Sstevel@tonic-gate #endif /* EUC */
76*0Sstevel@tonic-gate /* */)
77*0Sstevel@tonic-gate {
78*0Sstevel@tonic-gate int i;
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate while (--argc > 0) {
81*0Sstevel@tonic-gate s_arg = *++argv;
82*0Sstevel@tonic-gate match = 0;
83*0Sstevel@tonic-gate if (term & ASYNC) {
84*0Sstevel@tonic-gate if (eq("erase") && --argc)
85*0Sstevel@tonic-gate cb->c_cc[VERASE] = gct(*++argv, term);
86*0Sstevel@tonic-gate else if (eq("intr") && --argc)
87*0Sstevel@tonic-gate cb->c_cc[VINTR] = gct(*++argv, term);
88*0Sstevel@tonic-gate else if (eq("quit") && --argc)
89*0Sstevel@tonic-gate cb->c_cc[VQUIT] = gct(*++argv, term);
90*0Sstevel@tonic-gate else if (eq("eof") && --argc)
91*0Sstevel@tonic-gate cb->c_cc[VEOF] = gct(*++argv, term);
92*0Sstevel@tonic-gate else if (eq("min") && --argc) {
93*0Sstevel@tonic-gate if (isdigit((unsigned char)argv[1][0]))
94*0Sstevel@tonic-gate cb->c_cc[VMIN] = atoi(*++argv);
95*0Sstevel@tonic-gate else
96*0Sstevel@tonic-gate cb->c_cc[VMIN] = gct(*++argv, term);
97*0Sstevel@tonic-gate } else if (eq("eol") && --argc)
98*0Sstevel@tonic-gate cb->c_cc[VEOL] = gct(*++argv, term);
99*0Sstevel@tonic-gate else if (eq("eol2") && --argc)
100*0Sstevel@tonic-gate cb->c_cc[VEOL2] = gct(*++argv, term);
101*0Sstevel@tonic-gate else if (eq("time") && --argc) {
102*0Sstevel@tonic-gate if (isdigit((unsigned char)argv[1][0]))
103*0Sstevel@tonic-gate cb->c_cc[VTIME] = atoi(*++argv);
104*0Sstevel@tonic-gate else
105*0Sstevel@tonic-gate cb->c_cc[VTIME] = gct(*++argv, term);
106*0Sstevel@tonic-gate } else if (eq("kill") && --argc)
107*0Sstevel@tonic-gate cb->c_cc[VKILL] = gct(*++argv, term);
108*0Sstevel@tonic-gate else if (eq("swtch") && --argc)
109*0Sstevel@tonic-gate cb->c_cc[VSWTCH] = gct(*++argv, term);
110*0Sstevel@tonic-gate if (match)
111*0Sstevel@tonic-gate continue;
112*0Sstevel@tonic-gate if (term & TERMIOS) {
113*0Sstevel@tonic-gate if (eq("start") && --argc)
114*0Sstevel@tonic-gate cb->c_cc[VSTART] = gct(*++argv, term);
115*0Sstevel@tonic-gate else if (eq("stop") && --argc)
116*0Sstevel@tonic-gate cb->c_cc[VSTOP] = gct(*++argv, term);
117*0Sstevel@tonic-gate else if (eq("susp") && --argc)
118*0Sstevel@tonic-gate cb->c_cc[VSUSP] = gct(*++argv, term);
119*0Sstevel@tonic-gate else if (eq("dsusp") && --argc)
120*0Sstevel@tonic-gate cb->c_cc[VDSUSP] = gct(*++argv, term);
121*0Sstevel@tonic-gate else if (eq("rprnt") && --argc)
122*0Sstevel@tonic-gate cb->c_cc[VREPRINT] = gct(*++argv, term);
123*0Sstevel@tonic-gate else if (eq("reprint") && --argc)
124*0Sstevel@tonic-gate cb->c_cc[VREPRINT] = gct(*++argv, term);
125*0Sstevel@tonic-gate else if (eq("discard") && --argc)
126*0Sstevel@tonic-gate cb->c_cc[VDISCARD] = gct(*++argv, term);
127*0Sstevel@tonic-gate else if (eq("flush") && --argc)
128*0Sstevel@tonic-gate cb->c_cc[VDISCARD] = gct(*++argv, term);
129*0Sstevel@tonic-gate else if (eq("werase") && --argc)
130*0Sstevel@tonic-gate cb->c_cc[VWERASE] = gct(*++argv, term);
131*0Sstevel@tonic-gate else if (eq("lnext") && --argc)
132*0Sstevel@tonic-gate cb->c_cc[VLNEXT] = gct(*++argv, term);
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate if (match)
135*0Sstevel@tonic-gate continue;
136*0Sstevel@tonic-gate if (eq("ek")) {
137*0Sstevel@tonic-gate cb->c_cc[VERASE] = CERASE;
138*0Sstevel@tonic-gate cb->c_cc[VKILL] = CKILL;
139*0Sstevel@tonic-gate } else if (eq("line") &&
140*0Sstevel@tonic-gate !(term & TERMIOS) && --argc) {
141*0Sstevel@tonic-gate ocb->c_line = atoi(*++argv);
142*0Sstevel@tonic-gate continue;
143*0Sstevel@tonic-gate } else if (eq("raw")) {
144*0Sstevel@tonic-gate cb->c_cc[VMIN] = 1;
145*0Sstevel@tonic-gate cb->c_cc[VTIME] = 0;
146*0Sstevel@tonic-gate } else if (eq("-raw") | eq("cooked")) {
147*0Sstevel@tonic-gate cb->c_cc[VEOF] = CEOF;
148*0Sstevel@tonic-gate cb->c_cc[VEOL] = CNUL;
149*0Sstevel@tonic-gate } else if (eq("sane")) {
150*0Sstevel@tonic-gate cb->c_cc[VERASE] = CERASE;
151*0Sstevel@tonic-gate cb->c_cc[VKILL] = CKILL;
152*0Sstevel@tonic-gate cb->c_cc[VQUIT] = CQUIT;
153*0Sstevel@tonic-gate cb->c_cc[VINTR] = CINTR;
154*0Sstevel@tonic-gate cb->c_cc[VEOF] = CEOF;
155*0Sstevel@tonic-gate cb->c_cc[VEOL] = CNUL;
156*0Sstevel@tonic-gate /* SWTCH purposely not set */
157*0Sstevel@tonic-gate #ifdef EUC
158*0Sstevel@tonic-gate } else if (eq("defeucw")) {
159*0Sstevel@tonic-gate kwp->eucw[0] = '\001';
160*0Sstevel@tonic-gate kwp->eucw[1] =
161*0Sstevel@tonic-gate (unsigned char)(wp->_eucw1 & 0177);
162*0Sstevel@tonic-gate kwp->eucw[2] =
163*0Sstevel@tonic-gate (unsigned char)(wp->_eucw2 & 0177);
164*0Sstevel@tonic-gate kwp->eucw[3] =
165*0Sstevel@tonic-gate (unsigned char)(wp->_eucw3 & 0177);
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate kwp->scrw[0] = '\001';
168*0Sstevel@tonic-gate kwp->scrw[1] =
169*0Sstevel@tonic-gate (unsigned char)(wp->_scrw1 & 0177);
170*0Sstevel@tonic-gate kwp->scrw[2] =
171*0Sstevel@tonic-gate (unsigned char)(wp->_scrw2 & 0177);
172*0Sstevel@tonic-gate kwp->scrw[3] =
173*0Sstevel@tonic-gate (unsigned char)(wp->_scrw3 & 0177);
174*0Sstevel@tonic-gate
175*0Sstevel@tonic-gate (void) memcpy((void *)kcswp, (const void *)cswp,
176*0Sstevel@tonic-gate sizeof (ldterm_cs_data_user_t));
177*0Sstevel@tonic-gate #endif /* EUC */
178*0Sstevel@tonic-gate } else if ((term & TERMIOS) && eq("ospeed") && --argc) {
179*0Sstevel@tonic-gate s_arg = *++argv;
180*0Sstevel@tonic-gate for (match = 0, i = 0; speeds[i].string; i++) {
181*0Sstevel@tonic-gate if (eq(speeds[i].string)) {
182*0Sstevel@tonic-gate (void) cfsetospeed(cb,
183*0Sstevel@tonic-gate speeds[i].code);
184*0Sstevel@tonic-gate break;
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate }
187*0Sstevel@tonic-gate if (!match)
188*0Sstevel@tonic-gate return (s_arg);
189*0Sstevel@tonic-gate continue;
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate } else if ((term & TERMIOS) && eq("ispeed") && --argc) {
192*0Sstevel@tonic-gate s_arg = *++argv;
193*0Sstevel@tonic-gate for (match = 0, i = 0; speeds[i].string; i++) {
194*0Sstevel@tonic-gate if (eq(speeds[i].string)) {
195*0Sstevel@tonic-gate (void) cfsetispeed(cb,
196*0Sstevel@tonic-gate speeds[i].code);
197*0Sstevel@tonic-gate break;
198*0Sstevel@tonic-gate }
199*0Sstevel@tonic-gate }
200*0Sstevel@tonic-gate if (!match)
201*0Sstevel@tonic-gate return (s_arg);
202*0Sstevel@tonic-gate continue;
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate } else {
205*0Sstevel@tonic-gate for (match = 0, i = 0; speeds[i].string; i++) {
206*0Sstevel@tonic-gate if (eq(speeds[i].string)) {
207*0Sstevel@tonic-gate (void) cfsetospeed(cb,
208*0Sstevel@tonic-gate speeds[i].code);
209*0Sstevel@tonic-gate (void) cfsetispeed(cb,
210*0Sstevel@tonic-gate speeds[i].code);
211*0Sstevel@tonic-gate break;
212*0Sstevel@tonic-gate }
213*0Sstevel@tonic-gate }
214*0Sstevel@tonic-gate }
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate if (!(term & ASYNC) && eq("ctab") && --argc) {
217*0Sstevel@tonic-gate cb->c_cc[7] = gct(*++argv, term);
218*0Sstevel@tonic-gate continue;
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate for (i = 0; imodes[i].string; i++)
222*0Sstevel@tonic-gate if (eq(imodes[i].string)) {
223*0Sstevel@tonic-gate cb->c_iflag &= ~imodes[i].reset;
224*0Sstevel@tonic-gate cb->c_iflag |= imodes[i].set;
225*0Sstevel@tonic-gate #ifdef EUC
226*0Sstevel@tonic-gate if (wp->_multibyte &&
227*0Sstevel@tonic-gate (eq("-raw") || eq("cooked") || eq("sane")))
228*0Sstevel@tonic-gate cb->c_iflag &= ~ISTRIP;
229*0Sstevel@tonic-gate #endif /* EUC */
230*0Sstevel@tonic-gate }
231*0Sstevel@tonic-gate if (term & TERMIOS) {
232*0Sstevel@tonic-gate for (i = 0; nimodes[i].string; i++)
233*0Sstevel@tonic-gate if (eq(nimodes[i].string)) {
234*0Sstevel@tonic-gate cb->c_iflag &= ~nimodes[i].reset;
235*0Sstevel@tonic-gate cb->c_iflag |= nimodes[i].set;
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate }
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate for (i = 0; omodes[i].string; i++)
240*0Sstevel@tonic-gate if (eq(omodes[i].string)) {
241*0Sstevel@tonic-gate cb->c_oflag &= ~omodes[i].reset;
242*0Sstevel@tonic-gate cb->c_oflag |= omodes[i].set;
243*0Sstevel@tonic-gate }
244*0Sstevel@tonic-gate if (!(term & ASYNC) && eq("sane")) {
245*0Sstevel@tonic-gate cb->c_oflag |= TAB3;
246*0Sstevel@tonic-gate continue;
247*0Sstevel@tonic-gate }
248*0Sstevel@tonic-gate for (i = 0; cmodes[i].string; i++)
249*0Sstevel@tonic-gate if (eq(cmodes[i].string)) {
250*0Sstevel@tonic-gate cb->c_cflag &= ~cmodes[i].reset;
251*0Sstevel@tonic-gate cb->c_cflag |= cmodes[i].set;
252*0Sstevel@tonic-gate #ifdef EUC
253*0Sstevel@tonic-gate if (wp->_multibyte &&
254*0Sstevel@tonic-gate (eq("-raw") || eq("cooked") || eq("sane"))) {
255*0Sstevel@tonic-gate cb->c_cflag &= ~(CS7|PARENB);
256*0Sstevel@tonic-gate cb->c_cflag |= CS8;
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate #endif /* EUC */
259*0Sstevel@tonic-gate }
260*0Sstevel@tonic-gate if (term & TERMIOS)
261*0Sstevel@tonic-gate for (i = 0; ncmodes[i].string; i++)
262*0Sstevel@tonic-gate if (eq(ncmodes[i].string)) {
263*0Sstevel@tonic-gate cb->c_cflag &= ~ncmodes[i].reset;
264*0Sstevel@tonic-gate cb->c_cflag |= ncmodes[i].set;
265*0Sstevel@tonic-gate }
266*0Sstevel@tonic-gate for (i = 0; lmodes[i].string; i++)
267*0Sstevel@tonic-gate if (eq(lmodes[i].string)) {
268*0Sstevel@tonic-gate cb->c_lflag &= ~lmodes[i].reset;
269*0Sstevel@tonic-gate cb->c_lflag |= lmodes[i].set;
270*0Sstevel@tonic-gate }
271*0Sstevel@tonic-gate if (term & TERMIOS)
272*0Sstevel@tonic-gate for (i = 0; nlmodes[i].string; i++)
273*0Sstevel@tonic-gate if (eq(nlmodes[i].string)) {
274*0Sstevel@tonic-gate cb->c_lflag &= ~nlmodes[i].reset;
275*0Sstevel@tonic-gate cb->c_lflag |= nlmodes[i].set;
276*0Sstevel@tonic-gate }
277*0Sstevel@tonic-gate if (term & FLOW) {
278*0Sstevel@tonic-gate for (i = 0; hmodes[i].string; i++)
279*0Sstevel@tonic-gate if (eq(hmodes[i].string)) {
280*0Sstevel@tonic-gate termiox->x_hflag &= ~hmodes[i].reset;
281*0Sstevel@tonic-gate termiox->x_hflag |= hmodes[i].set;
282*0Sstevel@tonic-gate }
283*0Sstevel@tonic-gate for (i = 0; clkmodes[i].string; i++)
284*0Sstevel@tonic-gate if (eq(clkmodes[i].string)) {
285*0Sstevel@tonic-gate termiox->x_cflag &= ~clkmodes[i].reset;
286*0Sstevel@tonic-gate termiox->x_cflag |= clkmodes[i].set;
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate }
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate if (eq("rows") && --argc)
292*0Sstevel@tonic-gate winsize->ws_row = atoi(*++argv);
293*0Sstevel@tonic-gate else if ((eq("columns") || eq("cols")) && --argc)
294*0Sstevel@tonic-gate winsize->ws_col = atoi(*++argv);
295*0Sstevel@tonic-gate else if (eq("xpixels") && --argc)
296*0Sstevel@tonic-gate winsize->ws_xpixel = atoi(*++argv);
297*0Sstevel@tonic-gate else if (eq("ypixels") && --argc)
298*0Sstevel@tonic-gate winsize->ws_ypixel = atoi(*++argv);
299*0Sstevel@tonic-gate
300*0Sstevel@tonic-gate if (!match) {
301*0Sstevel@tonic-gate #ifdef EUC
302*0Sstevel@tonic-gate if (!parse_encoded(cb, kcswp, term)) {
303*0Sstevel@tonic-gate #else
304*0Sstevel@tonic-gate if (!parse_encoded(cb)) {
305*0Sstevel@tonic-gate #endif /* EUC */
306*0Sstevel@tonic-gate return (s_arg); /* parsing failed */
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate }
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate return ((char *)0);
311*0Sstevel@tonic-gate }
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate static int
314*0Sstevel@tonic-gate eq(const char *string)
315*0Sstevel@tonic-gate {
316*0Sstevel@tonic-gate int i;
317*0Sstevel@tonic-gate
318*0Sstevel@tonic-gate if (!s_arg)
319*0Sstevel@tonic-gate return (0);
320*0Sstevel@tonic-gate i = 0;
321*0Sstevel@tonic-gate loop:
322*0Sstevel@tonic-gate if (s_arg[i] != string[i])
323*0Sstevel@tonic-gate return (0);
324*0Sstevel@tonic-gate if (s_arg[i++] != '\0')
325*0Sstevel@tonic-gate goto loop;
326*0Sstevel@tonic-gate match++;
327*0Sstevel@tonic-gate return (1);
328*0Sstevel@tonic-gate }
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gate /* get pseudo control characters from terminal */
331*0Sstevel@tonic-gate /* and convert to internal representation */
332*0Sstevel@tonic-gate static int
333*0Sstevel@tonic-gate gct(char *cp, int term)
334*0Sstevel@tonic-gate {
335*0Sstevel@tonic-gate int c;
336*0Sstevel@tonic-gate
337*0Sstevel@tonic-gate c = *cp;
338*0Sstevel@tonic-gate if (c == '^') {
339*0Sstevel@tonic-gate c = *++cp;
340*0Sstevel@tonic-gate if (c == '?')
341*0Sstevel@tonic-gate c = 0177; /* map '^?' to 0177 */
342*0Sstevel@tonic-gate else if (c == '-') {
343*0Sstevel@tonic-gate /* map '^-' to undefined */
344*0Sstevel@tonic-gate c = (term & TERMIOS) ? _POSIX_VDISABLE : 0200;
345*0Sstevel@tonic-gate } else
346*0Sstevel@tonic-gate c &= 037;
347*0Sstevel@tonic-gate } else if (strcmp(cp, "undef") == 0) {
348*0Sstevel@tonic-gate /* map "undef" to undefined */
349*0Sstevel@tonic-gate c = (term & TERMIOS) ? _POSIX_VDISABLE : 0200;
350*0Sstevel@tonic-gate }
351*0Sstevel@tonic-gate return (c);
352*0Sstevel@tonic-gate }
353*0Sstevel@tonic-gate
354*0Sstevel@tonic-gate /* get modes of tty device and fill in applicable structures */
355*0Sstevel@tonic-gate int
356*0Sstevel@tonic-gate get_ttymode(int fd, struct termio *termio, struct termios *termios,
357*0Sstevel@tonic-gate struct stio *stermio, struct termiox *termiox, struct winsize *winsize
358*0Sstevel@tonic-gate #ifdef EUC
359*0Sstevel@tonic-gate /* */, struct eucioc *kwp, ldterm_cs_data_user_t *kcswp
360*0Sstevel@tonic-gate #endif /* EUC */
361*0Sstevel@tonic-gate /* */)
362*0Sstevel@tonic-gate {
363*0Sstevel@tonic-gate int i;
364*0Sstevel@tonic-gate int term = 0;
365*0Sstevel@tonic-gate #ifdef EUC
366*0Sstevel@tonic-gate struct strioctl cmd;
367*0Sstevel@tonic-gate #endif /* EUC */
368*0Sstevel@tonic-gate if (ioctl(fd, STGET, stermio) == -1) {
369*0Sstevel@tonic-gate term |= ASYNC;
370*0Sstevel@tonic-gate if (ioctl(fd, TCGETS, termios) == -1) {
371*0Sstevel@tonic-gate if (ioctl(fd, TCGETA, termio) == -1)
372*0Sstevel@tonic-gate return (-1);
373*0Sstevel@tonic-gate termios->c_lflag = termio->c_lflag;
374*0Sstevel@tonic-gate termios->c_oflag = termio->c_oflag;
375*0Sstevel@tonic-gate termios->c_iflag = termio->c_iflag;
376*0Sstevel@tonic-gate termios->c_cflag = termio->c_cflag;
377*0Sstevel@tonic-gate for (i = 0; i < NCC; i++)
378*0Sstevel@tonic-gate termios->c_cc[i] = termio->c_cc[i];
379*0Sstevel@tonic-gate } else
380*0Sstevel@tonic-gate term |= TERMIOS;
381*0Sstevel@tonic-gate } else {
382*0Sstevel@tonic-gate termios->c_cc[7] = (unsigned)stermio->tab;
383*0Sstevel@tonic-gate termios->c_lflag = stermio->lmode;
384*0Sstevel@tonic-gate termios->c_oflag = stermio->omode;
385*0Sstevel@tonic-gate termios->c_iflag = stermio->imode;
386*0Sstevel@tonic-gate }
387*0Sstevel@tonic-gate
388*0Sstevel@tonic-gate if (ioctl(fd, TCGETX, termiox) == 0)
389*0Sstevel@tonic-gate term |= FLOW;
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate if (ioctl(fd, TIOCGWINSZ, winsize) == 0)
392*0Sstevel@tonic-gate term |= WINDOW;
393*0Sstevel@tonic-gate #ifdef EUC
394*0Sstevel@tonic-gate cmd.ic_cmd = EUC_WGET;
395*0Sstevel@tonic-gate cmd.ic_timout = 0;
396*0Sstevel@tonic-gate cmd.ic_len = sizeof (struct eucioc);
397*0Sstevel@tonic-gate cmd.ic_dp = (char *)kwp;
398*0Sstevel@tonic-gate
399*0Sstevel@tonic-gate if (ioctl(fd, I_STR, &cmd) == 0)
400*0Sstevel@tonic-gate term |= EUCW;
401*0Sstevel@tonic-gate
402*0Sstevel@tonic-gate cmd.ic_cmd = CSDATA_GET;
403*0Sstevel@tonic-gate cmd.ic_timout = 0;
404*0Sstevel@tonic-gate cmd.ic_len = sizeof (ldterm_cs_data_user_t);
405*0Sstevel@tonic-gate cmd.ic_dp = (char *)kcswp;
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gate if (ioctl(fd, I_STR, &cmd) == 0)
408*0Sstevel@tonic-gate term |= CSIW;
409*0Sstevel@tonic-gate else
410*0Sstevel@tonic-gate (void) memset((void *)kcswp, 0, sizeof (ldterm_cs_data_user_t));
411*0Sstevel@tonic-gate #endif /* EUC */
412*0Sstevel@tonic-gate return (term);
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate
415*0Sstevel@tonic-gate /* set tty modes */
416*0Sstevel@tonic-gate int
417*0Sstevel@tonic-gate set_ttymode(int fd, int term, struct termio *termio, struct termios *termios,
418*0Sstevel@tonic-gate struct stio *stermio, struct termiox *termiox, struct winsize *winsize,
419*0Sstevel@tonic-gate struct winsize *owinsize
420*0Sstevel@tonic-gate #ifdef EUC
421*0Sstevel@tonic-gate /* */, struct eucioc *kwp, ldterm_cs_data_user_t *kcswp,
422*0Sstevel@tonic-gate int invalid_ldterm_dat_file
423*0Sstevel@tonic-gate #endif /* EUC */
424*0Sstevel@tonic-gate /* */)
425*0Sstevel@tonic-gate {
426*0Sstevel@tonic-gate int i;
427*0Sstevel@tonic-gate #ifdef EUC
428*0Sstevel@tonic-gate struct strioctl cmd;
429*0Sstevel@tonic-gate #endif /* EUC */
430*0Sstevel@tonic-gate
431*0Sstevel@tonic-gate if (term & ASYNC) {
432*0Sstevel@tonic-gate if (term & TERMIOS) {
433*0Sstevel@tonic-gate if (ioctl(fd, TCSETSW, termios) == -1)
434*0Sstevel@tonic-gate return (-1);
435*0Sstevel@tonic-gate } else {
436*0Sstevel@tonic-gate termio->c_lflag = termios->c_lflag;
437*0Sstevel@tonic-gate termio->c_oflag = termios->c_oflag;
438*0Sstevel@tonic-gate termio->c_iflag = termios->c_iflag;
439*0Sstevel@tonic-gate termio->c_cflag = termios->c_cflag;
440*0Sstevel@tonic-gate for (i = 0; i < NCC; i++)
441*0Sstevel@tonic-gate termio->c_cc[i] = termios->c_cc[i];
442*0Sstevel@tonic-gate if (ioctl(fd, TCSETAW, termio) == -1)
443*0Sstevel@tonic-gate return (-1);
444*0Sstevel@tonic-gate }
445*0Sstevel@tonic-gate
446*0Sstevel@tonic-gate } else {
447*0Sstevel@tonic-gate stermio->imode = termios->c_iflag;
448*0Sstevel@tonic-gate stermio->omode = termios->c_oflag;
449*0Sstevel@tonic-gate stermio->lmode = termios->c_lflag;
450*0Sstevel@tonic-gate stermio->tab = termios->c_cc[7];
451*0Sstevel@tonic-gate if (ioctl(fd, STSET, stermio) == -1)
452*0Sstevel@tonic-gate return (-1);
453*0Sstevel@tonic-gate }
454*0Sstevel@tonic-gate if (term & FLOW) {
455*0Sstevel@tonic-gate if (ioctl(fd, TCSETXW, termiox) == -1)
456*0Sstevel@tonic-gate return (-1);
457*0Sstevel@tonic-gate }
458*0Sstevel@tonic-gate if ((owinsize->ws_col != winsize->ws_col ||
459*0Sstevel@tonic-gate owinsize->ws_row != winsize->ws_row ||
460*0Sstevel@tonic-gate owinsize->ws_xpixel != winsize->ws_xpixel ||
461*0Sstevel@tonic-gate owinsize->ws_ypixel != winsize->ws_ypixel) &&
462*0Sstevel@tonic-gate ioctl(0, TIOCSWINSZ, winsize) != 0)
463*0Sstevel@tonic-gate return (-1);
464*0Sstevel@tonic-gate #ifdef EUC
465*0Sstevel@tonic-gate /*
466*0Sstevel@tonic-gate * If the ldterm.dat file contains valid, non-EUC codeset info,
467*0Sstevel@tonic-gate * send downstream CSDATA_SET. Otherwise, try EUC_WSET.
468*0Sstevel@tonic-gate */
469*0Sstevel@tonic-gate if (invalid_ldterm_dat_file) {
470*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(
471*0Sstevel@tonic-gate "stty: can't set codeset width due to invalid ldterm.dat.\n"));
472*0Sstevel@tonic-gate return (-1);
473*0Sstevel@tonic-gate } else if ((term & CSIW) && kcswp->version) {
474*0Sstevel@tonic-gate cmd.ic_cmd = CSDATA_SET;
475*0Sstevel@tonic-gate cmd.ic_timout = 0;
476*0Sstevel@tonic-gate cmd.ic_len = sizeof (ldterm_cs_data_user_t);
477*0Sstevel@tonic-gate cmd.ic_dp = (char *)kcswp;
478*0Sstevel@tonic-gate if (ioctl(fd, I_STR, &cmd) != 0) {
479*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(
480*0Sstevel@tonic-gate "stty: can't set codeset width.\n"));
481*0Sstevel@tonic-gate return (-1);
482*0Sstevel@tonic-gate }
483*0Sstevel@tonic-gate } else if (term & EUCW) {
484*0Sstevel@tonic-gate cmd.ic_cmd = EUC_WSET;
485*0Sstevel@tonic-gate cmd.ic_timout = 0;
486*0Sstevel@tonic-gate cmd.ic_len = sizeof (struct eucioc);
487*0Sstevel@tonic-gate cmd.ic_dp = (char *)kwp;
488*0Sstevel@tonic-gate if (ioctl(fd, I_STR, &cmd) != 0) {
489*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(
490*0Sstevel@tonic-gate "stty: can't set EUC codeset width.\n"));
491*0Sstevel@tonic-gate return (-1);
492*0Sstevel@tonic-gate }
493*0Sstevel@tonic-gate }
494*0Sstevel@tonic-gate #endif /* EUC */
495*0Sstevel@tonic-gate return (0);
496*0Sstevel@tonic-gate }
497*0Sstevel@tonic-gate
498*0Sstevel@tonic-gate static int
499*0Sstevel@tonic-gate parse_encoded(struct termios *cb
500*0Sstevel@tonic-gate #ifdef EUC
501*0Sstevel@tonic-gate /* */, ldterm_cs_data_user_t *kcswp, int term
502*0Sstevel@tonic-gate #endif /* EUC */
503*0Sstevel@tonic-gate /* */)
504*0Sstevel@tonic-gate {
505*0Sstevel@tonic-gate unsigned long grab[NUM_FIELDS];
506*0Sstevel@tonic-gate int last, i;
507*0Sstevel@tonic-gate #ifdef EUC
508*0Sstevel@tonic-gate long l;
509*0Sstevel@tonic-gate char s[3];
510*0Sstevel@tonic-gate char *t;
511*0Sstevel@tonic-gate char *r;
512*0Sstevel@tonic-gate uchar_t *g;
513*0Sstevel@tonic-gate ldterm_cs_data_user_t ecswp;
514*0Sstevel@tonic-gate #endif /* EUC */
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gate /*
517*0Sstevel@tonic-gate * Although there are only 16 control chars defined as of April 1995,
518*0Sstevel@tonic-gate * parse_encoded() and prencode() will not have to be changed if up to
519*0Sstevel@tonic-gate * MAX_CC control chars are defined in the future.
520*0Sstevel@tonic-gate * Scan the fields of "stty -g" output into the grab array.
521*0Sstevel@tonic-gate * Set a total of NUM_FIELDS fields (NUM_MODES modes + MAX_CC
522*0Sstevel@tonic-gate * control chars).
523*0Sstevel@tonic-gate */
524*0Sstevel@tonic-gate i = sscanf(s_arg, "%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:"
525*0Sstevel@tonic-gate "%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",
526*0Sstevel@tonic-gate &grab[0], &grab[1], &grab[2], &grab[3], &grab[4], &grab[5],
527*0Sstevel@tonic-gate &grab[6], &grab[7], &grab[8], &grab[9], &grab[10], &grab[11],
528*0Sstevel@tonic-gate &grab[12], &grab[13], &grab[14], &grab[15], &grab[16], &grab[17],
529*0Sstevel@tonic-gate &grab[18], &grab[19], &grab[20], &grab[21]);
530*0Sstevel@tonic-gate
531*0Sstevel@tonic-gate if (i < 12)
532*0Sstevel@tonic-gate return (0);
533*0Sstevel@tonic-gate cb->c_iflag = grab[0];
534*0Sstevel@tonic-gate cb->c_oflag = grab[1];
535*0Sstevel@tonic-gate cb->c_cflag = grab[2];
536*0Sstevel@tonic-gate cb->c_lflag = grab[3];
537*0Sstevel@tonic-gate
538*0Sstevel@tonic-gate last = i - NUM_MODES;
539*0Sstevel@tonic-gate for (i = 0; i < last; i++)
540*0Sstevel@tonic-gate cb->c_cc[i] = (unsigned char) grab[i+NUM_MODES];
541*0Sstevel@tonic-gate
542*0Sstevel@tonic-gate #ifdef EUC
543*0Sstevel@tonic-gate /* This is to fulfill PSARC/1999/140 TCR2. */
544*0Sstevel@tonic-gate if (term & CSIW) {
545*0Sstevel@tonic-gate r = strdup(s_arg);
546*0Sstevel@tonic-gate if (r == (char *)NULL) {
547*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(
548*0Sstevel@tonic-gate "no more memory - try again later\n"));
549*0Sstevel@tonic-gate return (0);
550*0Sstevel@tonic-gate }
551*0Sstevel@tonic-gate t = strtok(r, ":");
552*0Sstevel@tonic-gate for (i = 0; t != NULL && i < 22; i++) {
553*0Sstevel@tonic-gate t = strtok(NULL, ":");
554*0Sstevel@tonic-gate }
555*0Sstevel@tonic-gate
556*0Sstevel@tonic-gate if (t == NULL) {
557*0Sstevel@tonic-gate free((void *)r);
558*0Sstevel@tonic-gate return (0);
559*0Sstevel@tonic-gate }
560*0Sstevel@tonic-gate ecswp.version = (uchar_t)strtol(t, (char **)NULL, 16);
561*0Sstevel@tonic-gate if (ecswp.version > LDTERM_DATA_VERSION ||
562*0Sstevel@tonic-gate ecswp.version == 0) {
563*0Sstevel@tonic-gate free((void *)r);
564*0Sstevel@tonic-gate return (0);
565*0Sstevel@tonic-gate }
566*0Sstevel@tonic-gate
567*0Sstevel@tonic-gate if ((t = strtok(NULL, ":")) == NULL) {
568*0Sstevel@tonic-gate free((void *)r);
569*0Sstevel@tonic-gate return (0);
570*0Sstevel@tonic-gate }
571*0Sstevel@tonic-gate ecswp.codeset_type = (uchar_t)strtol(t, (char **)NULL, 16);
572*0Sstevel@tonic-gate if (ecswp.codeset_type < LDTERM_CS_TYPE_MIN ||
573*0Sstevel@tonic-gate ecswp.codeset_type > LDTERM_CS_TYPE_MAX) {
574*0Sstevel@tonic-gate free((void *)r);
575*0Sstevel@tonic-gate return (0);
576*0Sstevel@tonic-gate }
577*0Sstevel@tonic-gate
578*0Sstevel@tonic-gate if ((t = strtok(NULL, ":")) == NULL) {
579*0Sstevel@tonic-gate free((void *)r);
580*0Sstevel@tonic-gate return (0);
581*0Sstevel@tonic-gate }
582*0Sstevel@tonic-gate ecswp.csinfo_num = (uchar_t)strtol(t, (char **)NULL, 16);
583*0Sstevel@tonic-gate if ((ecswp.codeset_type == LDTERM_CS_TYPE_EUC &&
584*0Sstevel@tonic-gate ecswp.csinfo_num > 3) ||
585*0Sstevel@tonic-gate (ecswp.codeset_type == LDTERM_CS_TYPE_PCCS &&
586*0Sstevel@tonic-gate (ecswp.csinfo_num < 1 || ecswp.csinfo_num > 10))) {
587*0Sstevel@tonic-gate free((void *)r);
588*0Sstevel@tonic-gate return (0);
589*0Sstevel@tonic-gate }
590*0Sstevel@tonic-gate
591*0Sstevel@tonic-gate if ((t = strtok(NULL, ":")) == NULL) {
592*0Sstevel@tonic-gate free((void *)r);
593*0Sstevel@tonic-gate return (0);
594*0Sstevel@tonic-gate }
595*0Sstevel@tonic-gate s[2] = '\0';
596*0Sstevel@tonic-gate for (i = 0; *t != 0 && i < MAXNAMELEN; i++) {
597*0Sstevel@tonic-gate if (*(t + 1) == (char)NULL) {
598*0Sstevel@tonic-gate free((void *)r);
599*0Sstevel@tonic-gate return (0);
600*0Sstevel@tonic-gate }
601*0Sstevel@tonic-gate s[0] = *t++;
602*0Sstevel@tonic-gate s[1] = *t++;
603*0Sstevel@tonic-gate ecswp.locale_name[i] = (char)strtol(s, (char **)NULL,
604*0Sstevel@tonic-gate 16);
605*0Sstevel@tonic-gate }
606*0Sstevel@tonic-gate if (i >= MAXNAMELEN) {
607*0Sstevel@tonic-gate free((void *)r);
608*0Sstevel@tonic-gate return (0);
609*0Sstevel@tonic-gate }
610*0Sstevel@tonic-gate ecswp.locale_name[i] = '\0';
611*0Sstevel@tonic-gate
612*0Sstevel@tonic-gate g = (uchar_t *)ecswp.eucpc_data;
613*0Sstevel@tonic-gate for (i = 0; i < (LDTERM_CS_MAX_CODESETS * 4); i++) {
614*0Sstevel@tonic-gate if ((t = strtok(NULL, ":")) == NULL) {
615*0Sstevel@tonic-gate free((void *)r);
616*0Sstevel@tonic-gate return (0);
617*0Sstevel@tonic-gate }
618*0Sstevel@tonic-gate l = strtol(t, (char **)NULL, 16);
619*0Sstevel@tonic-gate if (l < 0 || l > 255) {
620*0Sstevel@tonic-gate free((void *)r);
621*0Sstevel@tonic-gate return (0);
622*0Sstevel@tonic-gate }
623*0Sstevel@tonic-gate *g++ = (uchar_t)l;
624*0Sstevel@tonic-gate }
625*0Sstevel@tonic-gate
626*0Sstevel@tonic-gate /* We got the 'ecswp' all filled up now; let's copy. */
627*0Sstevel@tonic-gate (void) memcpy((void *)kcswp, (const void *)&ecswp,
628*0Sstevel@tonic-gate sizeof (ldterm_cs_data_user_t));
629*0Sstevel@tonic-gate }
630*0Sstevel@tonic-gate #endif /* EUC */
631*0Sstevel@tonic-gate
632*0Sstevel@tonic-gate return (1);
633*0Sstevel@tonic-gate }
634