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 ** 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 * 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 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 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 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 * 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 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 ** 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 ** 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 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 * 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 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 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 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