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]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright (c) 1997, by Sun Microsystems, Inc.
28 * All rights reserved.
31 #pragma ident "%Z%%M% %I% %E% SMI"
38 * Contains the following global functions:
39 * getdgrp() Get the device groups that meet certain criteria.
43 * Header Files Referenced
44 * <sys/types.h> Data Types
45 * <stdio.h> Standard I/O definitions
46 * <string.h> Character-string definitions
47 * <devmgmt.h> Definitions for accessing device table files
48 * "devtab.h" Local definitions for device tables
51 #include <sys/types.h>
60 * struct dgrplist Structure that makes up the internal device
63 * name Name of the device group
64 * next Pointer to the next in the list
69 struct dgrplist
*next
;
75 * initdgrplist Initialize the internal device group list
76 * addtodgrplist Add a device group to the device group list
77 * isindevlist Does the device group contain a device?
78 * isincallerslist Is a device group in the caller's list?
79 * buildreturnlist Build list of device groups to return
80 * freedgrplist Free the internal device group list
83 static void initdgrplist(void);
84 static int addtodgrplist(struct dgrptabent
*);
85 static int isindevlist(struct dgrptabent
*, char **);
86 static int isincallerslist(struct dgrptabent
*, char **);
87 static char **buildreturnlist(void);
88 static void freedgrplist(void);
93 * dgrplistfirst First (dummy) node in the device group list
94 * dgrplistcount Number of items in the device group list
97 static struct dgrplist dgrplistfirst
;
98 static int dgrplistcount
;
101 * char **getdgrp(dgroups, criteria, options)
106 * This function compiles a list of device groups containing devices
107 * that meet certain criteria and returns a pointer to the first
111 * dgroups The list of device groups to choose from or the list
112 * of device groups to exclude from the list (depends on
114 * criteria The criteria that a device must meet
115 * options Indicates 1) whether to "and" the criteria or to "or"
116 * the criteria, 2) indicates whether to limit the
117 * generated list to "dgroups" or to exclude those
118 * device-groups from the list, 3) to list all device
119 * groups even if they don't contain valid devices.
122 * A pointer to the first address in the list of addresses of generated
128 char **dgroups
, /* List of device groups */
129 char **criteria
, /* List of criteria to meet */
130 int options
) /* Options governing the search */
133 char **devlist
; /* Devices that meet criteria */
134 char **plist
; /* Device groups to return */
135 struct dgrptabent
*dgrp
; /* Dgrp information struct */
136 int errorflag
; /* TRUE if error occurred */
137 int listallflag
; /* TRUE if DTAB_LISTALL && (!criteria || !*criteria) */
141 * Open the device-group table if needed
144 if (!oam_dgroup
&& !_opendgrptab("r"))
149 * Get the list of devices that meet the criteria specified
150 * This step can be skipped if DTAB_LISTALL is requested and
151 * there is no criteria list.
154 if (((options
& DTAB_LISTALL
) == 0) || (criteria
&& *criteria
)) {
155 devlist
= getdev(NULL
, criteria
, (options
& DTAB_ANDCRITERIA
));
164 * Initialize the device group list (contains the device groups
165 * we're accumulating)
173 * If no device groups were specified by the caller, accumulate all
178 if (!dgroups
|| !(*dgroups
)) {
179 while (!errorflag
&& (dgrp
= _getdgrptabent())) {
180 if (!dgrp
->comment
&& (listallflag
||
181 isindevlist(dgrp
, devlist
)))
182 errorflag
= !addtodgrplist(dgrp
);
183 _freedgrptabent(dgrp
);
190 * If the exclusion flag is not set, build a list of device
191 * groups that is a subset of those specified by the caller
194 if ((options
& DTAB_EXCLUDEFLAG
) == 0) {
195 while (!errorflag
&& (dgrp
= _getdgrptabent())) {
196 if (!dgrp
->comment
&& isincallerslist(dgrp
, dgroups
) &&
197 (listallflag
|| isindevlist(dgrp
, devlist
))) {
198 errorflag
= !addtodgrplist(dgrp
);
200 _freedgrptabent(dgrp
);
205 * If the exclusion flag is set, build a list of device groups
206 * that meet the criteria and are not in the list of device
207 * groups specified by the caller.
210 while (!errorflag
&& (dgrp
= _getdgrptabent())) {
211 if (!dgrp
->comment
&& !isincallerslist(dgrp
, dgroups
) &&
212 (listallflag
|| isindevlist(dgrp
, devlist
))) {
213 errorflag
= !addtodgrplist(dgrp
);
215 _freedgrptabent(dgrp
);
219 plist
= buildreturnlist();
228 * Initializes the internal device group linked list
241 * Initialize the structure. Dummy node points to nothing, count to
245 dgrplistfirst
.name
= "";
246 dgrplistfirst
.next
= NULL
;
250 * int addtodgrplist(dgrp)
251 * struct dgrptabent *dgrp
253 * Adds the device group described by the "dgrp" structure to the
254 * internal list of device-groups we're accumulating.
257 * dgrp Describes the device-group we're adding
260 * TRUE if successful, FALSE otherwise
264 addtodgrplist(struct dgrptabent
*dgrp
)
267 struct dgrplist
*newnode
; /* Allocated node */
268 struct dgrplist
*p
; /* Running dgrp list ptr */
269 struct dgrplist
*q
; /* Another Running dgrp list ptr */
270 char *newstr
; /* Space for the dgroup name */
271 int errorflag
; /* TRUE if error */
272 int cmpval
; /* Value from strcmp() */
274 /* No errors seen yet */
277 /* Find where we're supposed to insert this item in the list */
280 while (p
&& ((cmpval
= strcmp(p
->name
, dgrp
->name
)) < 0)) {
285 /* If the item isn't already in the list, insert it */
286 if ((p
== NULL
) || (cmpval
!= 0)) {
288 /* Allocate space for the structure */
289 newnode
= malloc(sizeof (struct dgrplist
));
292 /* Allocate space for the device group name */
293 if (newstr
= malloc(strlen(dgrp
->name
)+1)) {
295 /* Link the new structure into the list */
296 newnode
->name
= strcpy(newstr
, dgrp
->name
);
301 /* No space for the string. Clean up */
305 } else errorflag
= TRUE
;
308 /* Return a value that indicates whether we've had an error */
313 * int isindevlist(dgrp, devlist)
314 * struct dgrptabent *dgrp
317 * This function searches the device membership list of the device
318 * group <dgrp> for any of the devices listed in the list of devices
319 * <devlist>. It returns TRUE if at least one device in <devlist> is
320 * found in <dgrp>, otherwise it returns false.
323 * dgrp The device group to examine
324 * devlist The list of devices to search for
327 * TRUE if one of the devices in <devlist> is a member of the device
328 * group <dgrp>, FALSE otherwise
333 struct dgrptabent
*dgrp
, /* Dgrp to search for */
334 char **devlist
) /* List of devices to search against */
337 struct member
*pmbr
; /* Next member of the dgrp list */
338 char **pdev
; /* Next device in the dev list */
339 char *mbralias
; /* The alias of a group member */
340 int cmpval
; /* strcmp() result */
341 int notfound
; /* TRUE if no mbr of dgrp is in dev list */
342 int allocflag
; /* TRUE if the mbralias string is malloc()ed */
346 * For each device in the device group, search the alphabetically
347 * sorted list of devices for that device.
351 for (pmbr
= dgrp
->membership
; notfound
&& pmbr
; pmbr
= pmbr
->next
) {
354 * Get the member's alias (we've got it if the member is not a
357 allocflag
= (*pmbr
->name
== '/');
359 mbralias
= devattr(pmbr
->name
, DTAB_ALIAS
);
360 else mbralias
= pmbr
->name
;
362 /* If we've got a member alias, search the device list for it */
364 for (pdev
= devlist
; notfound
&& *pdev
; pdev
++)
366 if ((cmpval
= strcmp(mbralias
, *pdev
)) == 0) notfound
= FALSE
;
368 break; /* Optimization: alpha sorted list */
371 * Free the space allocated to the member alias
372 * (if it was allocated above by devattr())
374 if (allocflag
) free(mbralias
);
380 * Return a value indicating that we the device group contains
381 * a member that is in the list of devices
388 * int isincallerslist(dgrp, dgroups)
389 * struct dgrptabent *dgrp
392 * This function looks through the "dgroups" list for the device
393 * group described by "dgrp"
396 * dgrp Device group to search for
397 * dgroups The address of the first item in the list of device
401 * TRUE if found, FALSE otherwise
406 struct dgrptabent
*dgrp
, /* Dgrp to search for */
407 char **dgroups
) /* Caller's list of dgroups */
414 * Search the list of device groups for the name of the device group
415 * in the structure described by <dgrp>.
418 /* Initializations */
421 /* Search the device group list for name of this device group */
422 for (pdgrp
= dgroups
; notfound
&& *pdgrp
; pdgrp
++) {
423 if (strcmp(dgrp
->name
, *pdgrp
) == 0) notfound
= FALSE
;
426 /* Return TRUE if the device group is in the list, FALSE otherwise */
431 * char **buildreturnlist()
433 * This function builds the list of pointers to device groups
434 * to return to the caller from the linked list of device-groups
435 * we've been accumulating.
440 * A pointer to the first element in the malloc()ed list of pointers
441 * to malloc()ed character strings containing device groups which have
442 * member devices which match the criteria
446 buildreturnlist(void)
448 char **list
; /* List being built */
449 char **pp
; /* Temp ptr within list */
450 struct dgrplist
*pdgrpent
; /* Ptr into list of dgrps to return */
452 /* Allocate space for the list of pointers to device groups */
453 list
= malloc((dgrplistcount
+1)*sizeof (char *));
456 * For each item in the device group list, put an entry in the
457 * list of names we're building
459 if ((pp
= list
) != NULL
) {
460 for (pdgrpent
= dgrplistfirst
.next
; pdgrpent
;
461 pdgrpent
= pdgrpent
->next
) {
463 *pp
++ = pdgrpent
->name
;
465 /* The list ends with a null pointer */
469 /* Return a pointer to the allocated list */
474 * void freedgrplist()
476 * This function frees the resources allocated to the internal
477 * linked list of device groups
487 struct dgrplist
*pdgrpent
; /* Dgrp to free */
488 struct dgrplist
*nextnode
; /* Next one to free */
490 for (pdgrpent
= dgrplistfirst
.next
; pdgrpent
; pdgrpent
= nextnode
) {
491 nextnode
= pdgrpent
->next
;