xref: /onnv-gate/usr/src/lib/libadm/common/getdgrp.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright (c) 1997, by Sun Microsystems, Inc.
28*0Sstevel@tonic-gate  * All rights reserved.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate /*LINTLIBRARY*/
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  *  getdgrp.c
37*0Sstevel@tonic-gate  *
38*0Sstevel@tonic-gate  * Contains the following global functions:
39*0Sstevel@tonic-gate  *	getdgrp()	Get the device groups that meet certain criteria.
40*0Sstevel@tonic-gate  */
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /*
43*0Sstevel@tonic-gate  *  Header Files Referenced
44*0Sstevel@tonic-gate  *	<sys/types.h>		Data Types
45*0Sstevel@tonic-gate  *	<stdio.h>		Standard I/O definitions
46*0Sstevel@tonic-gate  *	<string.h>		Character-string definitions
47*0Sstevel@tonic-gate  *	<devmgmt.h>		Definitions for accessing device table files
48*0Sstevel@tonic-gate  *	"devtab.h"		Local definitions for device tables
49*0Sstevel@tonic-gate  */
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate #include	<sys/types.h>
52*0Sstevel@tonic-gate #include	<stdio.h>
53*0Sstevel@tonic-gate #include	<string.h>
54*0Sstevel@tonic-gate #include	<stdlib.h>
55*0Sstevel@tonic-gate #include	<devmgmt.h>
56*0Sstevel@tonic-gate #include	"devtab.h"
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate /*
59*0Sstevel@tonic-gate  *  Local definitions
60*0Sstevel@tonic-gate  *	struct dgrplist		Structure that makes up the internal device
61*0Sstevel@tonic-gate  *				group list
62*0Sstevel@tonic-gate  *				Members:
63*0Sstevel@tonic-gate  *				    name	Name of the device group
64*0Sstevel@tonic-gate  *				    next	Pointer to the next in the list
65*0Sstevel@tonic-gate  */
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate struct dgrplist {
68*0Sstevel@tonic-gate 	char			*name;
69*0Sstevel@tonic-gate 	struct dgrplist		*next;
70*0Sstevel@tonic-gate };
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate /*
74*0Sstevel@tonic-gate  *  Local functions
75*0Sstevel@tonic-gate  *	initdgrplist		Initialize the internal device group list
76*0Sstevel@tonic-gate  *	addtodgrplist		Add a device group to the device group list
77*0Sstevel@tonic-gate  *	isindevlist		Does the device group contain a device?
78*0Sstevel@tonic-gate  *	isincallerslist		Is a device group in the caller's list?
79*0Sstevel@tonic-gate  *	buildreturnlist		Build list of device groups to return
80*0Sstevel@tonic-gate  *	freedgrplist		Free the internal device group list
81*0Sstevel@tonic-gate  */
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate static	void	initdgrplist(void);
84*0Sstevel@tonic-gate static	int	addtodgrplist(struct dgrptabent *);
85*0Sstevel@tonic-gate static	int	isindevlist(struct dgrptabent *, char **);
86*0Sstevel@tonic-gate static	int	isincallerslist(struct dgrptabent *, char **);
87*0Sstevel@tonic-gate static	char	**buildreturnlist(void);
88*0Sstevel@tonic-gate static	void	freedgrplist(void);
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate /*
92*0Sstevel@tonic-gate  *  Local data
93*0Sstevel@tonic-gate  *	dgrplistfirst	First (dummy) node in the device group list
94*0Sstevel@tonic-gate  *	dgrplistcount	Number of items in the device group list
95*0Sstevel@tonic-gate  */
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate static	struct dgrplist	dgrplistfirst;
98*0Sstevel@tonic-gate static	int		dgrplistcount;
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate /*
101*0Sstevel@tonic-gate  * char **getdgrp(dgroups, criteria, options)
102*0Sstevel@tonic-gate  *	char  **dgroups
103*0Sstevel@tonic-gate  *	char  **criteria
104*0Sstevel@tonic-gate  *	int	options
105*0Sstevel@tonic-gate  *
106*0Sstevel@tonic-gate  *	This function compiles a list of device groups containing devices
107*0Sstevel@tonic-gate  *	that meet certain criteria and returns a pointer to the first
108*0Sstevel@tonic-gate  *	item in that list.
109*0Sstevel@tonic-gate  *
110*0Sstevel@tonic-gate  *  Arguments:
111*0Sstevel@tonic-gate  *	dgroups		The list of device groups to choose from or the list
112*0Sstevel@tonic-gate  *			of device groups to exclude from the list (depends on
113*0Sstevel@tonic-gate  *			"options"
114*0Sstevel@tonic-gate  *	criteria	The criteria that a device must meet
115*0Sstevel@tonic-gate  *	options		Indicates 1) whether to "and" the criteria or to "or"
116*0Sstevel@tonic-gate  *			the criteria, 2) indicates whether to limit the
117*0Sstevel@tonic-gate  *			generated list to "dgroups" or to exclude those
118*0Sstevel@tonic-gate  *			device-groups from the list, 3) to list all device
119*0Sstevel@tonic-gate  *			groups even if they don't contain valid devices.
120*0Sstevel@tonic-gate  *
121*0Sstevel@tonic-gate  *  Returns:  char **
122*0Sstevel@tonic-gate  *	A pointer to the first address in the list of addresses of generated
123*0Sstevel@tonic-gate  *	device groups
124*0Sstevel@tonic-gate  */
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate char **
getdgrp(char ** dgroups,char ** criteria,int options)127*0Sstevel@tonic-gate getdgrp(
128*0Sstevel@tonic-gate 	char	**dgroups,	/* List of device groups */
129*0Sstevel@tonic-gate 	char	**criteria,	/* List of criteria to meet */
130*0Sstevel@tonic-gate 	int	options)	/* Options governing the search */
131*0Sstevel@tonic-gate {
132*0Sstevel@tonic-gate 	/*  Automatic data  */
133*0Sstevel@tonic-gate 	char			**devlist;	/* Devices that meet criteria */
134*0Sstevel@tonic-gate 	char			**plist;	/* Device groups to return */
135*0Sstevel@tonic-gate 	struct dgrptabent	*dgrp;		/* Dgrp information struct */
136*0Sstevel@tonic-gate 	int			errorflag;	/* TRUE if error occurred */
137*0Sstevel@tonic-gate 	int listallflag; /* TRUE if DTAB_LISTALL && (!criteria || !*criteria) */
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	/*
141*0Sstevel@tonic-gate 	 *  Open the device-group table if needed
142*0Sstevel@tonic-gate 	 */
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate 	if (!oam_dgroup && !_opendgrptab("r"))
145*0Sstevel@tonic-gate 		return (NULL);
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	/*
149*0Sstevel@tonic-gate 	 *  Get the list of devices that meet the criteria specified
150*0Sstevel@tonic-gate 	 *  This step can be skipped if DTAB_LISTALL is requested and
151*0Sstevel@tonic-gate 	 *  there is no criteria list.
152*0Sstevel@tonic-gate 	 */
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 	if (((options & DTAB_LISTALL) == 0) || (criteria && *criteria)) {
155*0Sstevel@tonic-gate 	    devlist = getdev(NULL, criteria, (options & DTAB_ANDCRITERIA));
156*0Sstevel@tonic-gate 	    listallflag = FALSE;
157*0Sstevel@tonic-gate 	} else {
158*0Sstevel@tonic-gate 	    devlist = NULL;
159*0Sstevel@tonic-gate 	    listallflag = TRUE;
160*0Sstevel@tonic-gate 	}
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate 	/*
164*0Sstevel@tonic-gate 	 *  Initialize the device group list (contains the device groups
165*0Sstevel@tonic-gate 	 *  we're accumulating)
166*0Sstevel@tonic-gate 	 */
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 	errorflag = FALSE;
169*0Sstevel@tonic-gate 	initdgrplist();
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 	/*
173*0Sstevel@tonic-gate 	 *  If no device groups were specified by the caller, accumulate all
174*0Sstevel@tonic-gate 	 *  device groups
175*0Sstevel@tonic-gate 	 */
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	_setdgrptab();
178*0Sstevel@tonic-gate 	if (!dgroups || !(*dgroups)) {
179*0Sstevel@tonic-gate 	    while (!errorflag && (dgrp = _getdgrptabent())) {
180*0Sstevel@tonic-gate 		if (!dgrp->comment && (listallflag ||
181*0Sstevel@tonic-gate 		    isindevlist(dgrp, devlist)))
182*0Sstevel@tonic-gate 		    errorflag = !addtodgrplist(dgrp);
183*0Sstevel@tonic-gate 		_freedgrptabent(dgrp);
184*0Sstevel@tonic-gate 	    }
185*0Sstevel@tonic-gate 	}
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 	else {
188*0Sstevel@tonic-gate 
189*0Sstevel@tonic-gate 	/*
190*0Sstevel@tonic-gate 	 *  If the exclusion flag is not set, build a list of device
191*0Sstevel@tonic-gate 	 *  groups that is a subset of those specified by the caller
192*0Sstevel@tonic-gate 	 */
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 	    if ((options & DTAB_EXCLUDEFLAG) == 0) {
195*0Sstevel@tonic-gate 		while (!errorflag && (dgrp = _getdgrptabent())) {
196*0Sstevel@tonic-gate 		    if (!dgrp->comment && isincallerslist(dgrp, dgroups) &&
197*0Sstevel@tonic-gate 			(listallflag || isindevlist(dgrp, devlist))) {
198*0Sstevel@tonic-gate 			errorflag = !addtodgrplist(dgrp);
199*0Sstevel@tonic-gate 		    }
200*0Sstevel@tonic-gate 		    _freedgrptabent(dgrp);
201*0Sstevel@tonic-gate 		}
202*0Sstevel@tonic-gate 	    }
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 		/*
205*0Sstevel@tonic-gate 		 *  If the exclusion flag is set, build a list of device groups
206*0Sstevel@tonic-gate 		 *  that meet the criteria and are not in the list of device
207*0Sstevel@tonic-gate 		 *  groups specified by the caller.
208*0Sstevel@tonic-gate 		 */
209*0Sstevel@tonic-gate 	    else {
210*0Sstevel@tonic-gate 		while (!errorflag && (dgrp = _getdgrptabent())) {
211*0Sstevel@tonic-gate 		    if (!dgrp->comment && !isincallerslist(dgrp, dgroups) &&
212*0Sstevel@tonic-gate 			(listallflag || isindevlist(dgrp, devlist))) {
213*0Sstevel@tonic-gate 			errorflag = !addtodgrplist(dgrp);
214*0Sstevel@tonic-gate 		    }
215*0Sstevel@tonic-gate 		    _freedgrptabent(dgrp);
216*0Sstevel@tonic-gate 		}
217*0Sstevel@tonic-gate 	    }
218*0Sstevel@tonic-gate 	}
219*0Sstevel@tonic-gate 	plist = buildreturnlist();
220*0Sstevel@tonic-gate 	freedgrplist();
221*0Sstevel@tonic-gate 	_enddgrptab();
222*0Sstevel@tonic-gate 	return (plist);
223*0Sstevel@tonic-gate }
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate /*
226*0Sstevel@tonic-gate  *  int initdgrplist()
227*0Sstevel@tonic-gate  *
228*0Sstevel@tonic-gate  *	Initializes the internal device group linked list
229*0Sstevel@tonic-gate  *
230*0Sstevel@tonic-gate  *  Arguments:  None
231*0Sstevel@tonic-gate  *
232*0Sstevel@tonic-gate  *  Returns:  void
233*0Sstevel@tonic-gate  */
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate static void
initdgrplist(void)236*0Sstevel@tonic-gate initdgrplist(void)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate 	/*  Automatic data  */
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 	/*
241*0Sstevel@tonic-gate 	 *  Initialize the structure.  Dummy node points to nothing, count to
242*0Sstevel@tonic-gate 	 * zero.
243*0Sstevel@tonic-gate 	 */
244*0Sstevel@tonic-gate 	dgrplistcount = 0;
245*0Sstevel@tonic-gate 	dgrplistfirst.name = "";
246*0Sstevel@tonic-gate 	dgrplistfirst.next = NULL;
247*0Sstevel@tonic-gate }
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate /*
250*0Sstevel@tonic-gate  *  int addtodgrplist(dgrp)
251*0Sstevel@tonic-gate  *	struct dgrptabent *dgrp
252*0Sstevel@tonic-gate  *
253*0Sstevel@tonic-gate  *	Adds the device group described by the "dgrp" structure to the
254*0Sstevel@tonic-gate  *	internal list of device-groups we're accumulating.
255*0Sstevel@tonic-gate  *
256*0Sstevel@tonic-gate  *  Arguments:
257*0Sstevel@tonic-gate  *	dgrp	Describes the device-group we're adding
258*0Sstevel@tonic-gate  *
259*0Sstevel@tonic-gate  *  Returns: int
260*0Sstevel@tonic-gate  *	TRUE if successful, FALSE otherwise
261*0Sstevel@tonic-gate  */
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate static int
addtodgrplist(struct dgrptabent * dgrp)264*0Sstevel@tonic-gate addtodgrplist(struct dgrptabent *dgrp)
265*0Sstevel@tonic-gate {
266*0Sstevel@tonic-gate 	/*  Automatic data  */
267*0Sstevel@tonic-gate 	struct dgrplist *newnode;	/* Allocated node */
268*0Sstevel@tonic-gate 	struct dgrplist	*p;		/* Running dgrp list ptr */
269*0Sstevel@tonic-gate 	struct dgrplist	*q;		/* Another Running dgrp list ptr */
270*0Sstevel@tonic-gate 	char		*newstr;	/* Space for the dgroup name */
271*0Sstevel@tonic-gate 	int		errorflag;	/* TRUE if error */
272*0Sstevel@tonic-gate 	int		cmpval;		/* Value from strcmp() */
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 	/*  No errors seen yet  */
275*0Sstevel@tonic-gate 	errorflag = FALSE;
276*0Sstevel@tonic-gate 
277*0Sstevel@tonic-gate 	/*  Find where we're supposed to insert this item in the list  */
278*0Sstevel@tonic-gate 	q = &dgrplistfirst;
279*0Sstevel@tonic-gate 	p = q->next;
280*0Sstevel@tonic-gate 	while (p && ((cmpval = strcmp(p->name, dgrp->name)) < 0)) {
281*0Sstevel@tonic-gate 	    q = p;
282*0Sstevel@tonic-gate 	    p = p->next;
283*0Sstevel@tonic-gate 	}
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	/*  If the item isn't already in the list, insert it  */
286*0Sstevel@tonic-gate 	if ((p == NULL) || (cmpval != 0)) {
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate 	    /* Allocate space for the structure */
289*0Sstevel@tonic-gate 	    newnode = malloc(sizeof (struct dgrplist));
290*0Sstevel@tonic-gate 	    if (newnode) {
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 		/* Allocate space for the device group name */
293*0Sstevel@tonic-gate 		if (newstr = malloc(strlen(dgrp->name)+1)) {
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 		    /* Link the new structure into the list */
296*0Sstevel@tonic-gate 		    newnode->name = strcpy(newstr, dgrp->name);
297*0Sstevel@tonic-gate 		    newnode->next = p;
298*0Sstevel@tonic-gate 		    q->next = newnode;
299*0Sstevel@tonic-gate 		    dgrplistcount++;
300*0Sstevel@tonic-gate 		} else {
301*0Sstevel@tonic-gate 		    /* No space for the string.  Clean up */
302*0Sstevel@tonic-gate 		    errorflag = TRUE;
303*0Sstevel@tonic-gate 		    free(newnode);
304*0Sstevel@tonic-gate 		}
305*0Sstevel@tonic-gate 	    } else errorflag = TRUE;
306*0Sstevel@tonic-gate 	}
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate 	/* Return a value that indicates whether we've had an error */
309*0Sstevel@tonic-gate 	return (!errorflag);
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate /*
313*0Sstevel@tonic-gate  *  int isindevlist(dgrp, devlist)
314*0Sstevel@tonic-gate  *	struct dgrptabent *dgrp
315*0Sstevel@tonic-gate  *	char		 **devlist
316*0Sstevel@tonic-gate  *
317*0Sstevel@tonic-gate  *	This function searches the device membership list of the device
318*0Sstevel@tonic-gate  *	group <dgrp> for any of the devices listed in the list of devices
319*0Sstevel@tonic-gate  *	<devlist>.  It returns TRUE if at least one device in <devlist> is
320*0Sstevel@tonic-gate  *	found in <dgrp>, otherwise it returns false.
321*0Sstevel@tonic-gate  *
322*0Sstevel@tonic-gate  *  Arguments:
323*0Sstevel@tonic-gate  *	dgrp		The device group to examine
324*0Sstevel@tonic-gate  *	devlist		The list of devices to search for
325*0Sstevel@tonic-gate  *
326*0Sstevel@tonic-gate  *  Returns:  int
327*0Sstevel@tonic-gate  *	TRUE if one of the devices in <devlist> is a member of the device
328*0Sstevel@tonic-gate  *	group <dgrp>, FALSE otherwise
329*0Sstevel@tonic-gate  */
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate static int
isindevlist(struct dgrptabent * dgrp,char ** devlist)332*0Sstevel@tonic-gate isindevlist(
333*0Sstevel@tonic-gate 	struct dgrptabent *dgrp,	/* Dgrp to search for */
334*0Sstevel@tonic-gate 	char		**devlist)	/* List of devices to search against */
335*0Sstevel@tonic-gate {
336*0Sstevel@tonic-gate 	/*  Automatic data  */
337*0Sstevel@tonic-gate 	struct member *pmbr;	/* Next member of the dgrp list */
338*0Sstevel@tonic-gate 	char **pdev;		/* Next device in the dev list */
339*0Sstevel@tonic-gate 	char *mbralias;		/* The alias of a group member */
340*0Sstevel@tonic-gate 	int cmpval;		/* strcmp() result */
341*0Sstevel@tonic-gate 	int notfound;		/* TRUE if no mbr of dgrp is in dev list */
342*0Sstevel@tonic-gate 	int allocflag;		/* TRUE if the mbralias string is malloc()ed */
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	/*
346*0Sstevel@tonic-gate 	 *  For each device in the device group, search the alphabetically
347*0Sstevel@tonic-gate 	 *  sorted list of devices for that device.
348*0Sstevel@tonic-gate 	 */
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate 	notfound = TRUE;
351*0Sstevel@tonic-gate 	for (pmbr = dgrp->membership; notfound && pmbr; pmbr = pmbr->next) {
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate 	/*
354*0Sstevel@tonic-gate 	 * Get the member's alias (we've got it if the member is not a
355*0Sstevel@tonic-gate 	 * pathname)
356*0Sstevel@tonic-gate 	 */
357*0Sstevel@tonic-gate 	    allocflag = (*pmbr->name == '/');
358*0Sstevel@tonic-gate 	    if (allocflag)
359*0Sstevel@tonic-gate 		mbralias = devattr(pmbr->name, DTAB_ALIAS);
360*0Sstevel@tonic-gate 	    else mbralias = pmbr->name;
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 	    /* If we've got a member alias, search the device list for it */
363*0Sstevel@tonic-gate 	    if (mbralias)
364*0Sstevel@tonic-gate 		for (pdev = devlist; notfound && *pdev; pdev++)
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 		if ((cmpval = strcmp(mbralias, *pdev)) == 0) notfound = FALSE;
367*0Sstevel@tonic-gate 		else if (cmpval < 0)
368*0Sstevel@tonic-gate 			break;	/* Optimization:  alpha sorted list */
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 		/*
371*0Sstevel@tonic-gate 		 * Free the space allocated to the member alias
372*0Sstevel@tonic-gate 		 * (if it was allocated above by devattr())
373*0Sstevel@tonic-gate 		 */
374*0Sstevel@tonic-gate 	    if (allocflag) free(mbralias);
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 	}
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 	/*
380*0Sstevel@tonic-gate 	 *  Return a value indicating that we the device group contains
381*0Sstevel@tonic-gate 	 *  a member that is in the list of devices
382*0Sstevel@tonic-gate 	 */
383*0Sstevel@tonic-gate 
384*0Sstevel@tonic-gate 	return (!notfound);
385*0Sstevel@tonic-gate }
386*0Sstevel@tonic-gate 
387*0Sstevel@tonic-gate /*
388*0Sstevel@tonic-gate  * int isincallerslist(dgrp, dgroups)
389*0Sstevel@tonic-gate  *	struct dgrptabent *dgrp
390*0Sstevel@tonic-gate  *	char		 **dgroups
391*0Sstevel@tonic-gate  *
392*0Sstevel@tonic-gate  *	This function looks through the "dgroups" list for the device
393*0Sstevel@tonic-gate  *	group described by "dgrp"
394*0Sstevel@tonic-gate  *
395*0Sstevel@tonic-gate  *  Arguments:
396*0Sstevel@tonic-gate  *	dgrp		Device group to search for
397*0Sstevel@tonic-gate  *	dgroups		The address of the first item in the list of device
398*0Sstevel@tonic-gate  *			groups to search
399*0Sstevel@tonic-gate  *
400*0Sstevel@tonic-gate  *  Returns:  int
401*0Sstevel@tonic-gate  *	TRUE if found, FALSE otherwise
402*0Sstevel@tonic-gate  */
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate static int
isincallerslist(struct dgrptabent * dgrp,char ** dgroups)405*0Sstevel@tonic-gate isincallerslist(
406*0Sstevel@tonic-gate 	struct dgrptabent *dgrp,	/* Dgrp to search for */
407*0Sstevel@tonic-gate 	char		**dgroups)	/* Caller's list of dgroups */
408*0Sstevel@tonic-gate {
409*0Sstevel@tonic-gate 	/*  Automatic data  */
410*0Sstevel@tonic-gate 	char		**pdgrp;
411*0Sstevel@tonic-gate 	int		notfound;
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	/*
414*0Sstevel@tonic-gate 	 *  Search the list of device groups for the name of the device group
415*0Sstevel@tonic-gate 	 *  in the structure described by <dgrp>.
416*0Sstevel@tonic-gate 	 */
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate 	/*  Initializations  */
419*0Sstevel@tonic-gate 	notfound = TRUE;
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	/*  Search the device group list for name of this device group  */
422*0Sstevel@tonic-gate 	for (pdgrp = dgroups; notfound && *pdgrp; pdgrp++) {
423*0Sstevel@tonic-gate 	    if (strcmp(dgrp->name, *pdgrp) == 0) notfound = FALSE;
424*0Sstevel@tonic-gate 	}
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 	/*  Return TRUE if the device group is in the list, FALSE otherwise  */
427*0Sstevel@tonic-gate 	return (!notfound);
428*0Sstevel@tonic-gate }
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate /*
431*0Sstevel@tonic-gate  *  char **buildreturnlist()
432*0Sstevel@tonic-gate  *
433*0Sstevel@tonic-gate  *	This function builds the list of pointers to device groups
434*0Sstevel@tonic-gate  *	to return to the caller from the linked list of device-groups
435*0Sstevel@tonic-gate  *	we've been accumulating.
436*0Sstevel@tonic-gate  *
437*0Sstevel@tonic-gate  *  Arguments:  none
438*0Sstevel@tonic-gate  *
439*0Sstevel@tonic-gate  *  Returns: char **
440*0Sstevel@tonic-gate  *	A pointer to the first element in the malloc()ed list of pointers
441*0Sstevel@tonic-gate  *	to malloc()ed character strings containing device groups which have
442*0Sstevel@tonic-gate  *	member devices which match the criteria
443*0Sstevel@tonic-gate  */
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate static char **
buildreturnlist(void)446*0Sstevel@tonic-gate buildreturnlist(void)
447*0Sstevel@tonic-gate {
448*0Sstevel@tonic-gate 	char		**list;		/* List being built */
449*0Sstevel@tonic-gate 	char		**pp;		/* Temp ptr within list */
450*0Sstevel@tonic-gate 	struct dgrplist	*pdgrpent;	/* Ptr into list of dgrps to return */
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate 	/*  Allocate space for the list of pointers to device groups */
453*0Sstevel@tonic-gate 	list = malloc((dgrplistcount+1)*sizeof (char *));
454*0Sstevel@tonic-gate 
455*0Sstevel@tonic-gate 	/*
456*0Sstevel@tonic-gate 	 *  For each item in the device group list, put an entry in the
457*0Sstevel@tonic-gate 	 *  list of names we're building
458*0Sstevel@tonic-gate 	 */
459*0Sstevel@tonic-gate 	if ((pp = list) != NULL) {
460*0Sstevel@tonic-gate 	    for (pdgrpent = dgrplistfirst.next; pdgrpent;
461*0Sstevel@tonic-gate 		pdgrpent = pdgrpent->next) {
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 		*pp++ = pdgrpent->name;
464*0Sstevel@tonic-gate 	    }
465*0Sstevel@tonic-gate 	    /*  The list ends with a null pointer  */
466*0Sstevel@tonic-gate 	    *pp = NULL;
467*0Sstevel@tonic-gate 	}
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 	/*  Return a pointer to the allocated list  */
470*0Sstevel@tonic-gate 	return (list);
471*0Sstevel@tonic-gate }
472*0Sstevel@tonic-gate 
473*0Sstevel@tonic-gate /*
474*0Sstevel@tonic-gate  *  void freedgrplist()
475*0Sstevel@tonic-gate  *
476*0Sstevel@tonic-gate  *	This function frees the resources allocated to the internal
477*0Sstevel@tonic-gate  *	linked list of device groups
478*0Sstevel@tonic-gate  *
479*0Sstevel@tonic-gate  *  Arguments:  none
480*0Sstevel@tonic-gate  *
481*0Sstevel@tonic-gate  *  Returns:  void
482*0Sstevel@tonic-gate  */
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate static void
freedgrplist(void)485*0Sstevel@tonic-gate freedgrplist(void)
486*0Sstevel@tonic-gate {
487*0Sstevel@tonic-gate 	struct dgrplist		*pdgrpent;	/* Dgrp to free */
488*0Sstevel@tonic-gate 	struct dgrplist		*nextnode;	/* Next one to free */
489*0Sstevel@tonic-gate 
490*0Sstevel@tonic-gate 	for (pdgrpent = dgrplistfirst.next; pdgrpent; pdgrpent = nextnode) {
491*0Sstevel@tonic-gate 	    nextnode = pdgrpent->next;
492*0Sstevel@tonic-gate 	    free(pdgrpent);
493*0Sstevel@tonic-gate 	}
494*0Sstevel@tonic-gate }
495