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.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
37 * getdev Writes on the standard output stream a list of devices
38 * that match certain criteria.
40 #include <sys/types.h>
52 * TRUE Boolean TRUE value
53 * FALSE Boolean FALSE value
54 * EX_OK Exit Value if all went well
55 * EX_ERROR Exit Value if an error occurred
56 * EX_DEVTAB Exit Value if the device table couldn't be opened
76 * M_DEVTAB Can't open the device table
77 * M_NODEV Device not found in the device table
78 * M_ERROR Unexpected or internal error
81 #define M_USAGE "usage: getdev [-ae] [criterion [...]] [device [...]]"
82 #define M_DEVTAB "Cannot open the device table: %s"
83 #define M_NODEV "Device not found in the device table: %s"
84 #define M_ERROR "Internal error, errno=%d"
88 * Local (Static) Definitions and macros
89 * buildcriterialist() Builds the criteria list from the command-line
90 * builddevlist() Builds the device list from the command-line
91 * lbl Buffer for the standard message label
92 * txt Buffer for the standard message text
93 * stdmsg(r,l,s,t) Write a standard message:
94 * r Recoverability flag
100 static char **buildcriterialist();
101 static char **builddevlist();
103 static char lbl
[MM_MXLABELLN
+1];
104 static char txt
[MM_MXTXTLN
+1];
106 #define stdmsg(r,l,s,t) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG)
109 * getdev [-ae] [criterion [...]] [device [...]]
111 * This command generates a list of devices that match the
112 * specified criteria.
115 * -a A device must meet all of the criteria to be
116 * included in the generated list instead of just
117 * one of the criteria (the "and" flag)
118 * -e Exclude the devices mentioned from the generated
119 * list. If this flag is omitted, the devices in the
120 * list are selected from the devices mentioned.
123 * criterion An <attr><op><value> expression that describes
124 * a device attribute.
125 * <attr> is a device attribute
126 * <op> may be = != : !: indicating equals, does not
127 * equal, is defined, and is not defined
129 * <value> is the attribute value. Currently, the only
130 * value supported for the : and !: operators
132 * device A device to select for or exclude from the generated
136 * EX_OK All went well
137 * EX_ERROR An error (syntax, internal, or resource) occurred
138 * EX_DEVTAB The device-table could not be opened for reading
142 main(int argc
, char **argv
)
149 char **arglist
; /* List of arguments */
150 char **criterialist
; /* List of criteria */
151 char **devicelist
; /* List of devices to search/ignore */
152 char **fitdevlist
; /* List of devices that fit criteria */
153 char *cmdname
; /* Simple command name */
154 char *device
; /* Device name in the list */
155 char *devtab
; /* The device table name */
156 int exitcode
; /* Value to return to the caller */
157 int sev
; /* Message severity */
158 int optchar
; /* Option character (from getopt()) */
159 int andflag
; /* TRUE if criteria are to be anded */
160 int excludeflag
; /* TRUE if exclude "devices" lists */
161 int options
; /* Options to pass to getdev() */
162 int usageerr
; /* TRUE if syntax error */
165 /* Build the message label from the (simple) command name */
166 if ((cmdname
= strrchr(argv
[0], '/')) != (char *) NULL
) cmdname
++;
167 else cmdname
= argv
[0];
168 (void) strlcat(strcpy(lbl
, "UX:"), cmdname
, sizeof(lbl
));
170 /* Write text-component of messages only (goes away in SVR4.1) */
171 (void) putenv("MSGVERB=text");
174 * Parse the command line:
176 * - Selection criteria
177 * - Devices to include or exclude
181 * Extract options from the command line
184 /* Initializations */
185 andflag
= FALSE
; /* No -a -- Or criteria data */
186 excludeflag
= FALSE
; /* No -e -- Include only mentioned devices */
187 usageerr
= FALSE
; /* No errors on the command line (yet) */
190 * Loop until all of the command line options have been parced
192 opterr
= FALSE
; /* Don't let getopt() write messages */
193 while ((optchar
= getopt(argc
, argv
, "ae")) != EOF
) switch (optchar
) {
195 /* -a List devices that fit all of the criteria listed */
197 if (andflag
) usageerr
= TRUE
;
201 /* -e Exclude those devices mentioned on the command line */
203 if (excludeflag
) usageerr
= TRUE
;
204 else excludeflag
= TRUE
;
207 /* Default case -- command usage error */
214 /* If there is a usage error, write an appropriate message and exit */
216 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, M_USAGE
);
220 /* Open the device file (if there's one to be opened) */
221 if (!_opendevtab("r")) {
222 if (devtab
= _devtabpath()) {
223 (void) snprintf(txt
, sizeof(txt
), M_DEVTAB
, devtab
);
225 exitcode
= EX_DEVTAB
;
227 (void) sprintf(txt
, M_ERROR
, errno
);
231 stdmsg(MM_NRECOV
, lbl
, sev
, txt
);
235 /* Build the list of criteria and devices */
236 arglist
= argv
+ optind
;
237 criterialist
= buildcriterialist(arglist
);
238 devicelist
= builddevlist(arglist
);
239 options
= (excludeflag
?DTAB_EXCLUDEFLAG
:0)|(andflag
?DTAB_ANDCRITERIA
:0);
242 * Get the list of devices that meets the criteria requested. If we
243 * got a list (that might be empty), write that list to the standard
244 * output file (stdout).
248 if (!(fitdevlist
= getdev(devicelist
, criterialist
, options
))) {
251 else for (device
= *fitdevlist
++ ; device
; device
= *fitdevlist
++)
259 * char **buildcriterialist(arglist)
262 * Build a list of pointers to the criterion on the command-line
265 * arglist The list of arguments on the command-line
268 * The address of the first item of the list of criterion on the
269 * command-line. This is a pointer to malloc()ed space.
273 buildcriterialist(arglist
)
274 char **arglist
; /* Pointer to the list of argument pointers */
280 char **pp
; /* Pointer to a criteria */
281 char **allocbuf
; /* Pointer to the allocated data */
282 int ncriteria
; /* Number of criteria found */
286 * Search the argument list, looking for the end of the list or
287 * the first thing that's not a criteria. (A criteria is a
288 * character-string that contains a colon (':') or an equal-sign ('=')
293 while (*pp
&& (strchr(*pp
, '=') || strchr(*pp
, ':'))) {
300 /* Allocate space for the list of criteria pointers */
301 allocbuf
= (char **) malloc((ncriteria
+1)*sizeof(char **));
304 * Build the list of criteria arguments
306 pp
= allocbuf
; /* Beginning of the list */
307 while (*arglist
&& /* If there's more to do ... */
308 (strchr(*arglist
, '=') || /* and it's a = criterion ... */
309 strchr(*arglist
, ':'))) /* or it's a : criterion ... */
310 *pp
++ = *arglist
++; /* Include it in the list */
311 *pp
= (char *) NULL
; /* Terminate the list */
313 } else allocbuf
= (char **) NULL
; /* NO criteria */
320 * char **builddevlist(arglist)
323 * Builds a list of pointers to the devices mentioned on the command-
324 * line and returns the address of that list.
327 * arglist The address of the list of arguments to the
331 * A pointer to the first item in the list of pointers to devices
332 * specified on the command-line
336 builddevlist(arglist
)
337 char **arglist
; /* Pointer to the list of pointers to args */
344 * Search the argument list, looking for the end of the list or the
345 * first thing that's not a criteria. It is the first device in the
346 * list of devices (if any).
349 while (*arglist
&& (strchr(*arglist
, '=') || strchr(*arglist
, ':'))) arglist
++;
351 /* Return a pointer to the argument list. */
352 return(*arglist
?arglist
:(char **) NULL
);