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" /* SVr4.0 1.4 */
32*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
33*7c478bd9Sstevel@tonic-gate
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate * getdev.c
36*7c478bd9Sstevel@tonic-gate *
37*7c478bd9Sstevel@tonic-gate * Contents:
38*7c478bd9Sstevel@tonic-gate * getdev() List devices that match certain criteria.
39*7c478bd9Sstevel@tonic-gate */
40*7c478bd9Sstevel@tonic-gate
41*7c478bd9Sstevel@tonic-gate /*
42*7c478bd9Sstevel@tonic-gate * Header files referenced:
43*7c478bd9Sstevel@tonic-gate * <sys/types.h> System Data Types
44*7c478bd9Sstevel@tonic-gate * <errno.h> Error handling
45*7c478bd9Sstevel@tonic-gate * <fcntl.h> File controlling
46*7c478bd9Sstevel@tonic-gate * <ctype.h> Character types
47*7c478bd9Sstevel@tonic-gate * <string.h> String handling
48*7c478bd9Sstevel@tonic-gate * <devmgmt.h> Global device-management def'ns
49*7c478bd9Sstevel@tonic-gate * "devtab.h" Local device-management dev'ns
50*7c478bd9Sstevel@tonic-gate */
51*7c478bd9Sstevel@tonic-gate
52*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
53*7c478bd9Sstevel@tonic-gate #include <errno.h>
54*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
55*7c478bd9Sstevel@tonic-gate #include <ctype.h>
56*7c478bd9Sstevel@tonic-gate #include <string.h>
57*7c478bd9Sstevel@tonic-gate #include <devmgmt.h>
58*7c478bd9Sstevel@tonic-gate #include "devtab.h"
59*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
60*7c478bd9Sstevel@tonic-gate
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate * Local definitions
63*7c478bd9Sstevel@tonic-gate * NULL Nil address
64*7c478bd9Sstevel@tonic-gate * TRUE Boolean TRUE
65*7c478bd9Sstevel@tonic-gate * FALSE Boolean FALSE
66*7c478bd9Sstevel@tonic-gate */
67*7c478bd9Sstevel@tonic-gate
68*7c478bd9Sstevel@tonic-gate #ifndef NULL
69*7c478bd9Sstevel@tonic-gate #define NULL 0
70*7c478bd9Sstevel@tonic-gate #endif
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate #ifndef TRUE
73*7c478bd9Sstevel@tonic-gate #define TRUE ('t')
74*7c478bd9Sstevel@tonic-gate #endif
75*7c478bd9Sstevel@tonic-gate
76*7c478bd9Sstevel@tonic-gate #ifndef FALSE
77*7c478bd9Sstevel@tonic-gate #define FALSE 0
78*7c478bd9Sstevel@tonic-gate #endif
79*7c478bd9Sstevel@tonic-gate
80*7c478bd9Sstevel@tonic-gate
81*7c478bd9Sstevel@tonic-gate /*
82*7c478bd9Sstevel@tonic-gate * Comparison values. These values are placed in the struct srch
83*7c478bd9Sstevel@tonic-gate * structure by buildsearchlist() and are used to compare values
84*7c478bd9Sstevel@tonic-gate * in matches().
85*7c478bd9Sstevel@tonic-gate * EQUAL Attribute must equal this value
86*7c478bd9Sstevel@tonic-gate * NOTEQUAL Attribute must not equal this value
87*7c478bd9Sstevel@tonic-gate * EXISTS Attribute must exist
88*7c478bd9Sstevel@tonic-gate * NOEXISTS Attribute must not exist
89*7c478bd9Sstevel@tonic-gate * IGNORE Ignore this entry
90*7c478bd9Sstevel@tonic-gate * ENDLIST This entry ends the list
91*7c478bd9Sstevel@tonic-gate */
92*7c478bd9Sstevel@tonic-gate
93*7c478bd9Sstevel@tonic-gate #define EQUAL 1
94*7c478bd9Sstevel@tonic-gate #define NOTEQUAL 2
95*7c478bd9Sstevel@tonic-gate #define EXISTS 3
96*7c478bd9Sstevel@tonic-gate #define NOEXISTS 4
97*7c478bd9Sstevel@tonic-gate #define IGNORE 5
98*7c478bd9Sstevel@tonic-gate #define ENDLIST 0
99*7c478bd9Sstevel@tonic-gate
100*7c478bd9Sstevel@tonic-gate
101*7c478bd9Sstevel@tonic-gate /*
102*7c478bd9Sstevel@tonic-gate * Structure definitions:
103*7c478bd9Sstevel@tonic-gate * deviceent Defines a device that matches criteria
104*7c478bd9Sstevel@tonic-gate * srch Describes a criteria
105*7c478bd9Sstevel@tonic-gate */
106*7c478bd9Sstevel@tonic-gate
107*7c478bd9Sstevel@tonic-gate struct deviceent {
108*7c478bd9Sstevel@tonic-gate struct deviceent *next; /* Pointer to next item in the list */
109*7c478bd9Sstevel@tonic-gate char *name; /* Presentation name of the device */
110*7c478bd9Sstevel@tonic-gate };
111*7c478bd9Sstevel@tonic-gate
112*7c478bd9Sstevel@tonic-gate struct srch {
113*7c478bd9Sstevel@tonic-gate char *name; /* Name of field to compare */
114*7c478bd9Sstevel@tonic-gate char *cmp; /* Value to compare against */
115*7c478bd9Sstevel@tonic-gate int fcn; /* Type of comparison (see above) */
116*7c478bd9Sstevel@tonic-gate };
117*7c478bd9Sstevel@tonic-gate
118*7c478bd9Sstevel@tonic-gate
119*7c478bd9Sstevel@tonic-gate /*
120*7c478bd9Sstevel@tonic-gate * Local functions referenced
121*7c478bd9Sstevel@tonic-gate * oktoaddtolist() Determines if device can be added to the
122*7c478bd9Sstevel@tonic-gate * list by examining the devices list and
123*7c478bd9Sstevel@tonic-gate * the options governing the search
124*7c478bd9Sstevel@tonic-gate * initdevicelist() Initializes the linked list of devices
125*7c478bd9Sstevel@tonic-gate * to be included in the list-to-return
126*7c478bd9Sstevel@tonic-gate * freedevicelist() Frees the resources allocated to the linked
127*7c478bd9Sstevel@tonic-gate * list of devices
128*7c478bd9Sstevel@tonic-gate * addtodevicelist() Adds an entry to the linked list of devices
129*7c478bd9Sstevel@tonic-gate * buildsearchlist() Builds a list of struct srch structures from
130*7c478bd9Sstevel@tonic-gate * the criteria strings
131*7c478bd9Sstevel@tonic-gate * freesearchlist() Frees the resources allocated to the list of
132*7c478bd9Sstevel@tonic-gate * struct srch structures
133*7c478bd9Sstevel@tonic-gate * buildreturnlist() Builds the list of devices to return from the
134*7c478bd9Sstevel@tonic-gate * linked list of devices we've accumulated
135*7c478bd9Sstevel@tonic-gate * makealiaslist() Builds a list of aliases from the list of
136*7c478bd9Sstevel@tonic-gate * devices presented by the caller
137*7c478bd9Sstevel@tonic-gate * freealiaslist() Frees the resources allocated to the list of
138*7c478bd9Sstevel@tonic-gate * devices aliases
139*7c478bd9Sstevel@tonic-gate * getnextmatch() Get the next device that matches the search
140*7c478bd9Sstevel@tonic-gate * criteria
141*7c478bd9Sstevel@tonic-gate * matchallcriteria() See if the device attributes match all of the
142*7c478bd9Sstevel@tonic-gate * search criteria
143*7c478bd9Sstevel@tonic-gate * matchanycriteria() See if the device attributes match any of the
144*7c478bd9Sstevel@tonic-gate * search criteria
145*7c478bd9Sstevel@tonic-gate * matches() See if the criteria and attribute match
146*7c478bd9Sstevel@tonic-gate */
147*7c478bd9Sstevel@tonic-gate
148*7c478bd9Sstevel@tonic-gate static char *oktoaddtolist(char *, char **, char **, int);
149*7c478bd9Sstevel@tonic-gate static void initdevicelist(void);
150*7c478bd9Sstevel@tonic-gate static void freedevicelist(void);
151*7c478bd9Sstevel@tonic-gate static int addtodevicelist(char *);
152*7c478bd9Sstevel@tonic-gate static struct srch *buildsearchlist(char **);
153*7c478bd9Sstevel@tonic-gate static void freesearchlist(struct srch *);
154*7c478bd9Sstevel@tonic-gate static char **buildreturnlist(void);
155*7c478bd9Sstevel@tonic-gate static char **makealiaslist(char **);
156*7c478bd9Sstevel@tonic-gate static void freealiaslist(char **);
157*7c478bd9Sstevel@tonic-gate static char *getnextmatch(struct srch *, int);
158*7c478bd9Sstevel@tonic-gate static int matchallcriteria(struct devtabent *, struct srch *);
159*7c478bd9Sstevel@tonic-gate static int matchanycriteria(struct devtabent *, struct srch *);
160*7c478bd9Sstevel@tonic-gate static int matches(char *, char *, int);
161*7c478bd9Sstevel@tonic-gate
162*7c478bd9Sstevel@tonic-gate
163*7c478bd9Sstevel@tonic-gate /*
164*7c478bd9Sstevel@tonic-gate * Global Data
165*7c478bd9Sstevel@tonic-gate */
166*7c478bd9Sstevel@tonic-gate
167*7c478bd9Sstevel@tonic-gate /*
168*7c478bd9Sstevel@tonic-gate * Static Data
169*7c478bd9Sstevel@tonic-gate * devicelisthead The first item (dummy) in the linked list of devices
170*7c478bd9Sstevel@tonic-gate * we're building
171*7c478bd9Sstevel@tonic-gate * devicelist Structure describing the linked list of devices
172*7c478bd9Sstevel@tonic-gate */
173*7c478bd9Sstevel@tonic-gate
174*7c478bd9Sstevel@tonic-gate static struct deviceent devicelisthead;
175*7c478bd9Sstevel@tonic-gate static struct {
176*7c478bd9Sstevel@tonic-gate struct deviceent *head;
177*7c478bd9Sstevel@tonic-gate int count;
178*7c478bd9Sstevel@tonic-gate } devicelist = {&devicelisthead, 0};
179*7c478bd9Sstevel@tonic-gate
180*7c478bd9Sstevel@tonic-gate /*
181*7c478bd9Sstevel@tonic-gate * char **getdev(devices, criteria, options)
182*7c478bd9Sstevel@tonic-gate * char **devices
183*7c478bd9Sstevel@tonic-gate * char **criteria
184*7c478bd9Sstevel@tonic-gate * int options
185*7c478bd9Sstevel@tonic-gate *
186*7c478bd9Sstevel@tonic-gate * This function builds a list of devices that match criteria,
187*7c478bd9Sstevel@tonic-gate * governed by the device list.
188*7c478bd9Sstevel@tonic-gate *
189*7c478bd9Sstevel@tonic-gate * Arguments:
190*7c478bd9Sstevel@tonic-gate * devices The list of devices to select from or the list of
191*7c478bd9Sstevel@tonic-gate * devices to exclude, depending on the value of
192*7c478bd9Sstevel@tonic-gate * "options"
193*7c478bd9Sstevel@tonic-gate * criteria The list of criteria governing the device selection
194*7c478bd9Sstevel@tonic-gate * Of the form <attr><op><val>
195*7c478bd9Sstevel@tonic-gate * options Options controlling the device selection. May require
196*7c478bd9Sstevel@tonic-gate * that a device meet all of the criteria (default is
197*7c478bd9Sstevel@tonic-gate * any one of the criteria), or may require that the
198*7c478bd9Sstevel@tonic-gate * devices in the list of devices be excluded from the
199*7c478bd9Sstevel@tonic-gate * generated list (default is to select only those
200*7c478bd9Sstevel@tonic-gate * devices in the list)
201*7c478bd9Sstevel@tonic-gate *
202*7c478bd9Sstevel@tonic-gate * Returns: char **
203*7c478bd9Sstevel@tonic-gate * The address of the first item in the list of devices that meet
204*7c478bd9Sstevel@tonic-gate * the selection criteria
205*7c478bd9Sstevel@tonic-gate */
206*7c478bd9Sstevel@tonic-gate
207*7c478bd9Sstevel@tonic-gate char **
getdev(char ** devices,char ** criteria,int options)208*7c478bd9Sstevel@tonic-gate getdev(
209*7c478bd9Sstevel@tonic-gate char **devices, /* List of devices to constrain */
210*7c478bd9Sstevel@tonic-gate char **criteria, /* List of selection criteria */
211*7c478bd9Sstevel@tonic-gate int options) /* Options governing the search */
212*7c478bd9Sstevel@tonic-gate {
213*7c478bd9Sstevel@tonic-gate /* Automatic data */
214*7c478bd9Sstevel@tonic-gate char **aliases; /* List of constraining devices */
215*7c478bd9Sstevel@tonic-gate char **returnlist; /* List of ptrs to aliases to return */
216*7c478bd9Sstevel@tonic-gate struct srch *searchlist; /* Pointer to searching criteria */
217*7c478bd9Sstevel@tonic-gate char *entry; /* Pointer to alias in record */
218*7c478bd9Sstevel@tonic-gate int errflag; /* FLAG: TRUE if error */
219*7c478bd9Sstevel@tonic-gate
220*7c478bd9Sstevel@tonic-gate
221*7c478bd9Sstevel@tonic-gate /*
222*7c478bd9Sstevel@tonic-gate * Initializations
223*7c478bd9Sstevel@tonic-gate */
224*7c478bd9Sstevel@tonic-gate
225*7c478bd9Sstevel@tonic-gate /* Make sure the exclude/include list is all aliases */
226*7c478bd9Sstevel@tonic-gate aliases = makealiaslist(devices);
227*7c478bd9Sstevel@tonic-gate if (devices && !aliases)
228*7c478bd9Sstevel@tonic-gate return (NULL);
229*7c478bd9Sstevel@tonic-gate
230*7c478bd9Sstevel@tonic-gate /* Build the search list */
231*7c478bd9Sstevel@tonic-gate if (criteria) {
232*7c478bd9Sstevel@tonic-gate if (!(searchlist = buildsearchlist(criteria)))
233*7c478bd9Sstevel@tonic-gate return (NULL);
234*7c478bd9Sstevel@tonic-gate } else searchlist = NULL;
235*7c478bd9Sstevel@tonic-gate
236*7c478bd9Sstevel@tonic-gate /* Initialize searching */
237*7c478bd9Sstevel@tonic-gate initdevicelist();
238*7c478bd9Sstevel@tonic-gate _setdevtab();
239*7c478bd9Sstevel@tonic-gate
240*7c478bd9Sstevel@tonic-gate
241*7c478bd9Sstevel@tonic-gate /*
242*7c478bd9Sstevel@tonic-gate * Keep on going until we get no more matches
243*7c478bd9Sstevel@tonic-gate */
244*7c478bd9Sstevel@tonic-gate
245*7c478bd9Sstevel@tonic-gate errflag = FALSE;
246*7c478bd9Sstevel@tonic-gate while (!errflag && (entry = getnextmatch(searchlist, options))) {
247*7c478bd9Sstevel@tonic-gate if (entry = oktoaddtolist(entry, devices, aliases, options)) {
248*7c478bd9Sstevel@tonic-gate errflag = addtodevicelist(entry);
249*7c478bd9Sstevel@tonic-gate }
250*7c478bd9Sstevel@tonic-gate }
251*7c478bd9Sstevel@tonic-gate
252*7c478bd9Sstevel@tonic-gate
253*7c478bd9Sstevel@tonic-gate /*
254*7c478bd9Sstevel@tonic-gate * Clean up:
255*7c478bd9Sstevel@tonic-gate * - Free the entry space we've allocated.
256*7c478bd9Sstevel@tonic-gate * - Close the device table.
257*7c478bd9Sstevel@tonic-gate * - Build the list to return to the caller.
258*7c478bd9Sstevel@tonic-gate * - Free the accumulate device space (but not the strings!)
259*7c478bd9Sstevel@tonic-gate * - Free the alias list
260*7c478bd9Sstevel@tonic-gate * - Return the built list to the caller.
261*7c478bd9Sstevel@tonic-gate */
262*7c478bd9Sstevel@tonic-gate
263*7c478bd9Sstevel@tonic-gate returnlist = buildreturnlist();
264*7c478bd9Sstevel@tonic-gate freedevicelist();
265*7c478bd9Sstevel@tonic-gate freealiaslist(aliases);
266*7c478bd9Sstevel@tonic-gate _enddevtab();
267*7c478bd9Sstevel@tonic-gate return (returnlist);
268*7c478bd9Sstevel@tonic-gate }
269*7c478bd9Sstevel@tonic-gate
270*7c478bd9Sstevel@tonic-gate /*
271*7c478bd9Sstevel@tonic-gate * char *oktoaddtolist(devtabentry, devices, aliases, options)
272*7c478bd9Sstevel@tonic-gate * char *devtabentry
273*7c478bd9Sstevel@tonic-gate * char **devices
274*7c478bd9Sstevel@tonic-gate * char **aliases
275*7c478bd9Sstevel@tonic-gate * int options
276*7c478bd9Sstevel@tonic-gate *
277*7c478bd9Sstevel@tonic-gate * This function determines the device "devtabentry" can be
278*7c478bd9Sstevel@tonic-gate * added to the list of devices we're accumulating. If so,
279*7c478bd9Sstevel@tonic-gate * it returns the device name (not the alias).
280*7c478bd9Sstevel@tonic-gate *
281*7c478bd9Sstevel@tonic-gate * Arguments:
282*7c478bd9Sstevel@tonic-gate * devtabentry The device alias that may or may not belong in the
283*7c478bd9Sstevel@tonic-gate * list we're building.
284*7c478bd9Sstevel@tonic-gate * devices The devices specified by the caller
285*7c478bd9Sstevel@tonic-gate * aliases The aliases of the devices specified by the caller
286*7c478bd9Sstevel@tonic-gate * (1-1 correspondence with "devices")
287*7c478bd9Sstevel@tonic-gate * options Options controlling the search
288*7c478bd9Sstevel@tonic-gate */
289*7c478bd9Sstevel@tonic-gate
290*7c478bd9Sstevel@tonic-gate static char *
oktoaddtolist(char * devtabentry,char ** devices,char ** aliases,int options)291*7c478bd9Sstevel@tonic-gate oktoaddtolist(
292*7c478bd9Sstevel@tonic-gate char *devtabentry, /* Alias to check against list */
293*7c478bd9Sstevel@tonic-gate char **devices, /* List of devices to check against */
294*7c478bd9Sstevel@tonic-gate char **aliases, /* List of alias of those devices */
295*7c478bd9Sstevel@tonic-gate int options) /* Options governing search */
296*7c478bd9Sstevel@tonic-gate {
297*7c478bd9Sstevel@tonic-gate /* Automatic data */
298*7c478bd9Sstevel@tonic-gate char *rtnval; /* Value to return */
299*7c478bd9Sstevel@tonic-gate int found; /* Flag: TRUE if found */
300*7c478bd9Sstevel@tonic-gate
301*7c478bd9Sstevel@tonic-gate /* If there's a constraint list, is this device in it? */
302*7c478bd9Sstevel@tonic-gate if (devices && aliases) {
303*7c478bd9Sstevel@tonic-gate
304*7c478bd9Sstevel@tonic-gate /* Set "found" to TRUE if the device is in the list */
305*7c478bd9Sstevel@tonic-gate found = FALSE;
306*7c478bd9Sstevel@tonic-gate while (!found && *aliases) {
307*7c478bd9Sstevel@tonic-gate if (strcmp(devtabentry, *aliases) == 0) found = TRUE;
308*7c478bd9Sstevel@tonic-gate else {
309*7c478bd9Sstevel@tonic-gate devices++;
310*7c478bd9Sstevel@tonic-gate aliases++;
311*7c478bd9Sstevel@tonic-gate }
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate
314*7c478bd9Sstevel@tonic-gate /* Set value to return */
315*7c478bd9Sstevel@tonic-gate if (found)
316*7c478bd9Sstevel@tonic-gate rtnval = (options & DTAB_EXCLUDEFLAG) ?
317*7c478bd9Sstevel@tonic-gate NULL : *devices;
318*7c478bd9Sstevel@tonic-gate else
319*7c478bd9Sstevel@tonic-gate rtnval = (options & DTAB_EXCLUDEFLAG) ?
320*7c478bd9Sstevel@tonic-gate devtabentry : NULL;
321*7c478bd9Sstevel@tonic-gate
322*7c478bd9Sstevel@tonic-gate } else rtnval = devtabentry; /* No constraint list */
323*7c478bd9Sstevel@tonic-gate
324*7c478bd9Sstevel@tonic-gate return (rtnval);
325*7c478bd9Sstevel@tonic-gate }
326*7c478bd9Sstevel@tonic-gate
327*7c478bd9Sstevel@tonic-gate /*
328*7c478bd9Sstevel@tonic-gate * void initdevicelist()
329*7c478bd9Sstevel@tonic-gate *
330*7c478bd9Sstevel@tonic-gate * This function initializes the list of accumulated devices.
331*7c478bd9Sstevel@tonic-gate *
332*7c478bd9Sstevel@tonic-gate * Arguments: None
333*7c478bd9Sstevel@tonic-gate *
334*7c478bd9Sstevel@tonic-gate * Returns: Void.
335*7c478bd9Sstevel@tonic-gate *
336*7c478bd9Sstevel@tonic-gate * Notes:
337*7c478bd9Sstevel@tonic-gate */
338*7c478bd9Sstevel@tonic-gate
339*7c478bd9Sstevel@tonic-gate static void
initdevicelist(void)340*7c478bd9Sstevel@tonic-gate initdevicelist(void)
341*7c478bd9Sstevel@tonic-gate {
342*7c478bd9Sstevel@tonic-gate /* Make the list a null list */
343*7c478bd9Sstevel@tonic-gate (devicelist.head)->next = NULL;
344*7c478bd9Sstevel@tonic-gate devicelist.count = 0;
345*7c478bd9Sstevel@tonic-gate }
346*7c478bd9Sstevel@tonic-gate
347*7c478bd9Sstevel@tonic-gate /*
348*7c478bd9Sstevel@tonic-gate * void freedevicelist()
349*7c478bd9Sstevel@tonic-gate *
350*7c478bd9Sstevel@tonic-gate * This function frees the resources allocated to the linked list of
351*7c478bd9Sstevel@tonic-gate * devices we've been accumulating.
352*7c478bd9Sstevel@tonic-gate *
353*7c478bd9Sstevel@tonic-gate * Arguments: none
354*7c478bd9Sstevel@tonic-gate *
355*7c478bd9Sstevel@tonic-gate * Returns: void
356*7c478bd9Sstevel@tonic-gate */
357*7c478bd9Sstevel@tonic-gate
358*7c478bd9Sstevel@tonic-gate static void
freedevicelist(void)359*7c478bd9Sstevel@tonic-gate freedevicelist(void)
360*7c478bd9Sstevel@tonic-gate {
361*7c478bd9Sstevel@tonic-gate /* Automatic data */
362*7c478bd9Sstevel@tonic-gate struct deviceent *pdevice; /* Pointer to current entry */
363*7c478bd9Sstevel@tonic-gate char *freeblk; /* Pointer space to free */
364*7c478bd9Sstevel@tonic-gate
365*7c478bd9Sstevel@tonic-gate /* List has a dummy head node */
366*7c478bd9Sstevel@tonic-gate pdevice = (devicelist.head)->next;
367*7c478bd9Sstevel@tonic-gate while (pdevice) {
368*7c478bd9Sstevel@tonic-gate freeblk = (char *) pdevice;
369*7c478bd9Sstevel@tonic-gate pdevice = pdevice->next;
370*7c478bd9Sstevel@tonic-gate free(freeblk);
371*7c478bd9Sstevel@tonic-gate }
372*7c478bd9Sstevel@tonic-gate }
373*7c478bd9Sstevel@tonic-gate
374*7c478bd9Sstevel@tonic-gate /*
375*7c478bd9Sstevel@tonic-gate * int addtodevicelist(deventry)
376*7c478bd9Sstevel@tonic-gate * char *deventry
377*7c478bd9Sstevel@tonic-gate *
378*7c478bd9Sstevel@tonic-gate * This function adds the device <deventry> to the list of devices already
379*7c478bd9Sstevel@tonic-gate * accumulated. It will not add the device if that device already exists
380*7c478bd9Sstevel@tonic-gate * in the list. The function returns 0 if successful, -1 if not with
381*7c478bd9Sstevel@tonic-gate * "errno" set (by functions called) to indicate the error.
382*7c478bd9Sstevel@tonic-gate *
383*7c478bd9Sstevel@tonic-gate * Arguments:
384*7c478bd9Sstevel@tonic-gate * deventry char *
385*7c478bd9Sstevel@tonic-gate * The name of the device to add to the list of
386*7c478bd9Sstevel@tonic-gate * accumulated devices
387*7c478bd9Sstevel@tonic-gate *
388*7c478bd9Sstevel@tonic-gate * Returns:
389*7c478bd9Sstevel@tonic-gate * 0 If successful
390*7c478bd9Sstevel@tonic-gate * -1 If failed. "errno" will be set to a value that indicates the
391*7c478bd9Sstevel@tonic-gate * error.
392*7c478bd9Sstevel@tonic-gate *
393*7c478bd9Sstevel@tonic-gate * Notes:
394*7c478bd9Sstevel@tonic-gate * - The memory allocation scheme has the potential to fragment the memory
395*7c478bd9Sstevel@tonic-gate * in the malloc heap. We're allocating space for a local structure,
396*7c478bd9Sstevel@tonic-gate * which will be freed by getdev(), then allocating space for the device
397*7c478bd9Sstevel@tonic-gate * name, which will be freed (maybe) by the application using getdev().
398*7c478bd9Sstevel@tonic-gate * Not worrying about this at the moment.
399*7c478bd9Sstevel@tonic-gate */
400*7c478bd9Sstevel@tonic-gate
401*7c478bd9Sstevel@tonic-gate static int
addtodevicelist(char * deventry)402*7c478bd9Sstevel@tonic-gate addtodevicelist(char *deventry)
403*7c478bd9Sstevel@tonic-gate {
404*7c478bd9Sstevel@tonic-gate /* Automatic data */
405*7c478bd9Sstevel@tonic-gate struct deviceent *p; /* Pointer to current device */
406*7c478bd9Sstevel@tonic-gate struct deviceent *q; /* Pointer to next device */
407*7c478bd9Sstevel@tonic-gate struct deviceent *new; /* Pointer to the alloc'd new node */
408*7c478bd9Sstevel@tonic-gate char *str; /* Pointer to alloc'd space for name */
409*7c478bd9Sstevel@tonic-gate int rtncd; /* Value to return to the caller */
410*7c478bd9Sstevel@tonic-gate int cmpcd; /* strcmp() value, comparing names */
411*7c478bd9Sstevel@tonic-gate int done; /* Loop control, TRUE if done */
412*7c478bd9Sstevel@tonic-gate
413*7c478bd9Sstevel@tonic-gate
414*7c478bd9Sstevel@tonic-gate /* Initializations */
415*7c478bd9Sstevel@tonic-gate rtncd = FALSE;
416*7c478bd9Sstevel@tonic-gate
417*7c478bd9Sstevel@tonic-gate
418*7c478bd9Sstevel@tonic-gate /*
419*7c478bd9Sstevel@tonic-gate * Find the place in the found device list devicelist where this
420*7c478bd9Sstevel@tonic-gate * device is to reside
421*7c478bd9Sstevel@tonic-gate */
422*7c478bd9Sstevel@tonic-gate
423*7c478bd9Sstevel@tonic-gate p = devicelist.head;
424*7c478bd9Sstevel@tonic-gate done = FALSE;
425*7c478bd9Sstevel@tonic-gate while (!done) {
426*7c478bd9Sstevel@tonic-gate q = p->next;
427*7c478bd9Sstevel@tonic-gate if (!q) done = TRUE;
428*7c478bd9Sstevel@tonic-gate else if ((cmpcd = strcmp(deventry, q->name)) <= 0) done = TRUE;
429*7c478bd9Sstevel@tonic-gate else p = q;
430*7c478bd9Sstevel@tonic-gate }
431*7c478bd9Sstevel@tonic-gate
432*7c478bd9Sstevel@tonic-gate /*
433*7c478bd9Sstevel@tonic-gate * If the device is not already in the list, insert it in the list
434*7c478bd9Sstevel@tonic-gate */
435*7c478bd9Sstevel@tonic-gate
436*7c478bd9Sstevel@tonic-gate if (!q || (cmpcd != 0)) {
437*7c478bd9Sstevel@tonic-gate
438*7c478bd9Sstevel@tonic-gate /* Alloc space for the new node */
439*7c478bd9Sstevel@tonic-gate if (new = malloc(sizeof (struct deviceent))) {
440*7c478bd9Sstevel@tonic-gate
441*7c478bd9Sstevel@tonic-gate /* Alloc space for the device character string */
442*7c478bd9Sstevel@tonic-gate if (str = malloc(strlen(deventry)+1)) {
443*7c478bd9Sstevel@tonic-gate
444*7c478bd9Sstevel@tonic-gate /*
445*7c478bd9Sstevel@tonic-gate * Insert an entry in the found device list containing
446*7c478bd9Sstevel@tonic-gate * this device name
447*7c478bd9Sstevel@tonic-gate */
448*7c478bd9Sstevel@tonic-gate new->next = q;
449*7c478bd9Sstevel@tonic-gate p->next = new;
450*7c478bd9Sstevel@tonic-gate new->name = strcpy(str, deventry);
451*7c478bd9Sstevel@tonic-gate devicelist.count++;
452*7c478bd9Sstevel@tonic-gate }
453*7c478bd9Sstevel@tonic-gate
454*7c478bd9Sstevel@tonic-gate /* Couldn't alloc space for the device name. Error. */
455*7c478bd9Sstevel@tonic-gate else rtncd = TRUE;
456*7c478bd9Sstevel@tonic-gate }
457*7c478bd9Sstevel@tonic-gate
458*7c478bd9Sstevel@tonic-gate /* Couldn't alloc space for new node in the found list. Error. */
459*7c478bd9Sstevel@tonic-gate else rtncd = TRUE;
460*7c478bd9Sstevel@tonic-gate
461*7c478bd9Sstevel@tonic-gate }
462*7c478bd9Sstevel@tonic-gate
463*7c478bd9Sstevel@tonic-gate /* Return an value indicating success or failure */
464*7c478bd9Sstevel@tonic-gate return (rtncd);
465*7c478bd9Sstevel@tonic-gate }
466*7c478bd9Sstevel@tonic-gate
467*7c478bd9Sstevel@tonic-gate /*
468*7c478bd9Sstevel@tonic-gate * struct srch *buildsearchlist(criteria)
469*7c478bd9Sstevel@tonic-gate * char **criteria
470*7c478bd9Sstevel@tonic-gate *
471*7c478bd9Sstevel@tonic-gate * This function builds a list of search criteria structures from the
472*7c478bd9Sstevel@tonic-gate * criteria strings in the list of criteria whose first argument is
473*7c478bd9Sstevel@tonic-gate * specified by "criteria".
474*7c478bd9Sstevel@tonic-gate *
475*7c478bd9Sstevel@tonic-gate * Arguments:
476*7c478bd9Sstevel@tonic-gate * criteria The address of the first item in a list of
477*7c478bd9Sstevel@tonic-gate * character-strings specifying search criteria
478*7c478bd9Sstevel@tonic-gate *
479*7c478bd9Sstevel@tonic-gate * Returns: struct srch *
480*7c478bd9Sstevel@tonic-gate * The address of the structure in the list of structures describing the
481*7c478bd9Sstevel@tonic-gate * search criteria.
482*7c478bd9Sstevel@tonic-gate *
483*7c478bd9Sstevel@tonic-gate * Notes:
484*7c478bd9Sstevel@tonic-gate * - The only "regular expression" currently supported by the
485*7c478bd9Sstevel@tonic-gate * kywd:exp and kywd!:exp forms is exp=*. This function assumes
486*7c478bd9Sstevel@tonic-gate * that kywd:exp means "if kywd exist" and that kywd!:exp means
487*7c478bd9Sstevel@tonic-gate * "if kywd doesn't exist".
488*7c478bd9Sstevel@tonic-gate */
489*7c478bd9Sstevel@tonic-gate
490*7c478bd9Sstevel@tonic-gate static struct srch *
buildsearchlist(char ** criteria)491*7c478bd9Sstevel@tonic-gate buildsearchlist(char **criteria) /* Criteria from caller */
492*7c478bd9Sstevel@tonic-gate {
493*7c478bd9Sstevel@tonic-gate /* Automatic data */
494*7c478bd9Sstevel@tonic-gate struct srch *rtnbuf; /* Value to return */
495*7c478bd9Sstevel@tonic-gate struct srch *psrch; /* Running pointer */
496*7c478bd9Sstevel@tonic-gate char *str; /* Ptr to malloc()ed string space */
497*7c478bd9Sstevel@tonic-gate char *p; /* Temp pointer to char */
498*7c478bd9Sstevel@tonic-gate int noerror; /* TRUE if all's well */
499*7c478bd9Sstevel@tonic-gate int n; /* Temp counter */
500*7c478bd9Sstevel@tonic-gate char **pp; /* Running ptr to (char *) */
501*7c478bd9Sstevel@tonic-gate
502*7c478bd9Sstevel@tonic-gate
503*7c478bd9Sstevel@tonic-gate /* Initializations */
504*7c478bd9Sstevel@tonic-gate rtnbuf = NULL; /* Nothing to return yet */
505*7c478bd9Sstevel@tonic-gate noerror = TRUE; /* No errors (yet) */
506*7c478bd9Sstevel@tonic-gate
507*7c478bd9Sstevel@tonic-gate /* If we were given any criteria ... */
508*7c478bd9Sstevel@tonic-gate if (criteria) {
509*7c478bd9Sstevel@tonic-gate
510*7c478bd9Sstevel@tonic-gate /* Count the number of criteria in the list */
511*7c478bd9Sstevel@tonic-gate for (n = 1, pp = criteria; *pp++; n++)
512*7c478bd9Sstevel@tonic-gate ;
513*7c478bd9Sstevel@tonic-gate
514*7c478bd9Sstevel@tonic-gate /* Allocate space for structures describing the criteria */
515*7c478bd9Sstevel@tonic-gate if (rtnbuf = malloc(n*sizeof (struct srch))) {
516*7c478bd9Sstevel@tonic-gate
517*7c478bd9Sstevel@tonic-gate /* Build structures describing the criteria */
518*7c478bd9Sstevel@tonic-gate pp = criteria;
519*7c478bd9Sstevel@tonic-gate psrch = rtnbuf;
520*7c478bd9Sstevel@tonic-gate while (noerror && *pp) {
521*7c478bd9Sstevel@tonic-gate
522*7c478bd9Sstevel@tonic-gate /* Keep list sane for cleanup if necessary */
523*7c478bd9Sstevel@tonic-gate psrch->fcn = ENDLIST;
524*7c478bd9Sstevel@tonic-gate
525*7c478bd9Sstevel@tonic-gate /* Alloc space for strings referenced by the structure */
526*7c478bd9Sstevel@tonic-gate if (str = malloc(strlen(*pp)+1)) {
527*7c478bd9Sstevel@tonic-gate
528*7c478bd9Sstevel@tonic-gate /* Extract field name, function, and compare string */
529*7c478bd9Sstevel@tonic-gate (void) strcpy(str, *pp);
530*7c478bd9Sstevel@tonic-gate
531*7c478bd9Sstevel@tonic-gate /* If criteria contains an equal sign ('=') ... */
532*7c478bd9Sstevel@tonic-gate if (p = strchr(str+1, '=')) {
533*7c478bd9Sstevel@tonic-gate if (*(p-1) == '!') {
534*7c478bd9Sstevel@tonic-gate *(p-1) = '\0';
535*7c478bd9Sstevel@tonic-gate psrch->fcn = NOTEQUAL;
536*7c478bd9Sstevel@tonic-gate } else {
537*7c478bd9Sstevel@tonic-gate *p = '\0';
538*7c478bd9Sstevel@tonic-gate psrch->fcn = EQUAL;
539*7c478bd9Sstevel@tonic-gate }
540*7c478bd9Sstevel@tonic-gate psrch->cmp = p+1;
541*7c478bd9Sstevel@tonic-gate psrch->name = str;
542*7c478bd9Sstevel@tonic-gate psrch++;
543*7c478bd9Sstevel@tonic-gate }
544*7c478bd9Sstevel@tonic-gate
545*7c478bd9Sstevel@tonic-gate /* If criteria contains a colon (':') ... */
546*7c478bd9Sstevel@tonic-gate else if (p = strchr(str+1, ':')) {
547*7c478bd9Sstevel@tonic-gate if (*(p-1) == '!') {
548*7c478bd9Sstevel@tonic-gate *(p-1) = '\0';
549*7c478bd9Sstevel@tonic-gate psrch->fcn = NOEXISTS;
550*7c478bd9Sstevel@tonic-gate } else {
551*7c478bd9Sstevel@tonic-gate *p = '\0';
552*7c478bd9Sstevel@tonic-gate psrch->fcn = EXISTS;
553*7c478bd9Sstevel@tonic-gate }
554*7c478bd9Sstevel@tonic-gate psrch->cmp = p+1;
555*7c478bd9Sstevel@tonic-gate psrch->name = str;
556*7c478bd9Sstevel@tonic-gate psrch++;
557*7c478bd9Sstevel@tonic-gate }
558*7c478bd9Sstevel@tonic-gate } else {
559*7c478bd9Sstevel@tonic-gate /* Unable to malloc() string space. Clean up */
560*7c478bd9Sstevel@tonic-gate freesearchlist(rtnbuf);
561*7c478bd9Sstevel@tonic-gate noerror = FALSE;
562*7c478bd9Sstevel@tonic-gate }
563*7c478bd9Sstevel@tonic-gate /* Next criteria */
564*7c478bd9Sstevel@tonic-gate pp++;
565*7c478bd9Sstevel@tonic-gate }
566*7c478bd9Sstevel@tonic-gate /* Terminate list */
567*7c478bd9Sstevel@tonic-gate if (noerror) psrch->fcn = ENDLIST;
568*7c478bd9Sstevel@tonic-gate }
569*7c478bd9Sstevel@tonic-gate }
570*7c478bd9Sstevel@tonic-gate
571*7c478bd9Sstevel@tonic-gate /* Return a pointer to allocated space (if any) */
572*7c478bd9Sstevel@tonic-gate return (rtnbuf);
573*7c478bd9Sstevel@tonic-gate }
574*7c478bd9Sstevel@tonic-gate
575*7c478bd9Sstevel@tonic-gate /*
576*7c478bd9Sstevel@tonic-gate * void freesearchlist(list)
577*7c478bd9Sstevel@tonic-gate * struct srch *list
578*7c478bd9Sstevel@tonic-gate *
579*7c478bd9Sstevel@tonic-gate * This function frees the resources allocated to the searchlist <list>.
580*7c478bd9Sstevel@tonic-gate *
581*7c478bd9Sstevel@tonic-gate * Arguments:
582*7c478bd9Sstevel@tonic-gate * list The list whose resources are to be released.
583*7c478bd9Sstevel@tonic-gate *
584*7c478bd9Sstevel@tonic-gate * Returns: void
585*7c478bd9Sstevel@tonic-gate */
586*7c478bd9Sstevel@tonic-gate
587*7c478bd9Sstevel@tonic-gate static void
freesearchlist(struct srch * list)588*7c478bd9Sstevel@tonic-gate freesearchlist(struct srch *list)
589*7c478bd9Sstevel@tonic-gate {
590*7c478bd9Sstevel@tonic-gate /* Automatic data */
591*7c478bd9Sstevel@tonic-gate struct srch *psrch; /* Running ptr to structs */
592*7c478bd9Sstevel@tonic-gate
593*7c478bd9Sstevel@tonic-gate
594*7c478bd9Sstevel@tonic-gate /* Free all of the string space allocated for the structure elememts */
595*7c478bd9Sstevel@tonic-gate for (psrch = list; psrch->fcn != ENDLIST; psrch++) {
596*7c478bd9Sstevel@tonic-gate free(psrch->name);
597*7c478bd9Sstevel@tonic-gate }
598*7c478bd9Sstevel@tonic-gate
599*7c478bd9Sstevel@tonic-gate /* Free the list space */
600*7c478bd9Sstevel@tonic-gate free(list);
601*7c478bd9Sstevel@tonic-gate }
602*7c478bd9Sstevel@tonic-gate
603*7c478bd9Sstevel@tonic-gate /*
604*7c478bd9Sstevel@tonic-gate * char **buildreturnlist()
605*7c478bd9Sstevel@tonic-gate *
606*7c478bd9Sstevel@tonic-gate * This function builds a list of addresses of character-strings
607*7c478bd9Sstevel@tonic-gate * to be returned from the linked-list of devices we've been
608*7c478bd9Sstevel@tonic-gate * building. It returns a pointer to the first item in that list.
609*7c478bd9Sstevel@tonic-gate *
610*7c478bd9Sstevel@tonic-gate * Arguments: none
611*7c478bd9Sstevel@tonic-gate *
612*7c478bd9Sstevel@tonic-gate * Returns: char **
613*7c478bd9Sstevel@tonic-gate * The address of the first item in the return list
614*7c478bd9Sstevel@tonic-gate */
615*7c478bd9Sstevel@tonic-gate
616*7c478bd9Sstevel@tonic-gate static char **
buildreturnlist(void)617*7c478bd9Sstevel@tonic-gate buildreturnlist(void)
618*7c478bd9Sstevel@tonic-gate {
619*7c478bd9Sstevel@tonic-gate /* Automatic data */
620*7c478bd9Sstevel@tonic-gate char **list;
621*7c478bd9Sstevel@tonic-gate char **q;
622*7c478bd9Sstevel@tonic-gate struct deviceent *p;
623*7c478bd9Sstevel@tonic-gate
624*7c478bd9Sstevel@tonic-gate
625*7c478bd9Sstevel@tonic-gate /*
626*7c478bd9Sstevel@tonic-gate * Allocate space for the return list,
627*7c478bd9Sstevel@tonic-gate * with space for the terminating node
628*7c478bd9Sstevel@tonic-gate */
629*7c478bd9Sstevel@tonic-gate
630*7c478bd9Sstevel@tonic-gate if (list = malloc((devicelist.count+1)*sizeof (char *))) {
631*7c478bd9Sstevel@tonic-gate
632*7c478bd9Sstevel@tonic-gate /*
633*7c478bd9Sstevel@tonic-gate * Walk the list of accumulated devices, putting pointers to
634*7c478bd9Sstevel@tonic-gate * device names in the list to return
635*7c478bd9Sstevel@tonic-gate */
636*7c478bd9Sstevel@tonic-gate
637*7c478bd9Sstevel@tonic-gate q = list;
638*7c478bd9Sstevel@tonic-gate for (p = devicelist.head->next; p; p = p->next) *q++ = p->name;
639*7c478bd9Sstevel@tonic-gate
640*7c478bd9Sstevel@tonic-gate /* End the list with a null-pointer */
641*7c478bd9Sstevel@tonic-gate *q = NULL;
642*7c478bd9Sstevel@tonic-gate }
643*7c478bd9Sstevel@tonic-gate
644*7c478bd9Sstevel@tonic-gate
645*7c478bd9Sstevel@tonic-gate /* Return a pointer to the list we've built */
646*7c478bd9Sstevel@tonic-gate return (list);
647*7c478bd9Sstevel@tonic-gate }
648*7c478bd9Sstevel@tonic-gate
649*7c478bd9Sstevel@tonic-gate /*
650*7c478bd9Sstevel@tonic-gate * char **makealiaslist(devices)
651*7c478bd9Sstevel@tonic-gate * char **devices List of aliases
652*7c478bd9Sstevel@tonic-gate *
653*7c478bd9Sstevel@tonic-gate * Builds a list of aliases of the devices in the "devices"
654*7c478bd9Sstevel@tonic-gate * list. This list will be terminated by (char *) NULL and
655*7c478bd9Sstevel@tonic-gate * will have the same number of elements as "devices". If
656*7c478bd9Sstevel@tonic-gate * a device couldn't be found, that alias will be "". There
657*7c478bd9Sstevel@tonic-gate * will be a one-to-one correspondence of devices to aliases
658*7c478bd9Sstevel@tonic-gate * in the device list "devices" and the generated list.
659*7c478bd9Sstevel@tonic-gate *
660*7c478bd9Sstevel@tonic-gate * Arguments:
661*7c478bd9Sstevel@tonic-gate * devices The list of devices to derive aliases from
662*7c478bd9Sstevel@tonic-gate *
663*7c478bd9Sstevel@tonic-gate * Returns: char **
664*7c478bd9Sstevel@tonic-gate * The address of the list of addresses of aliases. The list
665*7c478bd9Sstevel@tonic-gate * and aliases will be allocated using the malloc() function.
666*7c478bd9Sstevel@tonic-gate */
667*7c478bd9Sstevel@tonic-gate
668*7c478bd9Sstevel@tonic-gate static char **
makealiaslist(char ** devices)669*7c478bd9Sstevel@tonic-gate makealiaslist(char **devices)
670*7c478bd9Sstevel@tonic-gate {
671*7c478bd9Sstevel@tonic-gate /* Automatic data */
672*7c478bd9Sstevel@tonic-gate char **pp; /* Running ptr to (char *) */
673*7c478bd9Sstevel@tonic-gate char **qq; /* Running ptr to (char *) */
674*7c478bd9Sstevel@tonic-gate char **aliases; /* List being returned */
675*7c478bd9Sstevel@tonic-gate char *alias; /* Alias of current device */
676*7c478bd9Sstevel@tonic-gate int olderrno; /* Value of errno on entry */
677*7c478bd9Sstevel@tonic-gate int noerror; /* Flag, TRUE if all's well */
678*7c478bd9Sstevel@tonic-gate int n; /* Count of entries in "devices" */
679*7c478bd9Sstevel@tonic-gate
680*7c478bd9Sstevel@tonic-gate
681*7c478bd9Sstevel@tonic-gate noerror = TRUE;
682*7c478bd9Sstevel@tonic-gate olderrno = errno;
683*7c478bd9Sstevel@tonic-gate if (devices) {
684*7c478bd9Sstevel@tonic-gate
685*7c478bd9Sstevel@tonic-gate /* Get the number of entries in the constaint list */
686*7c478bd9Sstevel@tonic-gate for (n = 1, pp = devices; *pp; pp++) n++;
687*7c478bd9Sstevel@tonic-gate
688*7c478bd9Sstevel@tonic-gate /* Get space for the alias list */
689*7c478bd9Sstevel@tonic-gate if (aliases = malloc(n*sizeof (char *))) {
690*7c478bd9Sstevel@tonic-gate
691*7c478bd9Sstevel@tonic-gate /* Build the alias list */
692*7c478bd9Sstevel@tonic-gate qq = aliases;
693*7c478bd9Sstevel@tonic-gate for (pp = devices; noerror && *pp; pp++) {
694*7c478bd9Sstevel@tonic-gate
695*7c478bd9Sstevel@tonic-gate /* Get the device's alias and put it in the list */
696*7c478bd9Sstevel@tonic-gate if (alias = devattr(*pp, DTAB_ALIAS)) *qq++ = alias;
697*7c478bd9Sstevel@tonic-gate else {
698*7c478bd9Sstevel@tonic-gate errno = olderrno;
699*7c478bd9Sstevel@tonic-gate if (alias = malloc(strlen("")+1))
700*7c478bd9Sstevel@tonic-gate *qq++ = strcpy(alias, "");
701*7c478bd9Sstevel@tonic-gate else {
702*7c478bd9Sstevel@tonic-gate /* No space for a null string? Yeech... */
703*7c478bd9Sstevel@tonic-gate for (qq = aliases; *qq; qq++) free(*qq);
704*7c478bd9Sstevel@tonic-gate free(aliases);
705*7c478bd9Sstevel@tonic-gate aliases = NULL;
706*7c478bd9Sstevel@tonic-gate noerror = FALSE;
707*7c478bd9Sstevel@tonic-gate }
708*7c478bd9Sstevel@tonic-gate }
709*7c478bd9Sstevel@tonic-gate }
710*7c478bd9Sstevel@tonic-gate if (noerror)
711*7c478bd9Sstevel@tonic-gate *qq = NULL;
712*7c478bd9Sstevel@tonic-gate
713*7c478bd9Sstevel@tonic-gate }
714*7c478bd9Sstevel@tonic-gate
715*7c478bd9Sstevel@tonic-gate } else
716*7c478bd9Sstevel@tonic-gate aliases = NULL; /* No constraint list */
717*7c478bd9Sstevel@tonic-gate
718*7c478bd9Sstevel@tonic-gate /* Return ptr to generated list or NULL if none or error */
719*7c478bd9Sstevel@tonic-gate return (aliases);
720*7c478bd9Sstevel@tonic-gate }
721*7c478bd9Sstevel@tonic-gate
722*7c478bd9Sstevel@tonic-gate /*
723*7c478bd9Sstevel@tonic-gate * void freealiaslist(aliaslist)
724*7c478bd9Sstevel@tonic-gate * char **aliaslist;
725*7c478bd9Sstevel@tonic-gate *
726*7c478bd9Sstevel@tonic-gate * Free the space allocated to the aliaslist. It frees the space
727*7c478bd9Sstevel@tonic-gate * allocated to the character-strings referenced by the list then
728*7c478bd9Sstevel@tonic-gate * it frees the list.
729*7c478bd9Sstevel@tonic-gate *
730*7c478bd9Sstevel@tonic-gate * Arguments:
731*7c478bd9Sstevel@tonic-gate * aliaslist The address of the first item in the list of
732*7c478bd9Sstevel@tonic-gate * aliases that is to be freed
733*7c478bd9Sstevel@tonic-gate *
734*7c478bd9Sstevel@tonic-gate * Returns: void
735*7c478bd9Sstevel@tonic-gate */
736*7c478bd9Sstevel@tonic-gate
737*7c478bd9Sstevel@tonic-gate static void
freealiaslist(char ** aliaslist)738*7c478bd9Sstevel@tonic-gate freealiaslist(char **aliaslist) /* Ptr to new device list */
739*7c478bd9Sstevel@tonic-gate {
740*7c478bd9Sstevel@tonic-gate /* Automatic Data */
741*7c478bd9Sstevel@tonic-gate char **pp; /* Running pointer */
742*7c478bd9Sstevel@tonic-gate
743*7c478bd9Sstevel@tonic-gate /* If there's a list ... */
744*7c478bd9Sstevel@tonic-gate if (aliaslist) {
745*7c478bd9Sstevel@tonic-gate
746*7c478bd9Sstevel@tonic-gate /* For each entry in the old list, free the entry */
747*7c478bd9Sstevel@tonic-gate for (pp = aliaslist; *pp; pp++) free(*pp);
748*7c478bd9Sstevel@tonic-gate
749*7c478bd9Sstevel@tonic-gate /* Free the list */
750*7c478bd9Sstevel@tonic-gate free(aliaslist);
751*7c478bd9Sstevel@tonic-gate }
752*7c478bd9Sstevel@tonic-gate }
753*7c478bd9Sstevel@tonic-gate
754*7c478bd9Sstevel@tonic-gate /*
755*7c478bd9Sstevel@tonic-gate * char *getnextmatch(criteria, options)
756*7c478bd9Sstevel@tonic-gate * struct srch *criteria
757*7c478bd9Sstevel@tonic-gate * int options
758*7c478bd9Sstevel@tonic-gate *
759*7c478bd9Sstevel@tonic-gate * Gets the next device in the device table that matches the criteria.
760*7c478bd9Sstevel@tonic-gate * Returns the alias of that device.
761*7c478bd9Sstevel@tonic-gate *
762*7c478bd9Sstevel@tonic-gate * Arguments:
763*7c478bd9Sstevel@tonic-gate * criteria The linked list of criteria to use to match a device
764*7c478bd9Sstevel@tonic-gate * options Options modifying the criteria (only one that's really
765*7c478bd9Sstevel@tonic-gate * important is the DTAB_ANDCRITERIA flag)
766*7c478bd9Sstevel@tonic-gate *
767*7c478bd9Sstevel@tonic-gate * Returns: char *
768*7c478bd9Sstevel@tonic-gate * A pointer to a malloc()ed string containing the alias of the next
769*7c478bd9Sstevel@tonic-gate * device that matches the criteria, or (char *) NULL if none.
770*7c478bd9Sstevel@tonic-gate */
771*7c478bd9Sstevel@tonic-gate
772*7c478bd9Sstevel@tonic-gate static char *
getnextmatch(struct srch * criteria,int options)773*7c478bd9Sstevel@tonic-gate getnextmatch(struct srch *criteria, int options)
774*7c478bd9Sstevel@tonic-gate {
775*7c478bd9Sstevel@tonic-gate /* Automatic data */
776*7c478bd9Sstevel@tonic-gate struct devtabent *devtabent; /* Ptr to current record */
777*7c478bd9Sstevel@tonic-gate char *alias; /* Alias of device found */
778*7c478bd9Sstevel@tonic-gate int notdone; /* Flag, done yet? */
779*7c478bd9Sstevel@tonic-gate int noerror; /* Flag, had an error yet? */
780*7c478bd9Sstevel@tonic-gate
781*7c478bd9Sstevel@tonic-gate
782*7c478bd9Sstevel@tonic-gate /*
783*7c478bd9Sstevel@tonic-gate * Initializations:
784*7c478bd9Sstevel@tonic-gate * - No alias yet
785*7c478bd9Sstevel@tonic-gate * - Not finished yet
786*7c478bd9Sstevel@tonic-gate * - Make sure there are criteria we're to use
787*7c478bd9Sstevel@tonic-gate */
788*7c478bd9Sstevel@tonic-gate
789*7c478bd9Sstevel@tonic-gate alias = NULL;
790*7c478bd9Sstevel@tonic-gate notdone = TRUE;
791*7c478bd9Sstevel@tonic-gate noerror = TRUE;
792*7c478bd9Sstevel@tonic-gate
793*7c478bd9Sstevel@tonic-gate /* If we're to "and" the criteria... */
794*7c478bd9Sstevel@tonic-gate if (options & DTAB_ANDCRITERIA) {
795*7c478bd9Sstevel@tonic-gate
796*7c478bd9Sstevel@tonic-gate /*
797*7c478bd9Sstevel@tonic-gate * Search the device table until we've got a record that matches
798*7c478bd9Sstevel@tonic-gate * all of the criteria or we run out of records
799*7c478bd9Sstevel@tonic-gate */
800*7c478bd9Sstevel@tonic-gate
801*7c478bd9Sstevel@tonic-gate while (notdone && (devtabent = _getdevtabent())) {
802*7c478bd9Sstevel@tonic-gate if (!devtabent->comment) {
803*7c478bd9Sstevel@tonic-gate if (!criteria || matchallcriteria(devtabent, criteria)) {
804*7c478bd9Sstevel@tonic-gate if (alias = malloc(strlen(devtabent->alias)+1))
805*7c478bd9Sstevel@tonic-gate (void) strcpy(alias, devtabent->alias);
806*7c478bd9Sstevel@tonic-gate else noerror = FALSE;
807*7c478bd9Sstevel@tonic-gate notdone = FALSE;
808*7c478bd9Sstevel@tonic-gate }
809*7c478bd9Sstevel@tonic-gate }
810*7c478bd9Sstevel@tonic-gate _freedevtabent(devtabent);
811*7c478bd9Sstevel@tonic-gate }
812*7c478bd9Sstevel@tonic-gate } else {
813*7c478bd9Sstevel@tonic-gate
814*7c478bd9Sstevel@tonic-gate /*
815*7c478bd9Sstevel@tonic-gate * Search the device table until we've got a record that matches
816*7c478bd9Sstevel@tonic-gate * any of the criteria or we run out of records
817*7c478bd9Sstevel@tonic-gate */
818*7c478bd9Sstevel@tonic-gate
819*7c478bd9Sstevel@tonic-gate while (notdone && (devtabent = _getdevtabent())) {
820*7c478bd9Sstevel@tonic-gate if (!devtabent->comment) {
821*7c478bd9Sstevel@tonic-gate if (!criteria || matchanycriteria(devtabent, criteria)) {
822*7c478bd9Sstevel@tonic-gate if (alias = malloc(strlen(devtabent->alias)+1))
823*7c478bd9Sstevel@tonic-gate (void) strcpy(alias, devtabent->alias);
824*7c478bd9Sstevel@tonic-gate else noerror = FALSE;
825*7c478bd9Sstevel@tonic-gate notdone = FALSE;
826*7c478bd9Sstevel@tonic-gate }
827*7c478bd9Sstevel@tonic-gate }
828*7c478bd9Sstevel@tonic-gate _freedevtabent(devtabent);
829*7c478bd9Sstevel@tonic-gate }
830*7c478bd9Sstevel@tonic-gate }
831*7c478bd9Sstevel@tonic-gate
832*7c478bd9Sstevel@tonic-gate
833*7c478bd9Sstevel@tonic-gate /* Return pointer to extracted alias (or NULL if none) */
834*7c478bd9Sstevel@tonic-gate if ((alias == NULL) && noerror) errno = ENOENT;
835*7c478bd9Sstevel@tonic-gate return (alias);
836*7c478bd9Sstevel@tonic-gate }
837*7c478bd9Sstevel@tonic-gate
838*7c478bd9Sstevel@tonic-gate /*
839*7c478bd9Sstevel@tonic-gate * int matchallcriteria(devtabent, criteria)
840*7c478bd9Sstevel@tonic-gate *
841*7c478bd9Sstevel@tonic-gate * This function examines the record contained in "devtabent" and
842*7c478bd9Sstevel@tonic-gate * determines if that record meets all of the criteria specified by
843*7c478bd9Sstevel@tonic-gate * "criteria".
844*7c478bd9Sstevel@tonic-gate *
845*7c478bd9Sstevel@tonic-gate * Arguments:
846*7c478bd9Sstevel@tonic-gate * struct devtabent *devtabent The device table entry to examine.
847*7c478bd9Sstevel@tonic-gate * struct srch *criteria The criteria to match.
848*7c478bd9Sstevel@tonic-gate *
849*7c478bd9Sstevel@tonic-gate * Returns: int
850*7c478bd9Sstevel@tonic-gate * Returns TRUE if the record matches criteria, FALSE otherwise.
851*7c478bd9Sstevel@tonic-gate */
852*7c478bd9Sstevel@tonic-gate
853*7c478bd9Sstevel@tonic-gate static int
matchallcriteria(struct devtabent * ent,struct srch * criteria)854*7c478bd9Sstevel@tonic-gate matchallcriteria(
855*7c478bd9Sstevel@tonic-gate struct devtabent *ent, /* Entry to check */
856*7c478bd9Sstevel@tonic-gate struct srch *criteria) /* Criteria governing match */
857*7c478bd9Sstevel@tonic-gate {
858*7c478bd9Sstevel@tonic-gate /* Automatic data */
859*7c478bd9Sstevel@tonic-gate struct srch *p; /* Pointer to current criteria */
860*7c478bd9Sstevel@tonic-gate struct attrval *q; /* Pointer to current attr/val pair */
861*7c478bd9Sstevel@tonic-gate int notfound; /* TRUE if attr found in list */
862*7c478bd9Sstevel@tonic-gate int failed; /* TRUE if record failed to match */
863*7c478bd9Sstevel@tonic-gate
864*7c478bd9Sstevel@tonic-gate
865*7c478bd9Sstevel@tonic-gate /* Test only if there's criteria to test against */
866*7c478bd9Sstevel@tonic-gate if (criteria && (criteria->fcn != ENDLIST)) {
867*7c478bd9Sstevel@tonic-gate
868*7c478bd9Sstevel@tonic-gate failed = FALSE;
869*7c478bd9Sstevel@tonic-gate for (p = criteria; !failed && (p->fcn != ENDLIST); p++) {
870*7c478bd9Sstevel@tonic-gate
871*7c478bd9Sstevel@tonic-gate /*
872*7c478bd9Sstevel@tonic-gate * Don't compare against this criteria if it's function is
873*7c478bd9Sstevel@tonic-gate * "IGNORE"
874*7c478bd9Sstevel@tonic-gate */
875*7c478bd9Sstevel@tonic-gate if (p->fcn != IGNORE) {
876*7c478bd9Sstevel@tonic-gate if (p->fcn != NOEXISTS) {
877*7c478bd9Sstevel@tonic-gate
878*7c478bd9Sstevel@tonic-gate /* Alias? */
879*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, DTAB_ALIAS) == 0)
880*7c478bd9Sstevel@tonic-gate failed = !matches(ent->alias, p->cmp, p->fcn);
881*7c478bd9Sstevel@tonic-gate
882*7c478bd9Sstevel@tonic-gate /* Char special device? */
883*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_CDEVICE) == 0)
884*7c478bd9Sstevel@tonic-gate failed = !matches(ent->cdevice, p->cmp, p->fcn);
885*7c478bd9Sstevel@tonic-gate
886*7c478bd9Sstevel@tonic-gate /* Block special device? */
887*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_BDEVICE) == 0)
888*7c478bd9Sstevel@tonic-gate failed = !matches(ent->bdevice, p->cmp, p->fcn);
889*7c478bd9Sstevel@tonic-gate
890*7c478bd9Sstevel@tonic-gate /* Pathname? */
891*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_PATHNAME) == 0)
892*7c478bd9Sstevel@tonic-gate failed = !matches(ent->pathname, p->cmp, p->fcn);
893*7c478bd9Sstevel@tonic-gate
894*7c478bd9Sstevel@tonic-gate /* Check other attributes... */
895*7c478bd9Sstevel@tonic-gate else {
896*7c478bd9Sstevel@tonic-gate notfound = TRUE;
897*7c478bd9Sstevel@tonic-gate q = ent->attrlist;
898*7c478bd9Sstevel@tonic-gate while (notfound && q) {
899*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, q->attr) == 0) {
900*7c478bd9Sstevel@tonic-gate notfound = FALSE;
901*7c478bd9Sstevel@tonic-gate if (!matches(q->val, p->cmp, p->fcn))
902*7c478bd9Sstevel@tonic-gate failed = TRUE;
903*7c478bd9Sstevel@tonic-gate } else q = q->next;
904*7c478bd9Sstevel@tonic-gate }
905*7c478bd9Sstevel@tonic-gate if (notfound) failed = TRUE;
906*7c478bd9Sstevel@tonic-gate }
907*7c478bd9Sstevel@tonic-gate } else {
908*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, DTAB_ALIAS) == 0) failed = TRUE;
909*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_CDEVICE) == 0)
910*7c478bd9Sstevel@tonic-gate failed = FALSE;
911*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_BDEVICE) == 0)
912*7c478bd9Sstevel@tonic-gate failed = FALSE;
913*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_PATHNAME) == 0)
914*7c478bd9Sstevel@tonic-gate failed = FALSE;
915*7c478bd9Sstevel@tonic-gate else {
916*7c478bd9Sstevel@tonic-gate q = ent->attrlist;
917*7c478bd9Sstevel@tonic-gate while (!failed && q) {
918*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, q->attr) == 0)
919*7c478bd9Sstevel@tonic-gate failed = TRUE;
920*7c478bd9Sstevel@tonic-gate else q = q->next;
921*7c478bd9Sstevel@tonic-gate }
922*7c478bd9Sstevel@tonic-gate }
923*7c478bd9Sstevel@tonic-gate }
924*7c478bd9Sstevel@tonic-gate
925*7c478bd9Sstevel@tonic-gate } /* Search function is not "IGNORE" */
926*7c478bd9Sstevel@tonic-gate
927*7c478bd9Sstevel@tonic-gate } /* for loop, checking each criteria */
928*7c478bd9Sstevel@tonic-gate
929*7c478bd9Sstevel@tonic-gate } /* if (criteria) */
930*7c478bd9Sstevel@tonic-gate
931*7c478bd9Sstevel@tonic-gate else failed = FALSE; /* No criteria specified, it's a match */
932*7c478bd9Sstevel@tonic-gate
933*7c478bd9Sstevel@tonic-gate
934*7c478bd9Sstevel@tonic-gate /* Return a value indicating if the record matches all criteria */
935*7c478bd9Sstevel@tonic-gate return (!failed);
936*7c478bd9Sstevel@tonic-gate }
937*7c478bd9Sstevel@tonic-gate
938*7c478bd9Sstevel@tonic-gate /*
939*7c478bd9Sstevel@tonic-gate * int matchanycriteria(devtabent, criteria)
940*7c478bd9Sstevel@tonic-gate *
941*7c478bd9Sstevel@tonic-gate * This function examines the record contained in "devtabent" and
942*7c478bd9Sstevel@tonic-gate * determines if that record meets any of the criteria specified by
943*7c478bd9Sstevel@tonic-gate * "criteria".
944*7c478bd9Sstevel@tonic-gate *
945*7c478bd9Sstevel@tonic-gate * Arguments:
946*7c478bd9Sstevel@tonic-gate * struct devtabent *devtabent The device table entry to examine.
947*7c478bd9Sstevel@tonic-gate * struct srch *criteria The criteria to match.
948*7c478bd9Sstevel@tonic-gate *
949*7c478bd9Sstevel@tonic-gate * Returns: int
950*7c478bd9Sstevel@tonic-gate * Returns TRUE if the record matches criteria, FALSE otherwise.
951*7c478bd9Sstevel@tonic-gate */
952*7c478bd9Sstevel@tonic-gate
953*7c478bd9Sstevel@tonic-gate static int
matchanycriteria(struct devtabent * ent,struct srch * criteria)954*7c478bd9Sstevel@tonic-gate matchanycriteria(
955*7c478bd9Sstevel@tonic-gate struct devtabent *ent, /* Entry to check */
956*7c478bd9Sstevel@tonic-gate struct srch *criteria) /* Criteria governing match */
957*7c478bd9Sstevel@tonic-gate {
958*7c478bd9Sstevel@tonic-gate /* Automatic data */
959*7c478bd9Sstevel@tonic-gate struct srch *p; /* Pointer to current criteria */
960*7c478bd9Sstevel@tonic-gate struct attrval *q; /* Pointer to current attr/val pair */
961*7c478bd9Sstevel@tonic-gate int matched; /* FLAG: TRUE if record matched */
962*7c478bd9Sstevel@tonic-gate int found; /* FLAG: TRUE if attribute found */
963*7c478bd9Sstevel@tonic-gate
964*7c478bd9Sstevel@tonic-gate
965*7c478bd9Sstevel@tonic-gate /* Test only if there's criteria to test against */
966*7c478bd9Sstevel@tonic-gate if (criteria && (criteria->fcn != ENDLIST)) {
967*7c478bd9Sstevel@tonic-gate
968*7c478bd9Sstevel@tonic-gate matched = FALSE;
969*7c478bd9Sstevel@tonic-gate for (p = criteria; !matched && (p->fcn != ENDLIST); p++) {
970*7c478bd9Sstevel@tonic-gate
971*7c478bd9Sstevel@tonic-gate /*
972*7c478bd9Sstevel@tonic-gate * Don't compare against this criteria if it's function is
973*7c478bd9Sstevel@tonic-gate * "IGNORE"
974*7c478bd9Sstevel@tonic-gate */
975*7c478bd9Sstevel@tonic-gate if (p->fcn != IGNORE) {
976*7c478bd9Sstevel@tonic-gate if (p->fcn != NOEXISTS) {
977*7c478bd9Sstevel@tonic-gate
978*7c478bd9Sstevel@tonic-gate /* Alias? */
979*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, DTAB_ALIAS) == 0)
980*7c478bd9Sstevel@tonic-gate matched = matches(ent->alias, p->cmp, p->fcn);
981*7c478bd9Sstevel@tonic-gate
982*7c478bd9Sstevel@tonic-gate /* Char special device? */
983*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_CDEVICE) == 0)
984*7c478bd9Sstevel@tonic-gate matched = matches(ent->cdevice, p->cmp, p->fcn);
985*7c478bd9Sstevel@tonic-gate
986*7c478bd9Sstevel@tonic-gate /* Block special device? */
987*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_BDEVICE) == 0)
988*7c478bd9Sstevel@tonic-gate matched = matches(ent->bdevice, p->cmp, p->fcn);
989*7c478bd9Sstevel@tonic-gate
990*7c478bd9Sstevel@tonic-gate /* Pathname? */
991*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_PATHNAME) == 0)
992*7c478bd9Sstevel@tonic-gate matched = matches(ent->pathname, p->cmp, p->fcn);
993*7c478bd9Sstevel@tonic-gate
994*7c478bd9Sstevel@tonic-gate /* Check other attributes... */
995*7c478bd9Sstevel@tonic-gate else {
996*7c478bd9Sstevel@tonic-gate q = ent->attrlist;
997*7c478bd9Sstevel@tonic-gate found = FALSE;
998*7c478bd9Sstevel@tonic-gate while (!found && q)
999*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, q->attr) == 0) {
1000*7c478bd9Sstevel@tonic-gate matched = matches(q->val, p->cmp, p->fcn);
1001*7c478bd9Sstevel@tonic-gate found = TRUE;
1002*7c478bd9Sstevel@tonic-gate } else q = q->next;
1003*7c478bd9Sstevel@tonic-gate }
1004*7c478bd9Sstevel@tonic-gate } else {
1005*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, DTAB_ALIAS) == 0) matched = FALSE;
1006*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_CDEVICE) == 0)
1007*7c478bd9Sstevel@tonic-gate matched = FALSE;
1008*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_BDEVICE) == 0)
1009*7c478bd9Sstevel@tonic-gate matched = FALSE;
1010*7c478bd9Sstevel@tonic-gate else if (strcmp(p->name, DTAB_PATHNAME) == 0)
1011*7c478bd9Sstevel@tonic-gate matched = FALSE;
1012*7c478bd9Sstevel@tonic-gate else {
1013*7c478bd9Sstevel@tonic-gate q = ent->attrlist;
1014*7c478bd9Sstevel@tonic-gate matched = TRUE;
1015*7c478bd9Sstevel@tonic-gate while (matched && q) {
1016*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, q->attr) == 0)
1017*7c478bd9Sstevel@tonic-gate matched = FALSE;
1018*7c478bd9Sstevel@tonic-gate else q = q->next;
1019*7c478bd9Sstevel@tonic-gate }
1020*7c478bd9Sstevel@tonic-gate }
1021*7c478bd9Sstevel@tonic-gate }
1022*7c478bd9Sstevel@tonic-gate } /* Search function is not "IGNORE" */
1023*7c478bd9Sstevel@tonic-gate
1024*7c478bd9Sstevel@tonic-gate } /* for loop, checking each criteria */
1025*7c478bd9Sstevel@tonic-gate
1026*7c478bd9Sstevel@tonic-gate } /* if (criteria) */
1027*7c478bd9Sstevel@tonic-gate
1028*7c478bd9Sstevel@tonic-gate else matched = TRUE; /* No criteria specified, it's a match */
1029*7c478bd9Sstevel@tonic-gate
1030*7c478bd9Sstevel@tonic-gate
1031*7c478bd9Sstevel@tonic-gate /* Return a value indicating if the record matches all criteria */
1032*7c478bd9Sstevel@tonic-gate return (matched);
1033*7c478bd9Sstevel@tonic-gate }
1034*7c478bd9Sstevel@tonic-gate
1035*7c478bd9Sstevel@tonic-gate /*
1036*7c478bd9Sstevel@tonic-gate * int matches(value, compare, function)
1037*7c478bd9Sstevel@tonic-gate * char *value
1038*7c478bd9Sstevel@tonic-gate * char *compare
1039*7c478bd9Sstevel@tonic-gate * int function
1040*7c478bd9Sstevel@tonic-gate *
1041*7c478bd9Sstevel@tonic-gate * This function sees if the operation <function> is satisfied by
1042*7c478bd9Sstevel@tonic-gate * comparing the value <value> with <compare>. It returns TRUE
1043*7c478bd9Sstevel@tonic-gate * if so, FALSE otherwise.
1044*7c478bd9Sstevel@tonic-gate *
1045*7c478bd9Sstevel@tonic-gate * Arguments:
1046*7c478bd9Sstevel@tonic-gate * value Value to compare
1047*7c478bd9Sstevel@tonic-gate * compare Value to compare against
1048*7c478bd9Sstevel@tonic-gate * function Function to be satisfied
1049*7c478bd9Sstevel@tonic-gate *
1050*7c478bd9Sstevel@tonic-gate * Returns: int
1051*7c478bd9Sstevel@tonic-gate * TRUE if the function is satisfied, FALSE otherwise
1052*7c478bd9Sstevel@tonic-gate */
1053*7c478bd9Sstevel@tonic-gate
1054*7c478bd9Sstevel@tonic-gate static int
matches(char * value,char * compare,int function)1055*7c478bd9Sstevel@tonic-gate matches(char *value, char *compare, int function)
1056*7c478bd9Sstevel@tonic-gate {
1057*7c478bd9Sstevel@tonic-gate /* Automatic data */
1058*7c478bd9Sstevel@tonic-gate int rtn; /* Value to return */
1059*7c478bd9Sstevel@tonic-gate
1060*7c478bd9Sstevel@tonic-gate
1061*7c478bd9Sstevel@tonic-gate if (value == NULL)
1062*7c478bd9Sstevel@tonic-gate value = "";
1063*7c478bd9Sstevel@tonic-gate
1064*7c478bd9Sstevel@tonic-gate /* Do case depending on the function */
1065*7c478bd9Sstevel@tonic-gate switch (function) {
1066*7c478bd9Sstevel@tonic-gate
1067*7c478bd9Sstevel@tonic-gate /* attr=val */
1068*7c478bd9Sstevel@tonic-gate case EQUAL:
1069*7c478bd9Sstevel@tonic-gate rtn = (strcmp(value, compare) == 0);
1070*7c478bd9Sstevel@tonic-gate break;
1071*7c478bd9Sstevel@tonic-gate
1072*7c478bd9Sstevel@tonic-gate /* attr!=val */
1073*7c478bd9Sstevel@tonic-gate case NOTEQUAL:
1074*7c478bd9Sstevel@tonic-gate rtn = (strcmp(value, compare) != 0);
1075*7c478bd9Sstevel@tonic-gate break;
1076*7c478bd9Sstevel@tonic-gate
1077*7c478bd9Sstevel@tonic-gate /* attr:* */
1078*7c478bd9Sstevel@tonic-gate case EXISTS:
1079*7c478bd9Sstevel@tonic-gate rtn = TRUE;
1080*7c478bd9Sstevel@tonic-gate break;
1081*7c478bd9Sstevel@tonic-gate
1082*7c478bd9Sstevel@tonic-gate /* attr!:* */
1083*7c478bd9Sstevel@tonic-gate case NOEXISTS:
1084*7c478bd9Sstevel@tonic-gate rtn = FALSE;
1085*7c478bd9Sstevel@tonic-gate break;
1086*7c478bd9Sstevel@tonic-gate
1087*7c478bd9Sstevel@tonic-gate /* Shouldn't get here... */
1088*7c478bd9Sstevel@tonic-gate default:
1089*7c478bd9Sstevel@tonic-gate rtn = FALSE;
1090*7c478bd9Sstevel@tonic-gate break;
1091*7c478bd9Sstevel@tonic-gate }
1092*7c478bd9Sstevel@tonic-gate
1093*7c478bd9Sstevel@tonic-gate /* Return a value indicating if the match was made */
1094*7c478bd9Sstevel@tonic-gate return (rtn);
1095*7c478bd9Sstevel@tonic-gate }
1096