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 2005 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"
33 * Implements the main body of the "getdgrp" command.
35 #include <sys/types.h>
47 * TRUE Boolean TRUE value
48 * FALSE Boolean FALSE value
63 * EX_OK All's well that ends well
64 * EX_ERROR Some other error occurred
65 * EX_DTAB Device table couldn't be opened
66 * EX_DGRP Device-group table couldn't be open.
77 * M_USAGE Command usage error
78 * M_ERROR Some unexpected error
79 * M_DEVTAB Device table couldn't be opened
80 * M_DGROUP Device-group table couldn't be opened
83 #define M_USAGE "usage: getdgrp [-ael] [criterion [...]] [dgroup [...]]"
84 #define M_ERROR "Internal error, errno=%d"
85 #define M_DEVTAB "Cannot open the device table: %s"
86 #define M_DGROUP "Cannot open the device-group table: %s"
91 * buildcriterialist() Builds a list of the criteria on the
93 * buildgrouplist() Builds a list of the device-groups mentioned
97 static char **buildcriterialist(); /* Builds criteria list from command line */
98 static char **builddgrouplist(); /* Builds dgroup list from command line */
103 * stdmsg(r,l,s,t) Generate a standard message
104 * r Recoverability flag
108 * isacriterion(p) Returns TRUE if *p is a criterion, FALSE otherwise
111 #define stdmsg(r,l,s,t) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG)
112 #define isacriterion(p) (strchr(*arglist,'=')||strchr(*arglist,':'))
117 * lbl Buffer for standard message label
118 * txt Buffer for standard message text
121 static char lbl
[MM_MXLABELLN
+1];
122 static char txt
[MM_MXTXTLN
+1];
125 * getdgrp [-ael] [criterion [...]] [dgroup [...]]
127 * This function gets the device groups that contain as members devices
128 * that match the given criteria.
131 * -a A device must meet all criteria before the device-group in
132 * which it is a member can be selected for inclusion in the
133 * generated list. If this option is missing, a device must
134 * meet at least one criterion before it's group can be
135 * selected. This option has no affect if there are no criterion
136 * on the command-line.
137 * -e The list of device groups specifies groups to exclude from
138 * the generated list. If this option is omitted, the list
139 * of groups is the set of groups that can be selected. This
140 * option has no effect if there are no device-groups on the
142 * -l List all device groups, even those that have no valid
143 * members (this option has no effect if criterion are specified
146 * criterion A device criterion of the form <attr><op><val> where
147 * <attr> is the name of an attribute, <op> is "=", "!=",
148 * ":", or "!:" for "is equal to", "is not equal to",
149 * "is defined," or "is not defined." <val> is the value
150 * that the attribute must be equal to or not equal to.
151 * (<val> must be "*" if <op> is ":" or "!:").
152 * dgroup A device group that is to be exclude selected for the
153 * generated list or excluded from the the generated
158 * 1 Usage or an internal error
159 * 2 The device table or the device-group table could not be
164 main(int argc
, char **argv
)
171 char **arglist
; /* List of arguments (subset of argv) */
172 char **criterialist
; /* List of criteria */
173 char **dgrouplist
; /* List of device groups to search or ignore */
174 char **fitgrouplist
; /* List of device groups that fit criteria */
175 char *cmdname
; /* Simple command name */
176 char *dgroup
; /* Pointer to device group name in list */
177 char *filename
; /* Pointer to filename in "error" */
178 int exitcode
; /* Value to return to the caller */
179 int sev
; /* Message severity */
180 int optchar
; /* Option character (returned by getopt()) */
181 int andflag
; /* TRUE if anding criteria, FALSE if or'ed */
182 int excludeflag
; /* TRUE if the dgroups list those to exclude */
183 int allflag
; /* TRUE if all device grps are to be displayed */
184 int options
; /* Options to pass to getdgrp() */
185 int usageerr
; /* TRUE if syntax error */
188 /* Build the message label from the (simple) command name */
189 if (cmdname
= strrchr(argv
[0], '/')) cmdname
++;
190 else cmdname
= argv
[0];
191 (void) strlcat(strcpy(lbl
, "UX:"), cmdname
, sizeof(lbl
));
193 /* Only write the text-component of messages (this goes away in SVR4.1) */
194 (void) putenv("MSGVERB=text");
197 * Parse the command line:
199 * - Selection criteria
200 * - Device groups to include or exclude
204 * Extract options from the command line
207 /* Initializations */
208 andflag
= FALSE
; /* No -a */
209 excludeflag
= FALSE
; /* No -e */
210 allflag
= FALSE
; /* No -l */
211 usageerr
= FALSE
; /* No errors yet */
214 * Loop until all of the command line options have been parced
216 opterr
= FALSE
; /* Don't let getopt() write messages */
217 while ((optchar
= getopt(argc
, argv
, "ael")) != EOF
) switch (optchar
) {
219 /* -a List device groups that fit all of the criteria listed */
221 if (andflag
) usageerr
= TRUE
;
225 /* -e Exclude those device groups mentioned on the command line */
227 if (excludeflag
) usageerr
= TRUE
;
228 else excludeflag
= TRUE
;
231 /* -l List all device groups (if no criteria is specified) */
233 if (allflag
) usageerr
= TRUE
;
237 /* Default case -- command usage error */
244 /* If there is a usage error, write an appropriate message and exit */
246 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, M_USAGE
);
250 /* Open the device file (if there's one to be opened) */
251 if (!_opendevtab("r")) {
252 if (filename
= _devtabpath()) {
253 (void) snprintf(txt
, sizeof(txt
), M_DEVTAB
, filename
);
257 (void) sprintf(txt
, M_ERROR
, errno
);
261 stdmsg(MM_NRECOV
, lbl
, sev
, txt
);
265 /* Open the device file (if there's one to be opened) */
266 if (!_opendgrptab("r")) {
267 if (filename
= _dgrptabpath()) {
268 (void) snprintf(txt
, sizeof(txt
), M_DGROUP
, filename
);
272 (void) sprintf(txt
, M_ERROR
, errno
);
276 stdmsg(MM_NRECOV
, lbl
, sev
, txt
);
280 /* Build the list of criteria and device groups */
281 arglist
= argv
+ optind
;
282 criterialist
= buildcriterialist(arglist
);
283 dgrouplist
= builddgrouplist(arglist
);
284 options
= (excludeflag
? DTAB_EXCLUDEFLAG
: 0) |
285 (andflag
? DTAB_ANDCRITERIA
: 0) |
286 (allflag
? DTAB_LISTALL
: 0) ;
289 * Get the list of device groups that meets the criteria requested.
290 * If we got a list (that might be empty), write that list to the
291 * standard output file (stdout).
295 if (!(fitgrouplist
= getdgrp(dgrouplist
, criterialist
, options
))) {
298 else for (dgroup
= *fitgrouplist
++ ; dgroup
; dgroup
= *fitgrouplist
++)
306 * char **buildcriterialist(arglist)
309 * This function builds a list of criteria descriptions from the
310 * list of arguments given. The list returned is in malloc()ed
314 * arglist The address of the first element in the list
315 * of arguments (possibly) containing criterion
318 * A pointer to the first element in the list of criterion.
319 * If there was a problem, the function returns (char **) NULL.
320 * If there are no criteria in the list, the function returns
325 buildcriterialist(arglist
)
326 char **arglist
; /* Pointer to the list of argument pointers */
332 char **pp
; /* Pointer to a criteria */
333 void *allocbuf
; /* Pointer to the allocated data */
334 int ncriteria
; /* Number of criteria found */
338 * Search the argument list, looking for the end of the list or
339 * the first thing that's not a criteria. (A criteria is a
340 * character-string that contains a colon (':') or an equal-sign ('=')
345 while (*pp
&& (strchr(*pp
, '=') || strchr(*pp
, ':'))) {
350 /* Allocate space for the list of criteria pointers */
351 if (allocbuf
= malloc(ncriteria
*sizeof(char **))) {
353 /* Build the list of criteria arguments */
354 pp
= (char **) allocbuf
;
355 while ((*arglist
!= (char *) NULL
) && isacriterion(*arglist
)) *pp
++ = *arglist
++;
359 return ((char **) allocbuf
);
363 * char **builddgrouplist(arglist)
366 * This function returns a pointer to the first element in a list of
367 * device-groups (i.e. not criteria) specified in the list of arguments
368 * whose first element is pointed to by <arglist>.
371 * arglist The address of the first element in the list of
372 * arguments to be searched for non-criteria
375 * The address of the first item in the list of arguments that are
376 * not criteria. If none, the function returns a pointer to a
380 * - The current implementation returns a pointer to an element in
385 builddgrouplist(arglist
)
386 char **arglist
; /* First item in the list of arguments */
393 * Search the argument list, looking for the end of the list or
394 * the first thing that's not a criteria. It is the first device
395 * group in the list of device groups (if any).
398 while (*arglist
&& isacriterion(*arglist
)) arglist
++;
400 /* Return a pointer to the argument list. */