dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libadm / common / getdev.c
blob8e4401140fcc5214c38dc818b1b3703a89dfc038
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright (c) 1997, by Sun Microsystems, Inc.
28 * All rights reserved.
31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4 */
32 /*LINTLIBRARY*/
35 * getdev.c
37 * Contents:
38 * getdev() List devices that match certain criteria.
42 * Header files referenced:
43 * <sys/types.h> System Data Types
44 * <errno.h> Error handling
45 * <fcntl.h> File controlling
46 * <ctype.h> Character types
47 * <string.h> String handling
48 * <devmgmt.h> Global device-management def'ns
49 * "devtab.h" Local device-management dev'ns
52 #include <sys/types.h>
53 #include <errno.h>
54 #include <fcntl.h>
55 #include <ctype.h>
56 #include <string.h>
57 #include <devmgmt.h>
58 #include "devtab.h"
59 #include <stdlib.h>
62 * Local definitions
63 * NULL Nil address
64 * TRUE Boolean TRUE
65 * FALSE Boolean FALSE
68 #ifndef NULL
69 #define NULL 0
70 #endif
72 #ifndef TRUE
73 #define TRUE ('t')
74 #endif
76 #ifndef FALSE
77 #define FALSE 0
78 #endif
82 * Comparison values. These values are placed in the struct srch
83 * structure by buildsearchlist() and are used to compare values
84 * in matches().
85 * EQUAL Attribute must equal this value
86 * NOTEQUAL Attribute must not equal this value
87 * EXISTS Attribute must exist
88 * NOEXISTS Attribute must not exist
89 * IGNORE Ignore this entry
90 * ENDLIST This entry ends the list
93 #define EQUAL 1
94 #define NOTEQUAL 2
95 #define EXISTS 3
96 #define NOEXISTS 4
97 #define IGNORE 5
98 #define ENDLIST 0
102 * Structure definitions:
103 * deviceent Defines a device that matches criteria
104 * srch Describes a criteria
107 struct deviceent {
108 struct deviceent *next; /* Pointer to next item in the list */
109 char *name; /* Presentation name of the device */
112 struct srch {
113 char *name; /* Name of field to compare */
114 char *cmp; /* Value to compare against */
115 int fcn; /* Type of comparison (see above) */
120 * Local functions referenced
121 * oktoaddtolist() Determines if device can be added to the
122 * list by examining the devices list and
123 * the options governing the search
124 * initdevicelist() Initializes the linked list of devices
125 * to be included in the list-to-return
126 * freedevicelist() Frees the resources allocated to the linked
127 * list of devices
128 * addtodevicelist() Adds an entry to the linked list of devices
129 * buildsearchlist() Builds a list of struct srch structures from
130 * the criteria strings
131 * freesearchlist() Frees the resources allocated to the list of
132 * struct srch structures
133 * buildreturnlist() Builds the list of devices to return from the
134 * linked list of devices we've accumulated
135 * makealiaslist() Builds a list of aliases from the list of
136 * devices presented by the caller
137 * freealiaslist() Frees the resources allocated to the list of
138 * devices aliases
139 * getnextmatch() Get the next device that matches the search
140 * criteria
141 * matchallcriteria() See if the device attributes match all of the
142 * search criteria
143 * matchanycriteria() See if the device attributes match any of the
144 * search criteria
145 * matches() See if the criteria and attribute match
148 static char *oktoaddtolist(char *, char **, char **, int);
149 static void initdevicelist(void);
150 static void freedevicelist(void);
151 static int addtodevicelist(char *);
152 static struct srch *buildsearchlist(char **);
153 static void freesearchlist(struct srch *);
154 static char **buildreturnlist(void);
155 static char **makealiaslist(char **);
156 static void freealiaslist(char **);
157 static char *getnextmatch(struct srch *, int);
158 static int matchallcriteria(struct devtabent *, struct srch *);
159 static int matchanycriteria(struct devtabent *, struct srch *);
160 static int matches(char *, char *, int);
164 * Global Data
168 * Static Data
169 * devicelisthead The first item (dummy) in the linked list of devices
170 * we're building
171 * devicelist Structure describing the linked list of devices
174 static struct deviceent devicelisthead;
175 static struct {
176 struct deviceent *head;
177 int count;
178 } devicelist = {&devicelisthead, 0};
181 * char **getdev(devices, criteria, options)
182 * char **devices
183 * char **criteria
184 * int options
186 * This function builds a list of devices that match criteria,
187 * governed by the device list.
189 * Arguments:
190 * devices The list of devices to select from or the list of
191 * devices to exclude, depending on the value of
192 * "options"
193 * criteria The list of criteria governing the device selection
194 * Of the form <attr><op><val>
195 * options Options controlling the device selection. May require
196 * that a device meet all of the criteria (default is
197 * any one of the criteria), or may require that the
198 * devices in the list of devices be excluded from the
199 * generated list (default is to select only those
200 * devices in the list)
202 * Returns: char **
203 * The address of the first item in the list of devices that meet
204 * the selection criteria
207 char **
208 getdev(
209 char **devices, /* List of devices to constrain */
210 char **criteria, /* List of selection criteria */
211 int options) /* Options governing the search */
213 /* Automatic data */
214 char **aliases; /* List of constraining devices */
215 char **returnlist; /* List of ptrs to aliases to return */
216 struct srch *searchlist; /* Pointer to searching criteria */
217 char *entry; /* Pointer to alias in record */
218 int errflag; /* FLAG: TRUE if error */
222 * Initializations
225 /* Make sure the exclude/include list is all aliases */
226 aliases = makealiaslist(devices);
227 if (devices && !aliases)
228 return (NULL);
230 /* Build the search list */
231 if (criteria) {
232 if (!(searchlist = buildsearchlist(criteria)))
233 return (NULL);
234 } else searchlist = NULL;
236 /* Initialize searching */
237 initdevicelist();
238 _setdevtab();
242 * Keep on going until we get no more matches
245 errflag = FALSE;
246 while (!errflag && (entry = getnextmatch(searchlist, options))) {
247 if (entry = oktoaddtolist(entry, devices, aliases, options)) {
248 errflag = addtodevicelist(entry);
254 * Clean up:
255 * - Free the entry space we've allocated.
256 * - Close the device table.
257 * - Build the list to return to the caller.
258 * - Free the accumulate device space (but not the strings!)
259 * - Free the alias list
260 * - Return the built list to the caller.
263 returnlist = buildreturnlist();
264 freedevicelist();
265 freealiaslist(aliases);
266 _enddevtab();
267 return (returnlist);
271 * char *oktoaddtolist(devtabentry, devices, aliases, options)
272 * char *devtabentry
273 * char **devices
274 * char **aliases
275 * int options
277 * This function determines the device "devtabentry" can be
278 * added to the list of devices we're accumulating. If so,
279 * it returns the device name (not the alias).
281 * Arguments:
282 * devtabentry The device alias that may or may not belong in the
283 * list we're building.
284 * devices The devices specified by the caller
285 * aliases The aliases of the devices specified by the caller
286 * (1-1 correspondence with "devices")
287 * options Options controlling the search
290 static char *
291 oktoaddtolist(
292 char *devtabentry, /* Alias to check against list */
293 char **devices, /* List of devices to check against */
294 char **aliases, /* List of alias of those devices */
295 int options) /* Options governing search */
297 /* Automatic data */
298 char *rtnval; /* Value to return */
299 int found; /* Flag: TRUE if found */
301 /* If there's a constraint list, is this device in it? */
302 if (devices && aliases) {
304 /* Set "found" to TRUE if the device is in the list */
305 found = FALSE;
306 while (!found && *aliases) {
307 if (strcmp(devtabentry, *aliases) == 0) found = TRUE;
308 else {
309 devices++;
310 aliases++;
314 /* Set value to return */
315 if (found)
316 rtnval = (options & DTAB_EXCLUDEFLAG) ?
317 NULL : *devices;
318 else
319 rtnval = (options & DTAB_EXCLUDEFLAG) ?
320 devtabentry : NULL;
322 } else rtnval = devtabentry; /* No constraint list */
324 return (rtnval);
328 * void initdevicelist()
330 * This function initializes the list of accumulated devices.
332 * Arguments: None
334 * Returns: Void.
336 * Notes:
339 static void
340 initdevicelist(void)
342 /* Make the list a null list */
343 (devicelist.head)->next = NULL;
344 devicelist.count = 0;
348 * void freedevicelist()
350 * This function frees the resources allocated to the linked list of
351 * devices we've been accumulating.
353 * Arguments: none
355 * Returns: void
358 static void
359 freedevicelist(void)
361 /* Automatic data */
362 struct deviceent *pdevice; /* Pointer to current entry */
363 char *freeblk; /* Pointer space to free */
365 /* List has a dummy head node */
366 pdevice = (devicelist.head)->next;
367 while (pdevice) {
368 freeblk = (char *) pdevice;
369 pdevice = pdevice->next;
370 free(freeblk);
375 * int addtodevicelist(deventry)
376 * char *deventry
378 * This function adds the device <deventry> to the list of devices already
379 * accumulated. It will not add the device if that device already exists
380 * in the list. The function returns 0 if successful, -1 if not with
381 * "errno" set (by functions called) to indicate the error.
383 * Arguments:
384 * deventry char *
385 * The name of the device to add to the list of
386 * accumulated devices
388 * Returns:
389 * 0 If successful
390 * -1 If failed. "errno" will be set to a value that indicates the
391 * error.
393 * Notes:
394 * - The memory allocation scheme has the potential to fragment the memory
395 * in the malloc heap. We're allocating space for a local structure,
396 * which will be freed by getdev(), then allocating space for the device
397 * name, which will be freed (maybe) by the application using getdev().
398 * Not worrying about this at the moment.
401 static int
402 addtodevicelist(char *deventry)
404 /* Automatic data */
405 struct deviceent *p; /* Pointer to current device */
406 struct deviceent *q; /* Pointer to next device */
407 struct deviceent *new; /* Pointer to the alloc'd new node */
408 char *str; /* Pointer to alloc'd space for name */
409 int rtncd; /* Value to return to the caller */
410 int cmpcd; /* strcmp() value, comparing names */
411 int done; /* Loop control, TRUE if done */
414 /* Initializations */
415 rtncd = FALSE;
419 * Find the place in the found device list devicelist where this
420 * device is to reside
423 p = devicelist.head;
424 done = FALSE;
425 while (!done) {
426 q = p->next;
427 if (!q) done = TRUE;
428 else if ((cmpcd = strcmp(deventry, q->name)) <= 0) done = TRUE;
429 else p = q;
433 * If the device is not already in the list, insert it in the list
436 if (!q || (cmpcd != 0)) {
438 /* Alloc space for the new node */
439 if (new = malloc(sizeof (struct deviceent))) {
441 /* Alloc space for the device character string */
442 if (str = malloc(strlen(deventry)+1)) {
445 * Insert an entry in the found device list containing
446 * this device name
448 new->next = q;
449 p->next = new;
450 new->name = strcpy(str, deventry);
451 devicelist.count++;
454 /* Couldn't alloc space for the device name. Error. */
455 else rtncd = TRUE;
458 /* Couldn't alloc space for new node in the found list. Error. */
459 else rtncd = TRUE;
463 /* Return an value indicating success or failure */
464 return (rtncd);
468 * struct srch *buildsearchlist(criteria)
469 * char **criteria
471 * This function builds a list of search criteria structures from the
472 * criteria strings in the list of criteria whose first argument is
473 * specified by "criteria".
475 * Arguments:
476 * criteria The address of the first item in a list of
477 * character-strings specifying search criteria
479 * Returns: struct srch *
480 * The address of the structure in the list of structures describing the
481 * search criteria.
483 * Notes:
484 * - The only "regular expression" currently supported by the
485 * kywd:exp and kywd!:exp forms is exp=*. This function assumes
486 * that kywd:exp means "if kywd exist" and that kywd!:exp means
487 * "if kywd doesn't exist".
490 static struct srch *
491 buildsearchlist(char **criteria) /* Criteria from caller */
493 /* Automatic data */
494 struct srch *rtnbuf; /* Value to return */
495 struct srch *psrch; /* Running pointer */
496 char *str; /* Ptr to malloc()ed string space */
497 char *p; /* Temp pointer to char */
498 int noerror; /* TRUE if all's well */
499 int n; /* Temp counter */
500 char **pp; /* Running ptr to (char *) */
503 /* Initializations */
504 rtnbuf = NULL; /* Nothing to return yet */
505 noerror = TRUE; /* No errors (yet) */
507 /* If we were given any criteria ... */
508 if (criteria) {
510 /* Count the number of criteria in the list */
511 for (n = 1, pp = criteria; *pp++; n++)
514 /* Allocate space for structures describing the criteria */
515 if (rtnbuf = malloc(n*sizeof (struct srch))) {
517 /* Build structures describing the criteria */
518 pp = criteria;
519 psrch = rtnbuf;
520 while (noerror && *pp) {
522 /* Keep list sane for cleanup if necessary */
523 psrch->fcn = ENDLIST;
525 /* Alloc space for strings referenced by the structure */
526 if (str = malloc(strlen(*pp)+1)) {
528 /* Extract field name, function, and compare string */
529 (void) strcpy(str, *pp);
531 /* If criteria contains an equal sign ('=') ... */
532 if (p = strchr(str+1, '=')) {
533 if (*(p-1) == '!') {
534 *(p-1) = '\0';
535 psrch->fcn = NOTEQUAL;
536 } else {
537 *p = '\0';
538 psrch->fcn = EQUAL;
540 psrch->cmp = p+1;
541 psrch->name = str;
542 psrch++;
545 /* If criteria contains a colon (':') ... */
546 else if (p = strchr(str+1, ':')) {
547 if (*(p-1) == '!') {
548 *(p-1) = '\0';
549 psrch->fcn = NOEXISTS;
550 } else {
551 *p = '\0';
552 psrch->fcn = EXISTS;
554 psrch->cmp = p+1;
555 psrch->name = str;
556 psrch++;
558 } else {
559 /* Unable to malloc() string space. Clean up */
560 freesearchlist(rtnbuf);
561 noerror = FALSE;
563 /* Next criteria */
564 pp++;
566 /* Terminate list */
567 if (noerror) psrch->fcn = ENDLIST;
571 /* Return a pointer to allocated space (if any) */
572 return (rtnbuf);
576 * void freesearchlist(list)
577 * struct srch *list
579 * This function frees the resources allocated to the searchlist <list>.
581 * Arguments:
582 * list The list whose resources are to be released.
584 * Returns: void
587 static void
588 freesearchlist(struct srch *list)
590 /* Automatic data */
591 struct srch *psrch; /* Running ptr to structs */
594 /* Free all of the string space allocated for the structure elememts */
595 for (psrch = list; psrch->fcn != ENDLIST; psrch++) {
596 free(psrch->name);
599 /* Free the list space */
600 free(list);
604 * char **buildreturnlist()
606 * This function builds a list of addresses of character-strings
607 * to be returned from the linked-list of devices we've been
608 * building. It returns a pointer to the first item in that list.
610 * Arguments: none
612 * Returns: char **
613 * The address of the first item in the return list
616 static char **
617 buildreturnlist(void)
619 /* Automatic data */
620 char **list;
621 char **q;
622 struct deviceent *p;
626 * Allocate space for the return list,
627 * with space for the terminating node
630 if (list = malloc((devicelist.count+1)*sizeof (char *))) {
633 * Walk the list of accumulated devices, putting pointers to
634 * device names in the list to return
637 q = list;
638 for (p = devicelist.head->next; p; p = p->next) *q++ = p->name;
640 /* End the list with a null-pointer */
641 *q = NULL;
645 /* Return a pointer to the list we've built */
646 return (list);
650 * char **makealiaslist(devices)
651 * char **devices List of aliases
653 * Builds a list of aliases of the devices in the "devices"
654 * list. This list will be terminated by (char *) NULL and
655 * will have the same number of elements as "devices". If
656 * a device couldn't be found, that alias will be "". There
657 * will be a one-to-one correspondence of devices to aliases
658 * in the device list "devices" and the generated list.
660 * Arguments:
661 * devices The list of devices to derive aliases from
663 * Returns: char **
664 * The address of the list of addresses of aliases. The list
665 * and aliases will be allocated using the malloc() function.
668 static char **
669 makealiaslist(char **devices)
671 /* Automatic data */
672 char **pp; /* Running ptr to (char *) */
673 char **qq; /* Running ptr to (char *) */
674 char **aliases; /* List being returned */
675 char *alias; /* Alias of current device */
676 int olderrno; /* Value of errno on entry */
677 int noerror; /* Flag, TRUE if all's well */
678 int n; /* Count of entries in "devices" */
681 noerror = TRUE;
682 olderrno = errno;
683 if (devices) {
685 /* Get the number of entries in the constaint list */
686 for (n = 1, pp = devices; *pp; pp++) n++;
688 /* Get space for the alias list */
689 if (aliases = malloc(n*sizeof (char *))) {
691 /* Build the alias list */
692 qq = aliases;
693 for (pp = devices; noerror && *pp; pp++) {
695 /* Get the device's alias and put it in the list */
696 if (alias = devattr(*pp, DTAB_ALIAS)) *qq++ = alias;
697 else {
698 errno = olderrno;
699 if (alias = malloc(strlen("")+1))
700 *qq++ = strcpy(alias, "");
701 else {
702 /* No space for a null string? Yeech... */
703 for (qq = aliases; *qq; qq++) free(*qq);
704 free(aliases);
705 aliases = NULL;
706 noerror = FALSE;
710 if (noerror)
711 *qq = NULL;
715 } else
716 aliases = NULL; /* No constraint list */
718 /* Return ptr to generated list or NULL if none or error */
719 return (aliases);
723 * void freealiaslist(aliaslist)
724 * char **aliaslist;
726 * Free the space allocated to the aliaslist. It frees the space
727 * allocated to the character-strings referenced by the list then
728 * it frees the list.
730 * Arguments:
731 * aliaslist The address of the first item in the list of
732 * aliases that is to be freed
734 * Returns: void
737 static void
738 freealiaslist(char **aliaslist) /* Ptr to new device list */
740 /* Automatic Data */
741 char **pp; /* Running pointer */
743 /* If there's a list ... */
744 if (aliaslist) {
746 /* For each entry in the old list, free the entry */
747 for (pp = aliaslist; *pp; pp++) free(*pp);
749 /* Free the list */
750 free(aliaslist);
755 * char *getnextmatch(criteria, options)
756 * struct srch *criteria
757 * int options
759 * Gets the next device in the device table that matches the criteria.
760 * Returns the alias of that device.
762 * Arguments:
763 * criteria The linked list of criteria to use to match a device
764 * options Options modifying the criteria (only one that's really
765 * important is the DTAB_ANDCRITERIA flag)
767 * Returns: char *
768 * A pointer to a malloc()ed string containing the alias of the next
769 * device that matches the criteria, or (char *) NULL if none.
772 static char *
773 getnextmatch(struct srch *criteria, int options)
775 /* Automatic data */
776 struct devtabent *devtabent; /* Ptr to current record */
777 char *alias; /* Alias of device found */
778 int notdone; /* Flag, done yet? */
779 int noerror; /* Flag, had an error yet? */
783 * Initializations:
784 * - No alias yet
785 * - Not finished yet
786 * - Make sure there are criteria we're to use
789 alias = NULL;
790 notdone = TRUE;
791 noerror = TRUE;
793 /* If we're to "and" the criteria... */
794 if (options & DTAB_ANDCRITERIA) {
797 * Search the device table until we've got a record that matches
798 * all of the criteria or we run out of records
801 while (notdone && (devtabent = _getdevtabent())) {
802 if (!devtabent->comment) {
803 if (!criteria || matchallcriteria(devtabent, criteria)) {
804 if (alias = malloc(strlen(devtabent->alias)+1))
805 (void) strcpy(alias, devtabent->alias);
806 else noerror = FALSE;
807 notdone = FALSE;
810 _freedevtabent(devtabent);
812 } else {
815 * Search the device table until we've got a record that matches
816 * any of the criteria or we run out of records
819 while (notdone && (devtabent = _getdevtabent())) {
820 if (!devtabent->comment) {
821 if (!criteria || matchanycriteria(devtabent, criteria)) {
822 if (alias = malloc(strlen(devtabent->alias)+1))
823 (void) strcpy(alias, devtabent->alias);
824 else noerror = FALSE;
825 notdone = FALSE;
828 _freedevtabent(devtabent);
833 /* Return pointer to extracted alias (or NULL if none) */
834 if ((alias == NULL) && noerror) errno = ENOENT;
835 return (alias);
839 * int matchallcriteria(devtabent, criteria)
841 * This function examines the record contained in "devtabent" and
842 * determines if that record meets all of the criteria specified by
843 * "criteria".
845 * Arguments:
846 * struct devtabent *devtabent The device table entry to examine.
847 * struct srch *criteria The criteria to match.
849 * Returns: int
850 * Returns TRUE if the record matches criteria, FALSE otherwise.
853 static int
854 matchallcriteria(
855 struct devtabent *ent, /* Entry to check */
856 struct srch *criteria) /* Criteria governing match */
858 /* Automatic data */
859 struct srch *p; /* Pointer to current criteria */
860 struct attrval *q; /* Pointer to current attr/val pair */
861 int notfound; /* TRUE if attr found in list */
862 int failed; /* TRUE if record failed to match */
865 /* Test only if there's criteria to test against */
866 if (criteria && (criteria->fcn != ENDLIST)) {
868 failed = FALSE;
869 for (p = criteria; !failed && (p->fcn != ENDLIST); p++) {
872 * Don't compare against this criteria if it's function is
873 * "IGNORE"
875 if (p->fcn != IGNORE) {
876 if (p->fcn != NOEXISTS) {
878 /* Alias? */
879 if (strcmp(p->name, DTAB_ALIAS) == 0)
880 failed = !matches(ent->alias, p->cmp, p->fcn);
882 /* Char special device? */
883 else if (strcmp(p->name, DTAB_CDEVICE) == 0)
884 failed = !matches(ent->cdevice, p->cmp, p->fcn);
886 /* Block special device? */
887 else if (strcmp(p->name, DTAB_BDEVICE) == 0)
888 failed = !matches(ent->bdevice, p->cmp, p->fcn);
890 /* Pathname? */
891 else if (strcmp(p->name, DTAB_PATHNAME) == 0)
892 failed = !matches(ent->pathname, p->cmp, p->fcn);
894 /* Check other attributes... */
895 else {
896 notfound = TRUE;
897 q = ent->attrlist;
898 while (notfound && q) {
899 if (strcmp(p->name, q->attr) == 0) {
900 notfound = FALSE;
901 if (!matches(q->val, p->cmp, p->fcn))
902 failed = TRUE;
903 } else q = q->next;
905 if (notfound) failed = TRUE;
907 } else {
908 if (strcmp(p->name, DTAB_ALIAS) == 0) failed = TRUE;
909 else if (strcmp(p->name, DTAB_CDEVICE) == 0)
910 failed = FALSE;
911 else if (strcmp(p->name, DTAB_BDEVICE) == 0)
912 failed = FALSE;
913 else if (strcmp(p->name, DTAB_PATHNAME) == 0)
914 failed = FALSE;
915 else {
916 q = ent->attrlist;
917 while (!failed && q) {
918 if (strcmp(p->name, q->attr) == 0)
919 failed = TRUE;
920 else q = q->next;
925 } /* Search function is not "IGNORE" */
927 } /* for loop, checking each criteria */
929 } /* if (criteria) */
931 else failed = FALSE; /* No criteria specified, it's a match */
934 /* Return a value indicating if the record matches all criteria */
935 return (!failed);
939 * int matchanycriteria(devtabent, criteria)
941 * This function examines the record contained in "devtabent" and
942 * determines if that record meets any of the criteria specified by
943 * "criteria".
945 * Arguments:
946 * struct devtabent *devtabent The device table entry to examine.
947 * struct srch *criteria The criteria to match.
949 * Returns: int
950 * Returns TRUE if the record matches criteria, FALSE otherwise.
953 static int
954 matchanycriteria(
955 struct devtabent *ent, /* Entry to check */
956 struct srch *criteria) /* Criteria governing match */
958 /* Automatic data */
959 struct srch *p; /* Pointer to current criteria */
960 struct attrval *q; /* Pointer to current attr/val pair */
961 int matched; /* FLAG: TRUE if record matched */
962 int found; /* FLAG: TRUE if attribute found */
965 /* Test only if there's criteria to test against */
966 if (criteria && (criteria->fcn != ENDLIST)) {
968 matched = FALSE;
969 for (p = criteria; !matched && (p->fcn != ENDLIST); p++) {
972 * Don't compare against this criteria if it's function is
973 * "IGNORE"
975 if (p->fcn != IGNORE) {
976 if (p->fcn != NOEXISTS) {
978 /* Alias? */
979 if (strcmp(p->name, DTAB_ALIAS) == 0)
980 matched = matches(ent->alias, p->cmp, p->fcn);
982 /* Char special device? */
983 else if (strcmp(p->name, DTAB_CDEVICE) == 0)
984 matched = matches(ent->cdevice, p->cmp, p->fcn);
986 /* Block special device? */
987 else if (strcmp(p->name, DTAB_BDEVICE) == 0)
988 matched = matches(ent->bdevice, p->cmp, p->fcn);
990 /* Pathname? */
991 else if (strcmp(p->name, DTAB_PATHNAME) == 0)
992 matched = matches(ent->pathname, p->cmp, p->fcn);
994 /* Check other attributes... */
995 else {
996 q = ent->attrlist;
997 found = FALSE;
998 while (!found && q)
999 if (strcmp(p->name, q->attr) == 0) {
1000 matched = matches(q->val, p->cmp, p->fcn);
1001 found = TRUE;
1002 } else q = q->next;
1004 } else {
1005 if (strcmp(p->name, DTAB_ALIAS) == 0) matched = FALSE;
1006 else if (strcmp(p->name, DTAB_CDEVICE) == 0)
1007 matched = FALSE;
1008 else if (strcmp(p->name, DTAB_BDEVICE) == 0)
1009 matched = FALSE;
1010 else if (strcmp(p->name, DTAB_PATHNAME) == 0)
1011 matched = FALSE;
1012 else {
1013 q = ent->attrlist;
1014 matched = TRUE;
1015 while (matched && q) {
1016 if (strcmp(p->name, q->attr) == 0)
1017 matched = FALSE;
1018 else q = q->next;
1022 } /* Search function is not "IGNORE" */
1024 } /* for loop, checking each criteria */
1026 } /* if (criteria) */
1028 else matched = TRUE; /* No criteria specified, it's a match */
1031 /* Return a value indicating if the record matches all criteria */
1032 return (matched);
1036 * int matches(value, compare, function)
1037 * char *value
1038 * char *compare
1039 * int function
1041 * This function sees if the operation <function> is satisfied by
1042 * comparing the value <value> with <compare>. It returns TRUE
1043 * if so, FALSE otherwise.
1045 * Arguments:
1046 * value Value to compare
1047 * compare Value to compare against
1048 * function Function to be satisfied
1050 * Returns: int
1051 * TRUE if the function is satisfied, FALSE otherwise
1054 static int
1055 matches(char *value, char *compare, int function)
1057 /* Automatic data */
1058 int rtn; /* Value to return */
1061 if (value == NULL)
1062 value = "";
1064 /* Do case depending on the function */
1065 switch (function) {
1067 /* attr=val */
1068 case EQUAL:
1069 rtn = (strcmp(value, compare) == 0);
1070 break;
1072 /* attr!=val */
1073 case NOTEQUAL:
1074 rtn = (strcmp(value, compare) != 0);
1075 break;
1077 /* attr:* */
1078 case EXISTS:
1079 rtn = TRUE;
1080 break;
1082 /* attr!:* */
1083 case NOEXISTS:
1084 rtn = FALSE;
1085 break;
1087 /* Shouldn't get here... */
1088 default:
1089 rtn = FALSE;
1090 break;
1093 /* Return a value indicating if the match was made */
1094 return (rtn);