17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
545916cd2Sjpk * Common Development and Distribution License (the "License").
645916cd2Sjpk * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*d75d0dc9Stz204579 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
277c478bd9Sstevel@tonic-gate
2845916cd2Sjpk #include <ctype.h>
2945916cd2Sjpk #include <string.h>
3045916cd2Sjpk #include <stdlib.h>
3145916cd2Sjpk #include <tsol/label.h>
3245916cd2Sjpk #include <bsm/devices.h>
3345916cd2Sjpk #include <bsm/devalloc.h>
3445916cd2Sjpk
3545916cd2Sjpk extern char *_strdup_null(char *);
3645916cd2Sjpk
377c478bd9Sstevel@tonic-gate static struct _dabuff {
387c478bd9Sstevel@tonic-gate FILE *_daf; /* pointer into /etc/security/device_allocate */
397c478bd9Sstevel@tonic-gate devalloc_t _interpdevalloc;
4045916cd2Sjpk char _interpdaline[DA_BUFSIZE + 1];
417c478bd9Sstevel@tonic-gate char *_DEVALLOC;
427c478bd9Sstevel@tonic-gate } *__dabuff;
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate #define daf (_da->_daf)
457c478bd9Sstevel@tonic-gate #define interpdevalloc (_da->_interpdevalloc)
4645916cd2Sjpk #define interpdaline (_da->_interpdaline)
4745916cd2Sjpk #define DEVALLOC_FILE (_da->_DEVALLOC)
4845916cd2Sjpk static devalloc_t *da_interpret(char *);
4945916cd2Sjpk
5045916cd2Sjpk int da_matchname(devalloc_t *, char *);
5145916cd2Sjpk int da_matchtype(devalloc_t *, char *);
5245916cd2Sjpk
5345916cd2Sjpk static int system_labeled = 0;
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate /*
5645916cd2Sjpk * trim_white -
5745916cd2Sjpk * trims off leading and trailing white space from input string.
5845916cd2Sjpk * The leading white space is skipped by moving the pointer forward.
5945916cd2Sjpk * The trailing white space is removed by nulling the white space
6045916cd2Sjpk * characters.
6145916cd2Sjpk * returns pointer to non-white string, else returns NULL if input string
6245916cd2Sjpk * is null or if the resulting string has zero length.
637c478bd9Sstevel@tonic-gate */
6445916cd2Sjpk char *
trim_white(char * ptr)6545916cd2Sjpk trim_white(char *ptr)
667c478bd9Sstevel@tonic-gate {
6745916cd2Sjpk char *tptr;
6845916cd2Sjpk
697c478bd9Sstevel@tonic-gate if (ptr == NULL)
707c478bd9Sstevel@tonic-gate return (NULL);
7145916cd2Sjpk while (isspace(*ptr))
727c478bd9Sstevel@tonic-gate ptr++;
7345916cd2Sjpk tptr = ptr + strlen(ptr);
7445916cd2Sjpk while (tptr != ptr && isspace(tptr[-1]))
7545916cd2Sjpk --tptr;
767c478bd9Sstevel@tonic-gate *tptr = '\0';
7745916cd2Sjpk if (*ptr == '\0')
787c478bd9Sstevel@tonic-gate return (NULL);
7945916cd2Sjpk
807c478bd9Sstevel@tonic-gate return (ptr);
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate /*
8445916cd2Sjpk * pack_white -
8545916cd2Sjpk * trims off multiple occurrences of white space from input string.
8645916cd2Sjpk * returns the number of spaces retained
877c478bd9Sstevel@tonic-gate */
8845916cd2Sjpk int
pack_white(char * ptr)8945916cd2Sjpk pack_white(char *ptr)
907c478bd9Sstevel@tonic-gate {
9145916cd2Sjpk int cnt = 0;
9245916cd2Sjpk char *tptr, ch;
937c478bd9Sstevel@tonic-gate
9445916cd2Sjpk if (ptr == NULL)
957c478bd9Sstevel@tonic-gate return (0);
9645916cd2Sjpk tptr = ptr;
9745916cd2Sjpk while (isspace(*tptr))
9845916cd2Sjpk tptr++;
9945916cd2Sjpk for (;;) {
10045916cd2Sjpk while ((ch = *tptr) != '\0' && !isspace(ch)) {
10145916cd2Sjpk *ptr++ = ch;
10245916cd2Sjpk tptr++;
1037c478bd9Sstevel@tonic-gate }
10445916cd2Sjpk while (isspace(*tptr))
10545916cd2Sjpk tptr++;
10645916cd2Sjpk if (*tptr == '\0')
10745916cd2Sjpk break;
10845916cd2Sjpk *ptr++ = ' ';
10945916cd2Sjpk cnt++;
1107c478bd9Sstevel@tonic-gate }
11145916cd2Sjpk *ptr = '\0';
1127c478bd9Sstevel@tonic-gate
11345916cd2Sjpk return (cnt);
11445916cd2Sjpk }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate /*
11745916cd2Sjpk * getdadmline -
11845916cd2Sjpk * reads one device_alloc/device_maps line from stream into buff of len
11945916cd2Sjpk * bytes. Continued lines from stream are concatenated into one line in
12045916cd2Sjpk * buff. Comments are removed from buff.
12145916cd2Sjpk * returns the number of characters in buff, else returns 0 if no
12245916cd2Sjpk * characters are read or an error occurred.
1237c478bd9Sstevel@tonic-gate */
12445916cd2Sjpk int
getdadmline(char * buff,int len,FILE * stream)12545916cd2Sjpk getdadmline(char *buff, int len, FILE *stream)
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate int tmpcnt;
1287c478bd9Sstevel@tonic-gate int charcnt = 0;
1297c478bd9Sstevel@tonic-gate int fileerr = 0;
13045916cd2Sjpk int contline = 0;
13145916cd2Sjpk char *cp;
13245916cd2Sjpk char *ccp;
13345916cd2Sjpk
1347c478bd9Sstevel@tonic-gate do {
1357c478bd9Sstevel@tonic-gate cp = buff;
1367c478bd9Sstevel@tonic-gate *cp = NULL;
1377c478bd9Sstevel@tonic-gate do {
13845916cd2Sjpk contline = 0;
1397c478bd9Sstevel@tonic-gate if (fgets(cp, len - charcnt, stream) == NULL) {
1407c478bd9Sstevel@tonic-gate fileerr = 1;
1417c478bd9Sstevel@tonic-gate break;
1427c478bd9Sstevel@tonic-gate }
14345916cd2Sjpk ccp = strchr(cp, '\n');
1447c478bd9Sstevel@tonic-gate if (ccp != NULL) {
14545916cd2Sjpk if (ccp != cp && ccp[-1] == '\\') {
14645916cd2Sjpk ccp--;
1477c478bd9Sstevel@tonic-gate contline = 1;
14845916cd2Sjpk }
1497c478bd9Sstevel@tonic-gate else
1507c478bd9Sstevel@tonic-gate contline = 0;
1517c478bd9Sstevel@tonic-gate *ccp = NULL;
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate tmpcnt = strlen(cp);
1547c478bd9Sstevel@tonic-gate cp += tmpcnt;
1557c478bd9Sstevel@tonic-gate charcnt += tmpcnt;
1567c478bd9Sstevel@tonic-gate } while ((contline) || (charcnt == 0));
1577c478bd9Sstevel@tonic-gate ccp = strpbrk(buff, "#");
1587c478bd9Sstevel@tonic-gate if (ccp != NULL)
1597c478bd9Sstevel@tonic-gate *ccp = NULL;
1607c478bd9Sstevel@tonic-gate charcnt = strlen(buff);
1617c478bd9Sstevel@tonic-gate } while ((fileerr == 0) && (charcnt == 0));
16245916cd2Sjpk
16345916cd2Sjpk if (fileerr && !charcnt)
1647c478bd9Sstevel@tonic-gate return (0);
1657c478bd9Sstevel@tonic-gate else
1667c478bd9Sstevel@tonic-gate return (charcnt);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate
16945916cd2Sjpk /*
17045916cd2Sjpk * _daalloc -
17145916cd2Sjpk * allocates common buffers and structures.
17245916cd2Sjpk * returns pointer to the new structure, else returns NULL on error.
17345916cd2Sjpk */
17445916cd2Sjpk static struct _dabuff *
_daalloc(void)17545916cd2Sjpk _daalloc(void)
1767c478bd9Sstevel@tonic-gate {
17745916cd2Sjpk struct _dabuff *_da = __dabuff;
17845916cd2Sjpk
17945916cd2Sjpk if (_da == NULL) {
18045916cd2Sjpk _da = (struct _dabuff *)calloc((unsigned)1,
18145916cd2Sjpk (unsigned)sizeof (*__dabuff));
18245916cd2Sjpk if (_da == NULL)
18345916cd2Sjpk return (NULL);
18445916cd2Sjpk DEVALLOC_FILE = "/etc/security/device_allocate";
18545916cd2Sjpk daf = NULL;
18645916cd2Sjpk __dabuff = _da;
18745916cd2Sjpk system_labeled = is_system_labeled();
18845916cd2Sjpk }
18945916cd2Sjpk
19045916cd2Sjpk return (__dabuff);
19145916cd2Sjpk }
19245916cd2Sjpk
19345916cd2Sjpk /*
19445916cd2Sjpk * getdadmfield -
19545916cd2Sjpk * gets individual fields separated by skip in ptr.
19645916cd2Sjpk */
19745916cd2Sjpk char *
getdadmfield(char * ptr,char * skip)19845916cd2Sjpk getdadmfield(char *ptr, char *skip)
19945916cd2Sjpk {
20045916cd2Sjpk static char *tptr = NULL;
20145916cd2Sjpk char *pend;
20245916cd2Sjpk
20345916cd2Sjpk /* check for a continuing search */
2047c478bd9Sstevel@tonic-gate if (ptr == NULL)
2057c478bd9Sstevel@tonic-gate ptr = tptr;
20645916cd2Sjpk /* check for source end */
20745916cd2Sjpk if (ptr == NULL || *ptr == '\0')
2087c478bd9Sstevel@tonic-gate return (NULL);
20945916cd2Sjpk /* find terminator */
21045916cd2Sjpk pend = strpbrk(ptr, skip);
21145916cd2Sjpk /* terminate and set continuation pointer */
21245916cd2Sjpk if (pend != NULL) {
21345916cd2Sjpk *pend++ = '\0';
21445916cd2Sjpk tptr = pend;
21545916cd2Sjpk } else
21645916cd2Sjpk tptr = NULL;
2177c478bd9Sstevel@tonic-gate /*
21845916cd2Sjpk * trim off any surrounding white space, return what's left
2197c478bd9Sstevel@tonic-gate */
2207c478bd9Sstevel@tonic-gate
22145916cd2Sjpk return (trim_white(ptr));
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate /*
22545916cd2Sjpk * setdaent -
22645916cd2Sjpk * rewinds the device_allocate file to the begining.
2277c478bd9Sstevel@tonic-gate */
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate void
setdaent(void)23045916cd2Sjpk setdaent(void)
2317c478bd9Sstevel@tonic-gate {
23245916cd2Sjpk struct _dabuff *_da = _daalloc();
2337c478bd9Sstevel@tonic-gate
23445916cd2Sjpk if (_da == NULL)
2357c478bd9Sstevel@tonic-gate return;
23645916cd2Sjpk if (daf == NULL)
237004388ebScasper daf = fopen(DEVALLOC_FILE, "rF");
23845916cd2Sjpk else
2397c478bd9Sstevel@tonic-gate rewind(daf);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate /*
24345916cd2Sjpk * enddaent -
24445916cd2Sjpk * closes device_allocate file.
2457c478bd9Sstevel@tonic-gate */
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate void
enddaent(void)24845916cd2Sjpk enddaent(void)
2497c478bd9Sstevel@tonic-gate {
25045916cd2Sjpk struct _dabuff *_da = _daalloc();
2517c478bd9Sstevel@tonic-gate
25245916cd2Sjpk if (_da == NULL)
2537c478bd9Sstevel@tonic-gate return;
2547c478bd9Sstevel@tonic-gate if (daf != NULL) {
2557c478bd9Sstevel@tonic-gate (void) fclose(daf);
2567c478bd9Sstevel@tonic-gate daf = NULL;
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate /*
26145916cd2Sjpk * setdafile -
26245916cd2Sjpk * changes the default device_allocate file to the one specified.
26345916cd2Sjpk * It does not close the previous file. If this is desired, enddaent
26445916cd2Sjpk * should be called prior to setdafile.
2657c478bd9Sstevel@tonic-gate */
2667c478bd9Sstevel@tonic-gate void
setdafile(char * file)26745916cd2Sjpk setdafile(char *file)
2687c478bd9Sstevel@tonic-gate {
26945916cd2Sjpk struct _dabuff *_da = _daalloc();
2707c478bd9Sstevel@tonic-gate
27145916cd2Sjpk if (_da == NULL)
2727c478bd9Sstevel@tonic-gate return;
2737c478bd9Sstevel@tonic-gate if (daf != NULL) {
2747c478bd9Sstevel@tonic-gate (void) fclose(daf);
2757c478bd9Sstevel@tonic-gate daf = NULL;
2767c478bd9Sstevel@tonic-gate }
27745916cd2Sjpk DEVALLOC_FILE = file;
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
28045916cd2Sjpk void
freedaent(devalloc_t * dap)28145916cd2Sjpk freedaent(devalloc_t *dap)
28245916cd2Sjpk {
28345916cd2Sjpk if (dap == NULL)
28445916cd2Sjpk return;
28545916cd2Sjpk _kva_free(dap->da_devopts);
28645916cd2Sjpk dap->da_devopts = NULL;
28745916cd2Sjpk }
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate /*
29045916cd2Sjpk * getdaon -
29145916cd2Sjpk * checks if device_allocate has string DEVICE_ALLOCATION=ON or
29245916cd2Sjpk * DEVICE_ALLOCATION=OFF string in it.
29345916cd2Sjpk * returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
29445916cd2Sjpk * DEVICE_ALLOCATION=OFF, -1 if neither string present.
29545916cd2Sjpk */
29645916cd2Sjpk int
getdaon()29745916cd2Sjpk getdaon()
29845916cd2Sjpk {
29945916cd2Sjpk int is_on = -1;
30045916cd2Sjpk char line1[DA_BUFSIZE + 1];
30145916cd2Sjpk struct _dabuff *_da = _daalloc();
30245916cd2Sjpk
30345916cd2Sjpk setdaent();
30445916cd2Sjpk if ((_da == NULL) || (daf == NULL)) {
30545916cd2Sjpk enddaent();
30645916cd2Sjpk return (is_on);
30745916cd2Sjpk }
30845916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
30945916cd2Sjpk if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) {
31045916cd2Sjpk is_on = 1;
31145916cd2Sjpk break;
31245916cd2Sjpk } else if (strncmp(line1, DA_OFF_STR,
31345916cd2Sjpk (strlen(DA_OFF_STR) - 1)) == 0) {
31445916cd2Sjpk is_on = 0;
31545916cd2Sjpk break;
31645916cd2Sjpk }
31745916cd2Sjpk }
31845916cd2Sjpk enddaent();
31945916cd2Sjpk
32045916cd2Sjpk return (is_on);
32145916cd2Sjpk }
32245916cd2Sjpk
32345916cd2Sjpk /*
32445916cd2Sjpk * getdaent -
32545916cd2Sjpk * When first called, returns a pointer to the first devalloc_t
32645916cd2Sjpk * structure in device_allocate; thereafter, it returns a pointer to the
32745916cd2Sjpk * next devalloc_t structure in the file. Thus, successive calls can be
32845916cd2Sjpk * used to search the entire file.
32945916cd2Sjpk * call to getdaent should be bracketed by setdaent and enddaent.
33045916cd2Sjpk * returns NULL on error.
3317c478bd9Sstevel@tonic-gate */
3327c478bd9Sstevel@tonic-gate devalloc_t *
getdaent(void)33345916cd2Sjpk getdaent(void)
3347c478bd9Sstevel@tonic-gate {
33545916cd2Sjpk char line1[DA_BUFSIZE + 1];
3367c478bd9Sstevel@tonic-gate devalloc_t *da;
33745916cd2Sjpk struct _dabuff *_da = _daalloc();
3387c478bd9Sstevel@tonic-gate
33945916cd2Sjpk if ((_da == 0) || (daf == NULL))
3407c478bd9Sstevel@tonic-gate return (NULL);
3417c478bd9Sstevel@tonic-gate
34245916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
34345916cd2Sjpk if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) ||
34445916cd2Sjpk (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0))
3457c478bd9Sstevel@tonic-gate continue;
34645916cd2Sjpk if ((da = da_interpret(line1)) == NULL)
34745916cd2Sjpk continue;
34845916cd2Sjpk return (da);
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate
35145916cd2Sjpk return (NULL);
35245916cd2Sjpk }
35345916cd2Sjpk
3547c478bd9Sstevel@tonic-gate /*
35545916cd2Sjpk * getdanam
35645916cd2Sjpk * searches from the beginning of device_allocate for the device specified
35745916cd2Sjpk * by its name.
35845916cd2Sjpk * call to getdanam should be bracketed by setdaent and enddaent.
35945916cd2Sjpk * returns pointer to devalloc_t for the device if it is found, else
36045916cd2Sjpk * returns NULL if device not found or in case of error.
3617c478bd9Sstevel@tonic-gate */
36245916cd2Sjpk devalloc_t *
getdanam(char * name)36345916cd2Sjpk getdanam(char *name)
3647c478bd9Sstevel@tonic-gate {
36545916cd2Sjpk char line[DA_BUFSIZE + 1];
36645916cd2Sjpk devalloc_t *da;
36745916cd2Sjpk struct _dabuff *_da = _daalloc();
3687c478bd9Sstevel@tonic-gate
36945916cd2Sjpk if ((name == NULL) || (_da == 0) || (daf == NULL))
37045916cd2Sjpk return (NULL);
37145916cd2Sjpk
37245916cd2Sjpk while (getdadmline(line, (int)sizeof (line), daf) != 0) {
37345916cd2Sjpk if (strstr(line, name) == NULL)
37445916cd2Sjpk continue;
37545916cd2Sjpk if ((da = da_interpret(line)) == NULL)
37645916cd2Sjpk continue;
37745916cd2Sjpk if (da_matchname(da, name)) {
37845916cd2Sjpk enddaent();
37945916cd2Sjpk return (da);
38045916cd2Sjpk }
38145916cd2Sjpk freedaent(da);
38245916cd2Sjpk }
38345916cd2Sjpk
38445916cd2Sjpk return (NULL);
38545916cd2Sjpk }
38645916cd2Sjpk
38745916cd2Sjpk /*
38845916cd2Sjpk * getdatype -
38945916cd2Sjpk * searches from the beginning of device_allocate for the device specified
39045916cd2Sjpk * by its type.
39145916cd2Sjpk * call to getdatype should be bracketed by setdaent and enddaent.
39245916cd2Sjpk * returns pointer to devalloc_t for the device if it is found, else
39345916cd2Sjpk * returns NULL if device not found or in case of error.
39445916cd2Sjpk */
39545916cd2Sjpk devalloc_t *
getdatype(char * type)39645916cd2Sjpk getdatype(char *type)
39745916cd2Sjpk {
39845916cd2Sjpk char line1[DA_BUFSIZE + 1];
39945916cd2Sjpk devalloc_t *da;
40045916cd2Sjpk struct _dabuff *_da = _daalloc();
40145916cd2Sjpk
40245916cd2Sjpk if ((type == NULL) || (_da == NULL) || (daf == NULL))
40345916cd2Sjpk return (NULL);
40445916cd2Sjpk
40545916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
40645916cd2Sjpk if (strstr(line1, type) == NULL)
40745916cd2Sjpk continue;
40845916cd2Sjpk if ((da = da_interpret(line1)) == NULL)
40945916cd2Sjpk continue;
41045916cd2Sjpk if (da_matchtype(da, type))
41145916cd2Sjpk return (da);
41245916cd2Sjpk freedaent(da);
41345916cd2Sjpk }
41445916cd2Sjpk
41545916cd2Sjpk return (NULL);
41645916cd2Sjpk }
41745916cd2Sjpk
41845916cd2Sjpk /*
41945916cd2Sjpk * da_matchname -
42045916cd2Sjpk * checks if the specified devalloc_t is for the device specified.
42145916cd2Sjpk * returns 1 if it is, else returns 0.
42245916cd2Sjpk */
42345916cd2Sjpk int
da_matchname(devalloc_t * dap,char * name)42445916cd2Sjpk da_matchname(devalloc_t *dap, char *name)
42545916cd2Sjpk {
42645916cd2Sjpk if (dap->da_devname == NULL)
4277c478bd9Sstevel@tonic-gate return (0);
42845916cd2Sjpk
42945916cd2Sjpk return ((strcmp(dap->da_devname, name) == 0));
43045916cd2Sjpk }
43145916cd2Sjpk
43245916cd2Sjpk /*
43345916cd2Sjpk * da_matchtype -
43445916cd2Sjpk * checks if the specified devalloc_t is for the device type specified.
43545916cd2Sjpk * returns 1 if match found, else, returns 0.
43645916cd2Sjpk */
43745916cd2Sjpk int
da_matchtype(devalloc_t * da,char * type)43845916cd2Sjpk da_matchtype(devalloc_t *da, char *type)
43945916cd2Sjpk {
44045916cd2Sjpk if (da->da_devtype == NULL)
4417c478bd9Sstevel@tonic-gate return (0);
44245916cd2Sjpk
44345916cd2Sjpk return ((strcmp(da->da_devtype, type) == 0));
44445916cd2Sjpk }
44545916cd2Sjpk
44645916cd2Sjpk /*
44745916cd2Sjpk * da_match -
44845916cd2Sjpk * calls da_matchname or da_matchdev as appropriate.
44945916cd2Sjpk */
45045916cd2Sjpk int
da_match(devalloc_t * dap,da_args * dargs)45145916cd2Sjpk da_match(devalloc_t *dap, da_args *dargs)
45245916cd2Sjpk {
45345916cd2Sjpk if (dargs->devinfo->devname)
45445916cd2Sjpk return (da_matchname(dap, dargs->devinfo->devname));
45545916cd2Sjpk else if (dargs->devinfo->devtype)
45645916cd2Sjpk return (da_matchtype(dap, dargs->devinfo->devtype));
45745916cd2Sjpk
4587c478bd9Sstevel@tonic-gate return (0);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate /*
46245916cd2Sjpk * da_interpret -
46345916cd2Sjpk * parses val and initializes pointers in devalloc_t.
46445916cd2Sjpk * returns pointer to parsed devalloc_t entry, else returns NULL on error.
4657c478bd9Sstevel@tonic-gate */
4667c478bd9Sstevel@tonic-gate static devalloc_t *
da_interpret(char * val)46745916cd2Sjpk da_interpret(char *val)
4687c478bd9Sstevel@tonic-gate {
46945916cd2Sjpk struct _dabuff *_da = _daalloc();
47045916cd2Sjpk char *opts;
47145916cd2Sjpk int i;
47245916cd2Sjpk kva_t *kvap;
47345916cd2Sjpk kv_t *kvp;
4747c478bd9Sstevel@tonic-gate
47545916cd2Sjpk if (_da == NULL)
47645916cd2Sjpk return (NULL);
4777c478bd9Sstevel@tonic-gate
47845916cd2Sjpk (void) strcpy(interpdaline, val);
47945916cd2Sjpk interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER);
48045916cd2Sjpk interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER);
48145916cd2Sjpk opts = getdadmfield(NULL, KV_DELIMITER);
48245916cd2Sjpk (void) getdadmfield(NULL, KV_DELIMITER); /* reserved field */
48345916cd2Sjpk interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER);
48445916cd2Sjpk interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER);
48545916cd2Sjpk interpdevalloc.da_devopts = NULL;
48645916cd2Sjpk if (interpdevalloc.da_devname == NULL ||
48745916cd2Sjpk interpdevalloc.da_devtype == NULL)
48845916cd2Sjpk return (NULL);
48945916cd2Sjpk if ((opts != NULL) &&
49045916cd2Sjpk (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) {
49145916cd2Sjpk interpdevalloc.da_devopts =
49245916cd2Sjpk _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT);
49345916cd2Sjpk }
49445916cd2Sjpk /* remove any extraneous whitespace in the options */
49545916cd2Sjpk if ((kvap = interpdevalloc.da_devopts) != NULL) {
49645916cd2Sjpk for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
49745916cd2Sjpk (void) pack_white(kvp->key);
49845916cd2Sjpk (void) pack_white(kvp->value);
49945916cd2Sjpk }
50045916cd2Sjpk }
50145916cd2Sjpk
50245916cd2Sjpk if (system_labeled) {
50345916cd2Sjpk /* if label range is not defined, use the default range. */
50445916cd2Sjpk int i = 0, nlen = 0;
50545916cd2Sjpk char *minstr = NULL, *maxstr = NULL;
50645916cd2Sjpk kva_t *nkvap = NULL;
50745916cd2Sjpk kv_t *ndata = NULL, *odata = NULL;
50845916cd2Sjpk
50945916cd2Sjpk if (kvap == NULL) {
51045916cd2Sjpk nlen = 2; /* minlabel, maxlabel */
51145916cd2Sjpk } else {
51245916cd2Sjpk nlen += kvap->length;
51345916cd2Sjpk if ((minstr = kva_match(kvap, DAOPT_MINLABEL)) == NULL)
51445916cd2Sjpk nlen++;
51545916cd2Sjpk if ((maxstr = kva_match(kvap, DAOPT_MAXLABEL)) == NULL)
51645916cd2Sjpk nlen++;
51745916cd2Sjpk }
51845916cd2Sjpk if ((minstr != NULL) && (maxstr != NULL))
51945916cd2Sjpk /*
52045916cd2Sjpk * label range provided; we don't need to construct
52145916cd2Sjpk * default range.
52245916cd2Sjpk */
52345916cd2Sjpk goto out;
52445916cd2Sjpk nkvap = _new_kva(nlen);
52545916cd2Sjpk ndata = nkvap->data;
52645916cd2Sjpk if (kvap != NULL) {
52745916cd2Sjpk for (i = 0; i < kvap->length; i++) {
52845916cd2Sjpk odata = kvap->data;
52945916cd2Sjpk ndata[i].key = _strdup_null(odata[i].key);
53045916cd2Sjpk ndata[i].value = _strdup_null(odata[i].value);
53145916cd2Sjpk nkvap->length++;
53245916cd2Sjpk }
53345916cd2Sjpk }
53445916cd2Sjpk if (minstr == NULL) {
53545916cd2Sjpk ndata[i].key = strdup(DAOPT_MINLABEL);
53645916cd2Sjpk ndata[i].value = strdup(DA_DEFAULT_MIN);
53745916cd2Sjpk nkvap->length++;
53845916cd2Sjpk i++;
53945916cd2Sjpk }
54045916cd2Sjpk if (maxstr == NULL) {
54145916cd2Sjpk ndata[i].key = strdup(DAOPT_MAXLABEL);
54245916cd2Sjpk ndata[i].value = strdup(DA_DEFAULT_MAX);
54345916cd2Sjpk nkvap->length++;
54445916cd2Sjpk }
54545916cd2Sjpk interpdevalloc.da_devopts = nkvap;
54645916cd2Sjpk }
54745916cd2Sjpk
54845916cd2Sjpk out:
5497c478bd9Sstevel@tonic-gate return (&interpdevalloc);
5507c478bd9Sstevel@tonic-gate }
551