xref: /titanic_54/usr/src/lib/libbsm/common/getdaent.c (revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e)
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
5*45916cd2Sjpk  * Common Development and Distribution License (the "License").
6*45916cd2Sjpk  * 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*45916cd2Sjpk  * Copyright 2006 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 
28*45916cd2Sjpk #ifndef lint
29*45916cd2Sjpk static char	sccsid[] = "%Z%%M% %I% %E% SMI";
307c478bd9Sstevel@tonic-gate #endif
317c478bd9Sstevel@tonic-gate 
32*45916cd2Sjpk #include <ctype.h>
33*45916cd2Sjpk #include <string.h>
34*45916cd2Sjpk #include <stdlib.h>
35*45916cd2Sjpk #include <tsol/label.h>
36*45916cd2Sjpk #include <bsm/devices.h>
37*45916cd2Sjpk #include <bsm/devalloc.h>
38*45916cd2Sjpk 
39*45916cd2Sjpk extern char *_strdup_null(char *);
40*45916cd2Sjpk 
417c478bd9Sstevel@tonic-gate static struct _dabuff {
427c478bd9Sstevel@tonic-gate 	FILE		*_daf;	/* pointer into /etc/security/device_allocate */
437c478bd9Sstevel@tonic-gate 	devalloc_t	_interpdevalloc;
44*45916cd2Sjpk 	char		_interpdaline[DA_BUFSIZE + 1];
457c478bd9Sstevel@tonic-gate 	char		 *_DEVALLOC;
467c478bd9Sstevel@tonic-gate } *__dabuff;
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #define	daf	(_da->_daf)
497c478bd9Sstevel@tonic-gate #define	interpdevalloc	(_da->_interpdevalloc)
50*45916cd2Sjpk #define	interpdaline	(_da->_interpdaline)
51*45916cd2Sjpk #define	DEVALLOC_FILE	(_da->_DEVALLOC)
52*45916cd2Sjpk static devalloc_t	*da_interpret(char *);
53*45916cd2Sjpk 
54*45916cd2Sjpk int da_matchname(devalloc_t *, char *);
55*45916cd2Sjpk int da_matchtype(devalloc_t *, char *);
56*45916cd2Sjpk 
57*45916cd2Sjpk static int system_labeled = 0;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
60*45916cd2Sjpk  * trim_white -
61*45916cd2Sjpk  *	trims off leading and trailing white space from input string.
62*45916cd2Sjpk  * 	The leading white space is skipped by moving the pointer forward.
63*45916cd2Sjpk  * 	The trailing white space is removed by nulling the white space
64*45916cd2Sjpk  *	characters.
65*45916cd2Sjpk  *	returns pointer to non-white string, else returns NULL if input string
66*45916cd2Sjpk  *	is null or if the resulting string has zero length.
677c478bd9Sstevel@tonic-gate  */
68*45916cd2Sjpk char *
69*45916cd2Sjpk trim_white(char *ptr)
707c478bd9Sstevel@tonic-gate {
71*45916cd2Sjpk 	char	*tptr;
72*45916cd2Sjpk 
737c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
747c478bd9Sstevel@tonic-gate 		return (NULL);
75*45916cd2Sjpk 	while (isspace(*ptr))
767c478bd9Sstevel@tonic-gate 		ptr++;
77*45916cd2Sjpk 	tptr = ptr + strlen(ptr);
78*45916cd2Sjpk 	while (tptr != ptr && isspace(tptr[-1]))
79*45916cd2Sjpk 		--tptr;
807c478bd9Sstevel@tonic-gate 	*tptr = '\0';
81*45916cd2Sjpk 	if (*ptr == '\0')
827c478bd9Sstevel@tonic-gate 		return (NULL);
83*45916cd2Sjpk 
847c478bd9Sstevel@tonic-gate 	return (ptr);
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /*
88*45916cd2Sjpk  * pack_white -
89*45916cd2Sjpk  *	trims off multiple occurrences of white space from input string.
90*45916cd2Sjpk  * 	returns the number of spaces retained
917c478bd9Sstevel@tonic-gate  */
92*45916cd2Sjpk int
93*45916cd2Sjpk pack_white(char *ptr)
947c478bd9Sstevel@tonic-gate {
95*45916cd2Sjpk 	int	cnt = 0;
96*45916cd2Sjpk 	char	*tptr, ch;
977c478bd9Sstevel@tonic-gate 
98*45916cd2Sjpk 	if (ptr == NULL)
997c478bd9Sstevel@tonic-gate 		return (0);
100*45916cd2Sjpk 	tptr = ptr;
101*45916cd2Sjpk 	while (isspace(*tptr))
102*45916cd2Sjpk 		tptr++;
103*45916cd2Sjpk 	for (;;) {
104*45916cd2Sjpk 		while ((ch = *tptr) != '\0' && !isspace(ch)) {
105*45916cd2Sjpk 			*ptr++ = ch;
106*45916cd2Sjpk 			tptr++;
1077c478bd9Sstevel@tonic-gate 		}
108*45916cd2Sjpk 		while (isspace(*tptr))
109*45916cd2Sjpk 			tptr++;
110*45916cd2Sjpk 		if (*tptr == '\0')
111*45916cd2Sjpk 			break;
112*45916cd2Sjpk 		*ptr++ = ' ';
113*45916cd2Sjpk 		cnt++;
1147c478bd9Sstevel@tonic-gate 	}
115*45916cd2Sjpk 	*ptr = '\0';
1167c478bd9Sstevel@tonic-gate 
117*45916cd2Sjpk 	return (cnt);
118*45916cd2Sjpk }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate /*
121*45916cd2Sjpk  * getdadmline -
122*45916cd2Sjpk  *	reads one device_alloc/device_maps line from stream into buff of len
123*45916cd2Sjpk  *	bytes. Continued lines from stream are concatenated into one line in
124*45916cd2Sjpk  *	buff. Comments are removed from buff.
125*45916cd2Sjpk  *	returns the number of characters in buff, else returns 0 if no
126*45916cd2Sjpk  * 	characters are read or an error occurred.
1277c478bd9Sstevel@tonic-gate  */
128*45916cd2Sjpk int
129*45916cd2Sjpk getdadmline(char *buff, int len, FILE *stream)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	int 	tmpcnt;
1327c478bd9Sstevel@tonic-gate 	int 	charcnt = 0;
1337c478bd9Sstevel@tonic-gate 	int 	fileerr = 0;
134*45916cd2Sjpk 	int 	contline = 0;
135*45916cd2Sjpk 	char 	*cp;
136*45916cd2Sjpk 	char 	*ccp;
137*45916cd2Sjpk 
1387c478bd9Sstevel@tonic-gate 	do {
1397c478bd9Sstevel@tonic-gate 		cp = buff;
1407c478bd9Sstevel@tonic-gate 		*cp = NULL;
1417c478bd9Sstevel@tonic-gate 		do {
142*45916cd2Sjpk 			contline = 0;
1437c478bd9Sstevel@tonic-gate 			if (fgets(cp, len - charcnt, stream) == NULL) {
1447c478bd9Sstevel@tonic-gate 				fileerr = 1;
1457c478bd9Sstevel@tonic-gate 				break;
1467c478bd9Sstevel@tonic-gate 			}
147*45916cd2Sjpk 			ccp = strchr(cp, '\n');
1487c478bd9Sstevel@tonic-gate 			if (ccp != NULL) {
149*45916cd2Sjpk 				if (ccp != cp && ccp[-1] == '\\') {
150*45916cd2Sjpk 					ccp--;
1517c478bd9Sstevel@tonic-gate 					contline = 1;
152*45916cd2Sjpk 				}
1537c478bd9Sstevel@tonic-gate 				else
1547c478bd9Sstevel@tonic-gate 					contline = 0;
1557c478bd9Sstevel@tonic-gate 				*ccp = NULL;
1567c478bd9Sstevel@tonic-gate 			}
1577c478bd9Sstevel@tonic-gate 			tmpcnt = strlen(cp);
1587c478bd9Sstevel@tonic-gate 			cp += tmpcnt;
1597c478bd9Sstevel@tonic-gate 			charcnt += tmpcnt;
1607c478bd9Sstevel@tonic-gate 		} while ((contline) || (charcnt == 0));
1617c478bd9Sstevel@tonic-gate 		ccp = strpbrk(buff, "#");
1627c478bd9Sstevel@tonic-gate 		if (ccp != NULL)
1637c478bd9Sstevel@tonic-gate 			*ccp = NULL;
1647c478bd9Sstevel@tonic-gate 		charcnt = strlen(buff);
1657c478bd9Sstevel@tonic-gate 	} while ((fileerr == 0) && (charcnt == 0));
166*45916cd2Sjpk 
167*45916cd2Sjpk 	if (fileerr && !charcnt)
1687c478bd9Sstevel@tonic-gate 		return (0);
1697c478bd9Sstevel@tonic-gate 	else
1707c478bd9Sstevel@tonic-gate 		return (charcnt);
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
173*45916cd2Sjpk /*
174*45916cd2Sjpk  * _daalloc -
175*45916cd2Sjpk  *	allocates common buffers and structures.
176*45916cd2Sjpk  * 	returns pointer to the new structure, else returns NULL on error.
177*45916cd2Sjpk  */
178*45916cd2Sjpk static struct _dabuff *
179*45916cd2Sjpk _daalloc(void)
1807c478bd9Sstevel@tonic-gate {
181*45916cd2Sjpk 	struct _dabuff	*_da = __dabuff;
182*45916cd2Sjpk 
183*45916cd2Sjpk 	if (_da == NULL) {
184*45916cd2Sjpk 		_da = (struct _dabuff *)calloc((unsigned)1,
185*45916cd2Sjpk 		    (unsigned)sizeof (*__dabuff));
186*45916cd2Sjpk 		if (_da == NULL)
187*45916cd2Sjpk 			return (NULL);
188*45916cd2Sjpk 		DEVALLOC_FILE = "/etc/security/device_allocate";
189*45916cd2Sjpk 		daf = NULL;
190*45916cd2Sjpk 		__dabuff = _da;
191*45916cd2Sjpk 		system_labeled = is_system_labeled();
192*45916cd2Sjpk 	}
193*45916cd2Sjpk 
194*45916cd2Sjpk 	return (__dabuff);
195*45916cd2Sjpk }
196*45916cd2Sjpk 
197*45916cd2Sjpk /*
198*45916cd2Sjpk  * getdadmfield -
199*45916cd2Sjpk  *	gets individual fields separated by skip in ptr.
200*45916cd2Sjpk  */
201*45916cd2Sjpk char *
202*45916cd2Sjpk getdadmfield(char *ptr, char *skip)
203*45916cd2Sjpk {
204*45916cd2Sjpk 	static char	*tptr = NULL;
205*45916cd2Sjpk 	char		*pend;
206*45916cd2Sjpk 
207*45916cd2Sjpk 	/* check for a continuing search */
2087c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
2097c478bd9Sstevel@tonic-gate 		ptr = tptr;
210*45916cd2Sjpk 	/* check for source end */
211*45916cd2Sjpk 	if (ptr == NULL || *ptr == '\0')
2127c478bd9Sstevel@tonic-gate 		return (NULL);
213*45916cd2Sjpk 	/* find terminator */
214*45916cd2Sjpk 	pend = strpbrk(ptr, skip);
215*45916cd2Sjpk 	/* terminate and set continuation pointer */
216*45916cd2Sjpk 	if (pend != NULL) {
217*45916cd2Sjpk 		*pend++ = '\0';
218*45916cd2Sjpk 		tptr = pend;
219*45916cd2Sjpk 	} else
220*45916cd2Sjpk 		tptr = NULL;
2217c478bd9Sstevel@tonic-gate 	/*
222*45916cd2Sjpk 	 * trim off any surrounding white space, return what's left
2237c478bd9Sstevel@tonic-gate 	 */
2247c478bd9Sstevel@tonic-gate 
225*45916cd2Sjpk 	return (trim_white(ptr));
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate /*
229*45916cd2Sjpk  * setdaent -
230*45916cd2Sjpk  *	rewinds the device_allocate file to the begining.
2317c478bd9Sstevel@tonic-gate  */
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate void
234*45916cd2Sjpk setdaent(void)
2357c478bd9Sstevel@tonic-gate {
236*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2377c478bd9Sstevel@tonic-gate 
238*45916cd2Sjpk 	if (_da == NULL)
2397c478bd9Sstevel@tonic-gate 		return;
240*45916cd2Sjpk 	if (daf == NULL)
241*45916cd2Sjpk 		daf = fopen(DEVALLOC_FILE, "r");
242*45916cd2Sjpk 	else
2437c478bd9Sstevel@tonic-gate 		rewind(daf);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate /*
247*45916cd2Sjpk  * enddaent -
248*45916cd2Sjpk  *	closes device_allocate file.
2497c478bd9Sstevel@tonic-gate  */
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate void
252*45916cd2Sjpk enddaent(void)
2537c478bd9Sstevel@tonic-gate {
254*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2557c478bd9Sstevel@tonic-gate 
256*45916cd2Sjpk 	if (_da == NULL)
2577c478bd9Sstevel@tonic-gate 		return;
2587c478bd9Sstevel@tonic-gate 	if (daf != NULL) {
2597c478bd9Sstevel@tonic-gate 		(void) fclose(daf);
2607c478bd9Sstevel@tonic-gate 		daf = NULL;
2617c478bd9Sstevel@tonic-gate 	}
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate /*
265*45916cd2Sjpk  * setdafile -
266*45916cd2Sjpk  *	changes the default device_allocate file to the one specified.
267*45916cd2Sjpk  * 	It does not close the previous file. If this is desired, enddaent
268*45916cd2Sjpk  *	should be called prior to setdafile.
2697c478bd9Sstevel@tonic-gate  */
2707c478bd9Sstevel@tonic-gate void
271*45916cd2Sjpk setdafile(char *file)
2727c478bd9Sstevel@tonic-gate {
273*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2747c478bd9Sstevel@tonic-gate 
275*45916cd2Sjpk 	if (_da == NULL)
2767c478bd9Sstevel@tonic-gate 		return;
2777c478bd9Sstevel@tonic-gate 	if (daf != NULL) {
2787c478bd9Sstevel@tonic-gate 		(void) fclose(daf);
2797c478bd9Sstevel@tonic-gate 		daf = NULL;
2807c478bd9Sstevel@tonic-gate 	}
281*45916cd2Sjpk 	DEVALLOC_FILE = file;
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate 
284*45916cd2Sjpk void
285*45916cd2Sjpk freedaent(devalloc_t *dap)
286*45916cd2Sjpk {
287*45916cd2Sjpk 	if (dap == NULL)
288*45916cd2Sjpk 		return;
289*45916cd2Sjpk 	_kva_free(dap->da_devopts);
290*45916cd2Sjpk 	dap->da_devopts = NULL;
291*45916cd2Sjpk }
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate /*
294*45916cd2Sjpk  * getdaon -
295*45916cd2Sjpk  *	checks if device_allocate has string DEVICE_ALLOCATION=ON or
296*45916cd2Sjpk  *	DEVICE_ALLOCATION=OFF string in it.
297*45916cd2Sjpk  *	returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
298*45916cd2Sjpk  *	DEVICE_ALLOCATION=OFF, -1 if neither string present.
299*45916cd2Sjpk  */
300*45916cd2Sjpk int
301*45916cd2Sjpk getdaon()
302*45916cd2Sjpk {
303*45916cd2Sjpk 	int		is_on = -1;
304*45916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
305*45916cd2Sjpk 	struct _dabuff *_da = _daalloc();
306*45916cd2Sjpk 
307*45916cd2Sjpk 	setdaent();
308*45916cd2Sjpk 	if ((_da == NULL) || (daf == NULL)) {
309*45916cd2Sjpk 		enddaent();
310*45916cd2Sjpk 		return (is_on);
311*45916cd2Sjpk 	}
312*45916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
313*45916cd2Sjpk 		if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) {
314*45916cd2Sjpk 			is_on = 1;
315*45916cd2Sjpk 			break;
316*45916cd2Sjpk 		} else if (strncmp(line1, DA_OFF_STR,
317*45916cd2Sjpk 		    (strlen(DA_OFF_STR) - 1)) == 0) {
318*45916cd2Sjpk 			is_on = 0;
319*45916cd2Sjpk 			break;
320*45916cd2Sjpk 		}
321*45916cd2Sjpk 	}
322*45916cd2Sjpk 	enddaent();
323*45916cd2Sjpk 
324*45916cd2Sjpk 	return (is_on);
325*45916cd2Sjpk }
326*45916cd2Sjpk 
327*45916cd2Sjpk /*
328*45916cd2Sjpk  * getdaent -
329*45916cd2Sjpk  *	When first called, returns a pointer to the first devalloc_t
330*45916cd2Sjpk  * 	structure in device_allocate; thereafter, it returns a pointer to the
331*45916cd2Sjpk  *	next devalloc_t structure in the file. Thus, successive calls can be
332*45916cd2Sjpk  *	used to search the entire file.
333*45916cd2Sjpk  *	call to getdaent should be bracketed by setdaent and enddaent.
334*45916cd2Sjpk  *	returns NULL on error.
3357c478bd9Sstevel@tonic-gate  */
3367c478bd9Sstevel@tonic-gate devalloc_t *
337*45916cd2Sjpk getdaent(void)
3387c478bd9Sstevel@tonic-gate {
339*45916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
3407c478bd9Sstevel@tonic-gate 	devalloc_t	*da;
341*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
3427c478bd9Sstevel@tonic-gate 
343*45916cd2Sjpk 	if ((_da == 0) || (daf == NULL))
3447c478bd9Sstevel@tonic-gate 		return (NULL);
3457c478bd9Sstevel@tonic-gate 
346*45916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
347*45916cd2Sjpk 		if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) ||
348*45916cd2Sjpk 		    (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0))
3497c478bd9Sstevel@tonic-gate 			continue;
350*45916cd2Sjpk 		if ((da = da_interpret(line1)) == NULL)
351*45916cd2Sjpk 			continue;
352*45916cd2Sjpk 		return (da);
3537c478bd9Sstevel@tonic-gate 	}
3547c478bd9Sstevel@tonic-gate 
355*45916cd2Sjpk 	return (NULL);
356*45916cd2Sjpk }
357*45916cd2Sjpk 
3587c478bd9Sstevel@tonic-gate /*
359*45916cd2Sjpk  * getdanam
360*45916cd2Sjpk  * 	searches from the beginning of device_allocate for the device specified
361*45916cd2Sjpk  * 	by its name.
362*45916cd2Sjpk  *	call to getdanam should be bracketed by setdaent and enddaent.
363*45916cd2Sjpk  * 	returns pointer to devalloc_t for the device if it is found, else
364*45916cd2Sjpk  *	returns NULL if device not found or in case of error.
3657c478bd9Sstevel@tonic-gate  */
366*45916cd2Sjpk devalloc_t *
367*45916cd2Sjpk getdanam(char *name)
3687c478bd9Sstevel@tonic-gate {
369*45916cd2Sjpk 	char		line[DA_BUFSIZE + 1];
370*45916cd2Sjpk 	devalloc_t	*da;
371*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
3727c478bd9Sstevel@tonic-gate 
373*45916cd2Sjpk 	if ((name == NULL) || (_da == 0) || (daf == NULL))
374*45916cd2Sjpk 		return (NULL);
375*45916cd2Sjpk 
376*45916cd2Sjpk 	while (getdadmline(line, (int)sizeof (line), daf) != 0) {
377*45916cd2Sjpk 		if (strstr(line, name) == NULL)
378*45916cd2Sjpk 			continue;
379*45916cd2Sjpk 		if ((da = da_interpret(line)) == NULL)
380*45916cd2Sjpk 			continue;
381*45916cd2Sjpk 		if (da_matchname(da, name)) {
382*45916cd2Sjpk 			enddaent();
383*45916cd2Sjpk 			return (da);
384*45916cd2Sjpk 		}
385*45916cd2Sjpk 		freedaent(da);
386*45916cd2Sjpk 	}
387*45916cd2Sjpk 
388*45916cd2Sjpk 	return (NULL);
389*45916cd2Sjpk }
390*45916cd2Sjpk 
391*45916cd2Sjpk /*
392*45916cd2Sjpk  * getdatype -
393*45916cd2Sjpk  * 	searches from the beginning of device_allocate for the device specified
394*45916cd2Sjpk  * 	by its type.
395*45916cd2Sjpk  *	call to getdatype should be bracketed by setdaent and enddaent.
396*45916cd2Sjpk  * 	returns pointer to devalloc_t for the device if it is found, else
397*45916cd2Sjpk  *	returns NULL if device not found or in case of error.
398*45916cd2Sjpk  */
399*45916cd2Sjpk devalloc_t *
400*45916cd2Sjpk getdatype(char *type)
401*45916cd2Sjpk {
402*45916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
403*45916cd2Sjpk 	devalloc_t	*da;
404*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
405*45916cd2Sjpk 
406*45916cd2Sjpk 	if ((type == NULL) || (_da == NULL) || (daf == NULL))
407*45916cd2Sjpk 		return (NULL);
408*45916cd2Sjpk 
409*45916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
410*45916cd2Sjpk 		if (strstr(line1, type) == NULL)
411*45916cd2Sjpk 			continue;
412*45916cd2Sjpk 		if ((da = da_interpret(line1)) == NULL)
413*45916cd2Sjpk 			continue;
414*45916cd2Sjpk 		if (da_matchtype(da, type))
415*45916cd2Sjpk 			return (da);
416*45916cd2Sjpk 		freedaent(da);
417*45916cd2Sjpk 	}
418*45916cd2Sjpk 
419*45916cd2Sjpk 	return (NULL);
420*45916cd2Sjpk }
421*45916cd2Sjpk 
422*45916cd2Sjpk /*
423*45916cd2Sjpk  * da_matchname -
424*45916cd2Sjpk  *	checks if the specified devalloc_t is for the device specified.
425*45916cd2Sjpk  * 	returns 1 if it is, else returns 0.
426*45916cd2Sjpk  */
427*45916cd2Sjpk int
428*45916cd2Sjpk da_matchname(devalloc_t *dap, char *name)
429*45916cd2Sjpk {
430*45916cd2Sjpk 	if (dap->da_devname == NULL)
4317c478bd9Sstevel@tonic-gate 		return (0);
432*45916cd2Sjpk 
433*45916cd2Sjpk 	return ((strcmp(dap->da_devname, name) == 0));
434*45916cd2Sjpk }
435*45916cd2Sjpk 
436*45916cd2Sjpk /*
437*45916cd2Sjpk  * da_matchtype -
438*45916cd2Sjpk  *	checks if the specified devalloc_t is for the device type specified.
439*45916cd2Sjpk  *	returns 1 if match found, else, returns 0.
440*45916cd2Sjpk  */
441*45916cd2Sjpk int
442*45916cd2Sjpk da_matchtype(devalloc_t *da, char *type)
443*45916cd2Sjpk {
444*45916cd2Sjpk 	if (da->da_devtype == NULL)
4457c478bd9Sstevel@tonic-gate 		return (0);
446*45916cd2Sjpk 
447*45916cd2Sjpk 	return ((strcmp(da->da_devtype, type) == 0));
448*45916cd2Sjpk }
449*45916cd2Sjpk 
450*45916cd2Sjpk /*
451*45916cd2Sjpk  * da_match -
452*45916cd2Sjpk  * 	calls da_matchname or da_matchdev as appropriate.
453*45916cd2Sjpk  */
454*45916cd2Sjpk int
455*45916cd2Sjpk da_match(devalloc_t *dap, da_args *dargs)
456*45916cd2Sjpk {
457*45916cd2Sjpk 	if (dargs->devinfo->devname)
458*45916cd2Sjpk 		return (da_matchname(dap, dargs->devinfo->devname));
459*45916cd2Sjpk 	else if (dargs->devinfo->devtype)
460*45916cd2Sjpk 		return (da_matchtype(dap, dargs->devinfo->devtype));
461*45916cd2Sjpk 
4627c478bd9Sstevel@tonic-gate 	return (0);
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate /*
466*45916cd2Sjpk  * da_interpret -
467*45916cd2Sjpk  *	parses val and initializes pointers in devalloc_t.
468*45916cd2Sjpk  * 	returns pointer to parsed devalloc_t entry, else returns NULL on error.
4697c478bd9Sstevel@tonic-gate  */
4707c478bd9Sstevel@tonic-gate static devalloc_t  *
471*45916cd2Sjpk da_interpret(char *val)
4727c478bd9Sstevel@tonic-gate {
473*45916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
474*45916cd2Sjpk 	char	*opts;
475*45916cd2Sjpk 	int	i;
476*45916cd2Sjpk 	kva_t	*kvap;
477*45916cd2Sjpk 	kv_t	*kvp;
4787c478bd9Sstevel@tonic-gate 
479*45916cd2Sjpk 	if (_da == NULL)
480*45916cd2Sjpk 		return (NULL);
4817c478bd9Sstevel@tonic-gate 
482*45916cd2Sjpk 	(void) strcpy(interpdaline, val);
483*45916cd2Sjpk 	interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER);
484*45916cd2Sjpk 	interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER);
485*45916cd2Sjpk 	opts = getdadmfield(NULL, KV_DELIMITER);
486*45916cd2Sjpk 	(void) getdadmfield(NULL, KV_DELIMITER);	/* reserved field */
487*45916cd2Sjpk 	interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER);
488*45916cd2Sjpk 	interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER);
489*45916cd2Sjpk 	interpdevalloc.da_devopts = NULL;
490*45916cd2Sjpk 	if (interpdevalloc.da_devname == NULL ||
491*45916cd2Sjpk 	    interpdevalloc.da_devtype == NULL)
492*45916cd2Sjpk 		return (NULL);
493*45916cd2Sjpk 	if ((opts != NULL) &&
494*45916cd2Sjpk 	    (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) {
495*45916cd2Sjpk 		interpdevalloc.da_devopts =
496*45916cd2Sjpk 		    _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT);
497*45916cd2Sjpk 	}
498*45916cd2Sjpk 	/* remove any extraneous whitespace in the options */
499*45916cd2Sjpk 	if ((kvap = interpdevalloc.da_devopts) != NULL) {
500*45916cd2Sjpk 		for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
501*45916cd2Sjpk 			(void) pack_white(kvp->key);
502*45916cd2Sjpk 			(void) pack_white(kvp->value);
503*45916cd2Sjpk 		}
504*45916cd2Sjpk 	}
505*45916cd2Sjpk 
506*45916cd2Sjpk 	if (system_labeled) {
507*45916cd2Sjpk 		/* if label range is not defined, use the default range. */
508*45916cd2Sjpk 		int		i = 0, nlen = 0;
509*45916cd2Sjpk 		char		*minstr = NULL, *maxstr = NULL;
510*45916cd2Sjpk 		kva_t		*nkvap = NULL;
511*45916cd2Sjpk 		kv_t		*ndata = NULL, *odata = NULL;
512*45916cd2Sjpk 
513*45916cd2Sjpk 		if (kvap == NULL) {
514*45916cd2Sjpk 			nlen = 2;	/* minlabel, maxlabel */
515*45916cd2Sjpk 		} else {
516*45916cd2Sjpk 			nlen += kvap->length;
517*45916cd2Sjpk 			if ((minstr = kva_match(kvap, DAOPT_MINLABEL)) == NULL)
518*45916cd2Sjpk 				nlen++;
519*45916cd2Sjpk 			if ((maxstr = kva_match(kvap, DAOPT_MAXLABEL)) == NULL)
520*45916cd2Sjpk 				nlen++;
521*45916cd2Sjpk 		}
522*45916cd2Sjpk 		if ((minstr != NULL) && (maxstr != NULL))
523*45916cd2Sjpk 			/*
524*45916cd2Sjpk 			 * label range provided; we don't need to construct
525*45916cd2Sjpk 			 * default range.
526*45916cd2Sjpk 			 */
527*45916cd2Sjpk 			goto out;
528*45916cd2Sjpk 		nkvap = _new_kva(nlen);
529*45916cd2Sjpk 		ndata = nkvap->data;
530*45916cd2Sjpk 		if (kvap != NULL) {
531*45916cd2Sjpk 			for (i = 0; i < kvap->length; i++) {
532*45916cd2Sjpk 				odata = kvap->data;
533*45916cd2Sjpk 				ndata[i].key = _strdup_null(odata[i].key);
534*45916cd2Sjpk 				ndata[i].value = _strdup_null(odata[i].value);
535*45916cd2Sjpk 				nkvap->length++;
536*45916cd2Sjpk 			}
537*45916cd2Sjpk 		}
538*45916cd2Sjpk 		if (minstr == NULL) {
539*45916cd2Sjpk 			ndata[i].key = strdup(DAOPT_MINLABEL);
540*45916cd2Sjpk 			ndata[i].value = strdup(DA_DEFAULT_MIN);
541*45916cd2Sjpk 			nkvap->length++;
542*45916cd2Sjpk 			i++;
543*45916cd2Sjpk 		}
544*45916cd2Sjpk 		if (maxstr == NULL) {
545*45916cd2Sjpk 			ndata[i].key = strdup(DAOPT_MAXLABEL);
546*45916cd2Sjpk 			ndata[i].value = strdup(DA_DEFAULT_MAX);
547*45916cd2Sjpk 			nkvap->length++;
548*45916cd2Sjpk 		}
549*45916cd2Sjpk 		interpdevalloc.da_devopts = nkvap;
550*45916cd2Sjpk 	}
551*45916cd2Sjpk 
552*45916cd2Sjpk out:
5537c478bd9Sstevel@tonic-gate 	return (&interpdevalloc);
5547c478bd9Sstevel@tonic-gate }
555