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