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