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
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.
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <sys/types.h>
41 #include <sys/stermio.h>
42 #include <sys/termiox.h>
48 static void insert_def();
53 extern struct Gdef Gdef
[];
58 * read_ttydefs - read in the /etc/ttydefs and store in Gdef array
59 * - if id is not NULL, only get entry with that id
60 * - if check is TRUE, print out the entries
63 read_ttydefs(id
,check
)
68 static struct Gdef def
;
69 register struct Gdef
*gptr
;
70 static char line
[BUFSIZ
];
71 static char dbuf
[BUFSIZ
];
74 int input
,state
,size
,rawc
,field
;
76 static char d_id
[MAXID
+1],
81 static char *states
[] = {
82 "","tty label","Initial flags","Final flags","Autobaud","Next label"
84 extern char *getword();
86 if ((fp
= fopen(TTYDEFS
,"r")) == NULL
) {
87 log("can't open \"%s\".\n", TTYDEFS
);
92 for (len
= 0; len
< (size_t)(BUFSIZ
- 1); len
++)
97 /* Start searching for the line with the proper "id". */
101 for (ptr
= line
,oldc
= '\0'; ptr
< &line
[sizeof(line
)-1] &&
102 (rawc
=getc(fp
))!='\n' && rawc
!= EOF
; ptr
++,oldc
=(char)rawc
){
103 if ((rawc
== '#') && (oldc
!= '\\'))
109 /* skip rest of the line */
110 if (rawc
!= EOF
&& rawc
!= '\n') {
111 if (check
&& rawc
!= '#')
112 log("Entry too long.");
113 while ((rawc
= getc(fp
)) != EOF
&& rawc
!= '\n')
118 if (ptr
== line
) break;
119 else input
= FINISHED
;
122 /* if empty line, skip */
123 for (ptr
=line
; *ptr
!= '\0' && isspace(*ptr
); ptr
++)
125 if (*ptr
== '\0') continue;
127 /* Now we have the complete line */
129 /* Initialize "def" and "gptr". */
131 zero((char *)gptr
, sizeof(struct Gdef
));
135 (void)strncpy(d_id
,getword(ptr
,&size
,0),MAXID
);
142 ptr
++; /* Skip the ':' */
146 /* If "id" != NULL, and it does not match, go to next entry */
147 if ((id
!= NULL
) && (strcmp(id
,gptr
->g_id
) != 0))
160 for (; state
!= FAILURE
&& state
!= SUCCESS
;) {
164 (void)strncpy(d_if
,getword(ptr
,&size
,1),BUFSIZ
);
165 gptr
->g_iflags
= d_if
;
167 if ((*ptr
!= ':') || (check_flags(d_if
) != 0)) {
177 (void)strncpy(d_ff
,getword(ptr
,&size
,1),BUFSIZ
);
178 gptr
->g_fflags
= d_ff
;
180 if ((*ptr
!= ':') || (check_flags(d_ff
) != 0)) {
190 (void)strncpy(d_autobaud
,getword(ptr
,&size
,0),MAXID
);
198 if (*d_autobaud
== 'A')
199 gptr
->g_autobaud
|= A_FLAG
;
212 ptr
++; /* Skip the ':' */
218 (void)strncpy(d_nextid
,getword(ptr
,&size
,0),MAXID
);
219 gptr
->g_nextid
= d_nextid
;
224 } else state
= SUCCESS
;
230 if (state
== SUCCESS
) {
233 log("ttylabel:\t%s", gptr
->g_id
);
234 log("initial flags:\t%s", gptr
->g_iflags
);
235 log("final flags:\t%s", gptr
->g_fflags
);
236 if (gptr
->g_autobaud
& A_FLAG
)
237 log("autobaud:\tyes");
239 log("autobaud:\tno");
240 log("nextlabel:\t%s", gptr
->g_nextid
);
245 log("can't add more entries to ttydefs table, "
246 " Maximum entries = %d", MAXDEFS
);
256 log("Parsing failure in the \"%s\" field\n"
257 "%s<--error detected here\n", states
[field
],line
);
259 } while (input
== ACTIVE
);
265 * zero - zero out the buffer
273 while (size
--) *adr
++ = '\0';
278 * - scan Gdef table for an entry with requested "ttylabel".
279 * - return a Gdef ptr if entry with "ttylabel" is found
280 * - return NULL if no entry with matching "ttylabel"
290 for (i
= 0; i
< Ndefs
; i
++,tp
++) {
291 if (strcmp(ttylabel
, tp
->g_id
) == 0) {
299 * check_flags - check to see if the flags contains options that are
300 * recognizable by stty
301 * - return 0 if no error. Otherwise return -1
307 struct termio termio
;
308 struct termios termios
;
309 struct termiox termiox
;
310 struct winsize winsize
;
313 char *argvp
[MAXARGS
]; /* stty args */
314 static char *binstty
= "/usr/bin/stty";
315 static char buf
[BUFSIZ
];
316 extern char *sttyparse();
317 char *s_arg
; /* this will point to invalid option */
319 /* put flags into buf, because strtok will break up buffer */
320 (void)strcpy(buf
,flags
);
321 argvp
[0] = binstty
; /* just a place holder */
322 mkargv(buf
,&argvp
[1],&cnt
,MAXARGS
-1);
323 argvp
[cnt
] = (char *)0;
326 * because we don't know what type of terminal we have now,
327 * just set term = everything, so all possible stty options
330 term
= ASYNC
|TERMIOS
|FLOW
;
331 if ((s_arg
= sttyparse(cnt
, argvp
, term
, &termio
, &termios
,
332 &termiox
, &winsize
)) != NULL
) {
333 log("invalid mode: %s", s_arg
);
340 * insert_def - insert one entry into Gdef table
347 extern struct Gdef
*find_def();
349 if (find_def(gptr
->g_id
) != NULL
) {
350 log("Warning -- duplicate entry <%s>, ignored", gptr
->g_id
);
354 tp
->g_id
= strsave(gptr
->g_id
);
355 tp
->g_iflags
= strsave(gptr
->g_iflags
);
356 tp
->g_fflags
= strsave(gptr
->g_fflags
);
357 tp
->g_autobaud
= gptr
->g_autobaud
;
358 tp
->g_nextid
= strsave(gptr
->g_nextid
);
364 * mkargv - parse the string into args, starting from args[cnt]
368 mkargv(string
,args
,cnt
,maxargs
)
369 char *string
, **args
;
372 register char *ptrin
,*ptrout
;
375 extern char quoted();
377 for (i
=0; i
< maxargs
; i
++) args
[i
] = NULL
;
378 for (ptrin
= ptrout
= string
,i
=0; *ptrin
!= '\0' && i
< maxargs
; i
++) {
379 /* Skip excess white spaces between arguments. */
380 while(*ptrin
== ' ' || *ptrin
== '\t') {
384 /* Save the address of argument if there is something there. */
385 if (*ptrin
== '\0') break;
386 else args
[i
] = ptrout
;
388 /* Span the argument itself. The '\' character causes quoting */
389 /* of the next character to take place (except for '\0'). */
390 while (*ptrin
!= '\0') {
391 if (*ptrin
== '\\') {
392 *ptrout
++ = quoted(ptrin
,&qsize
);
395 /* Is this the end of the argument? If so quit loop. */
396 } else if (*ptrin
== ' ' || *ptrin
== '\t') {
400 /* If this is a normal letter of the argument, save it, advancing */
401 /* the pointers at the same time. */
402 } else *ptrout
++ = *ptrin
++;
404 /* Null terminate the string. */
412 * dump_ttydefs - dump Gdef table to log file
420 log("********** dumping ttydefs table **********");
421 log("Ndefs = %d", Ndefs
);
423 for (i
= 0; i
< Ndefs
; i
++,gptr
++) {
424 log("----------------------------------------");
425 log("ttylabel:\t%s", gptr
->g_id
);
426 log("initial flags:\t%s", gptr
->g_iflags
);
427 log("final flags:\t%s", gptr
->g_fflags
);
428 if (gptr
->g_autobaud
& A_FLAG
)
429 log("autobaud:\tyes");
431 log("Autobaud:\tno");
432 log("nextlabel:\t%s", gptr
->g_nextid
);
435 log("********** end dumping ttydefs table **********");
442 * this is copies from uucp/strsave.c
443 * and is modified that if malloc fails, it will exit
452 if ((rval
= (char *)malloc(1)) == NULL
) {
453 log("strsave: malloc failed");
459 if ((rval
= (char *)malloc(strlen(str
) + 1)) == NULL
) {
460 log("strsave: malloc failed");
463 (void)strcpy(rval
, str
);