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