xref: /titanic_52/usr/src/cmd/streams/strcmd/strconf.c (revision 84ab085a13f931bc78e7415e7ce921dbaa14fcb3)
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 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.5	*/
27 /*
28  * Streams Command strconf:	display the configuration of the
29  *				stream associated with stdin.
30  *
31  * USAGE:	strconf
32  *    or:	strconf -m module
33  *    or:	strconf -t
34  *
35  * strconf with no options lists the modules on the stream.
36  * -m module	echos "yes" and returns 0 if the module is on the stream.
37  *		echos "no" and returns 2 if not.
38  * -t		lists only the topmost module.  returns 0 if there is a
39  *		module, 2 if not.
40  *
41  * RETURNS:
42  *	0	SUCCESS		it works
43  *	1	ERR_USAGE	bad invocation
44  *	2	ERR_MODULE	module not there
45  *	3	ERR_STDIN	an ioctl on the stdin stream failed
46  *	4	ERR_MEM		couldn't allocate memory
47  */
48 
49 #include	<stdio.h>
50 #include	<sys/stropts.h>
51 
52 #define	TRUE		 1
53 #define FALSE		 0
54 
55 #define	OPTLIST		"m:t"
56 #define USAGE		"USAGE: %s [ -m module | -t ]\n"
57 
58 #define SUCCESS		0
59 #define FAILURE		1
60 
61 #define	ERR_USAGE	1	/* bad invocation			*/
62 #define	ERR_MODULE	2	/* module not there			*/
63 #define	ERR_STDIN	3	/* an ioctl on the stdin stream failed	*/
64 #define	ERR_MEM		4	/* couldn't allocate memory		*/
65 
66 #define	NMODULES	16	/* "reasonable" # of modules on a stream  */
67 				/* 	(there can be more)		  */
68 #define	MAXMODULES	2048	/* max # of modules			  */
69 
70 #define	STDIN		0
71 #define	SAME		0	/* return from str[n]cmp if match	*/
72 
73 
74 static char		 *Cmd_namep;		/* how was it invoked?	*/
75 
76 
77 extern char	*strcpy();
78 extern int	getopt();
79 extern int	ioctl();
80 extern int	strncmp();
81 
82 static int	more_modules();	/* increase size of mod list		*/
83 
84 main( argc, argv)
85 int	argc;
86 char	*argv[];
87 {
88 	char		*modp;		/* ptr to module name		*/
89 	register int	i;		/* loop var & junk (what else?)	*/
90 	short		mod_present;	/* TRUE if -m module		*/
91 	short		topmost;	/* TRUE if -t			*/
92 	struct str_mlist
93 			mlist[NMODULES];/* modlist for strlist		*/
94 	struct str_list	strlist;	/* mods on stream		*/
95 
96 	extern char	*optarg;	/* for getopt()			*/
97 	extern int	optind;		/* for getopt()			*/
98 
99 	/*
100 	 *	init
101 	 */
102 	Cmd_namep = argv[0];
103 	mod_present = topmost = FALSE;
104 	strlist.sl_nmods = NMODULES;
105 	strlist.sl_modlist = mlist;
106 
107 	/*
108 	 *	parse args
109 	 */
110 	if ( argc > 1) {
111 		while ( (i = getopt( argc, argv, OPTLIST)) != -1 ) {
112 			switch( i) {
113 				case 'm':	/* module present ? */
114 					modp = optarg;
115 					mod_present = TRUE;
116 					break;
117 
118 				case 't':	/* list topmost	*/
119 					topmost = TRUE;
120 					break;
121 
122 				default:
123 					(void) fprintf(stderr, USAGE, Cmd_namep);
124 					return(ERR_USAGE);
125 			}
126 		}
127 
128 		if ( optind < argc ) {
129 			(void) fprintf(stderr, USAGE, Cmd_namep);
130 			return(ERR_USAGE);
131 		}
132 	}
133 
134 	if (topmost && mod_present) {
135 		(void) fprintf(stderr,
136 		"%s: [-t] and [-m] options cannot be used together\n", Cmd_namep);
137 		(void) fprintf(stderr, USAGE, Cmd_namep);
138 		return(ERR_USAGE);
139 	}
140 
141 	/*
142 	 * get number of modules on stream
143 	 * allocate more room if needed
144 	 */
145 	if ( (i =  ioctl(STDIN, I_LIST, (struct str_list *)NULL))
146 	 < 0 ) {
147 		perror("I_LIST");
148 		(void) fprintf(stderr,
149 			"%s: I_LIST ioctl failed\n", Cmd_namep);
150 		return(ERR_STDIN);
151 	}
152 	if ( i > strlist.sl_nmods )
153 		if ( more_modules(&strlist, i) != SUCCESS )
154 			return(ERR_MEM);
155 
156 	/*
157 	 *	get list of modules on stream
158 	 */
159 	strlist.sl_nmods = i;
160 	if ( ioctl (0, I_LIST, &strlist) < 0) {
161 		perror("I_LIST");
162 		(void) fprintf (stderr, "%s: I_LIST ioctl failed\n", Cmd_namep);
163 		return(ERR_STDIN);
164 	}
165 
166 	/*
167 	 *	list topmost module
168 	 */
169 	if ( topmost ) {
170 		if ( strlist.sl_nmods >= 2 ) {
171 			(void) printf("%s\n", strlist.sl_modlist[0].l_name);
172 			return(SUCCESS);
173 		}
174 		return(ERR_MODULE);
175 	}
176 
177 	/*
178 	 *	check if module is present
179 	 */
180 	if ( mod_present ) {
181 		for ( i = 0; i < strlist.sl_nmods; i++ ) {
182 			if ( strncmp(modp, strlist.sl_modlist[i].l_name,
183 							FMNAMESZ) == SAME ) {
184 				(void) printf("yes\n");
185 				return(SUCCESS);
186 			}
187 		}
188 		(void) printf("no\n");
189 		return(ERR_MODULE);
190 	}
191 
192 	/*
193 	 *	print names of all modules and topmost driver on stream
194 	 */
195 	for ( i = 0; i < strlist.sl_nmods; i++ )
196 		(void) printf("%s\n", strlist.sl_modlist[i].l_name);
197 	return(SUCCESS);
198 }
199 
200 /*
201  * more_modules(listp, n)	allocate space for 'n' modules in 'listp'
202  *
203  * returns:	SUCCESS or FAILURE
204  */
205 
206 static int
207 more_modules(listp, n)
208 struct str_list	*listp;		/* streams module list	*/
209 int		n;		/* # of modules		*/
210 {
211 	register int			i;
212 	register struct str_mlist	*modp;
213 
214 	extern char	*calloc();
215 
216 	if ( n > MAXMODULES ) {
217 		(void) fprintf(stderr,
218 			"%s: too many modules (%d) -- max is %d\n",
219 			Cmd_namep, n, MAXMODULES);
220 		return(FAILURE);
221 	}
222 
223 	if ( (modp = (struct str_mlist *)calloc((unsigned)n,
224 	(unsigned)sizeof(struct str_mlist))) == (struct str_mlist *)NULL ) {
225 		perror("calloc");
226 		(void) fprintf(stderr,
227 			"%s: failed to allocate space for module list\n",
228 			Cmd_namep);
229 		return(FAILURE);
230 	}
231 
232 	for ( i = 0; i < listp->sl_nmods; ++i )
233 		(void) strncpy(modp[i].l_name, listp->sl_modlist[i].l_name,
234 			FMNAMESZ);
235 	listp->sl_nmods = n;
236 	listp->sl_modlist = modp;
237 	return(SUCCESS);
238 }
239