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