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