1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <string.h>
31*0Sstevel@tonic-gate #include <malloc.h>
32*0Sstevel@tonic-gate #include <bsm/devices.h>
33*0Sstevel@tonic-gate #include <sys/errno.h>
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #define	MAXINT 0x7fffffff;
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate static struct _dmapbuff {
38*0Sstevel@tonic-gate 	devmap_t _NULLDM;
39*0Sstevel@tonic-gate 	FILE *_dmapf;	/* pointer into /etc/security/device_maps */
40*0Sstevel@tonic-gate 	devmap_t _interpdevmap;
41*0Sstevel@tonic-gate 	char _interpline[BUFSIZ + 1];
42*0Sstevel@tonic-gate 	char *_DEVMAP;
43*0Sstevel@tonic-gate } *__dmapbuff;
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate #define	NULLDM (_dmap->_NULLDM)
46*0Sstevel@tonic-gate #define	dmapf (_dmap->_dmapf)
47*0Sstevel@tonic-gate #define	interpdevmap (_dmap->_interpdevmap)
48*0Sstevel@tonic-gate #define	interpline (_dmap->_interpline)
49*0Sstevel@tonic-gate #define	DEVMAP (_dmap->_DEVMAP)
50*0Sstevel@tonic-gate static devmap_t  *interpret();
51*0Sstevel@tonic-gate static int matchdev();
52*0Sstevel@tonic-gate static int matchname();
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate  * trim_white(ptr) trims off leading and trailing white space from a NULL
55*0Sstevel@tonic-gate  * terminated string pointed to by "ptr". The leading white space is skipped
56*0Sstevel@tonic-gate  * by moving the pointer forward. The trailing white space is removed by
57*0Sstevel@tonic-gate  * nulling the white space characters.  The pointer is returned to the white
58*0Sstevel@tonic-gate  * string. If the resulting string is null in length then a NULL pointer is
59*0Sstevel@tonic-gate  * returned. If "ptr" is NULL then a NULL pointer is returned.
60*0Sstevel@tonic-gate  */
61*0Sstevel@tonic-gate static char *
62*0Sstevel@tonic-gate trim_white(char *ptr)
63*0Sstevel@tonic-gate {
64*0Sstevel@tonic-gate 	register char  *tptr;
65*0Sstevel@tonic-gate 	register int    cnt;
66*0Sstevel@tonic-gate 	if (ptr == NULL)
67*0Sstevel@tonic-gate 		return (NULL);
68*0Sstevel@tonic-gate 	while ((*ptr == ' ') || (*ptr == '\t')) {
69*0Sstevel@tonic-gate 		ptr++;
70*0Sstevel@tonic-gate 	}
71*0Sstevel@tonic-gate 	cnt = strlen(ptr);
72*0Sstevel@tonic-gate 	if (cnt != 0) {
73*0Sstevel@tonic-gate 		tptr = ptr + cnt - 1;
74*0Sstevel@tonic-gate 		while ((*tptr == ' ') || (*tptr == '\t')) {
75*0Sstevel@tonic-gate 			*tptr = '\0';
76*0Sstevel@tonic-gate 			tptr--;
77*0Sstevel@tonic-gate 		}
78*0Sstevel@tonic-gate 	}
79*0Sstevel@tonic-gate 	if (*ptr == NULL)
80*0Sstevel@tonic-gate 		return (NULL);
81*0Sstevel@tonic-gate 	return (ptr);
82*0Sstevel@tonic-gate }
83*0Sstevel@tonic-gate /*
84*0Sstevel@tonic-gate  * scan string pointed to by pointer "p"
85*0Sstevel@tonic-gate  * find next colin or end of line. Null it and
86*0Sstevel@tonic-gate  * return pointer to next char.
87*0Sstevel@tonic-gate  */
88*0Sstevel@tonic-gate static char *
89*0Sstevel@tonic-gate dmapskip(register char *p)
90*0Sstevel@tonic-gate {
91*0Sstevel@tonic-gate 	while (*p && *p != ':' && *p != '\n')
92*0Sstevel@tonic-gate 		++p;
93*0Sstevel@tonic-gate 	if (*p == '\n')
94*0Sstevel@tonic-gate 		*p = '\0';
95*0Sstevel@tonic-gate 	else if (*p != '\0')
96*0Sstevel@tonic-gate 		*p++ = '\0';
97*0Sstevel@tonic-gate 	return (p);
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate /*
100*0Sstevel@tonic-gate  * scan string pointed to by pointer "p"
101*0Sstevel@tonic-gate  * find next colin or end of line. Null it and
102*0Sstevel@tonic-gate  * return pointer to next char.
103*0Sstevel@tonic-gate  */
104*0Sstevel@tonic-gate static char *
105*0Sstevel@tonic-gate dmapdskip(register char *p)
106*0Sstevel@tonic-gate {
107*0Sstevel@tonic-gate 	while (*p && *p != ' ' && *p != '\n')
108*0Sstevel@tonic-gate 		++p;
109*0Sstevel@tonic-gate 	if (*p != '\0')
110*0Sstevel@tonic-gate 		*p++ = '\0';
111*0Sstevel@tonic-gate 	return (p);
112*0Sstevel@tonic-gate }
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate /*
115*0Sstevel@tonic-gate  * _dmapalloc() allocates common buffers and structures used by the device
116*0Sstevel@tonic-gate  * maps library routines. Then returns a pointer to a structure.  The
117*0Sstevel@tonic-gate  * returned pointer will be null if there is an error condition.
118*0Sstevel@tonic-gate  */
119*0Sstevel@tonic-gate static struct _dmapbuff *
120*0Sstevel@tonic-gate _dmapalloc(void)
121*0Sstevel@tonic-gate {
122*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = __dmapbuff;
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate 	if (_dmap == 0) {
125*0Sstevel@tonic-gate 		_dmap = (struct _dmapbuff *)
126*0Sstevel@tonic-gate 			calloc((unsigned)1, (unsigned)sizeof (*__dmapbuff));
127*0Sstevel@tonic-gate 		if (_dmap == 0)
128*0Sstevel@tonic-gate 			return (0);
129*0Sstevel@tonic-gate 		DEVMAP = "/etc/security/device_maps";
130*0Sstevel@tonic-gate 		__dmapbuff = _dmap;
131*0Sstevel@tonic-gate 	}
132*0Sstevel@tonic-gate 	return (__dmapbuff);
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate /*
135*0Sstevel@tonic-gate  * getdmapline(buff,len,stream) reads one device maps line from "stream" into
136*0Sstevel@tonic-gate  * "buff" on "len" bytes.  Continued lines from "stream" are concatinated
137*0Sstevel@tonic-gate  * into one line in "buff". Comments are removed from "buff". The number of
138*0Sstevel@tonic-gate  * characters in "buff" is returned.  If no characters are read or an error
139*0Sstevel@tonic-gate  * occured then "0" is returned
140*0Sstevel@tonic-gate  */
141*0Sstevel@tonic-gate static int
142*0Sstevel@tonic-gate getdmapline(char *buff, int len, FILE *stream)
143*0Sstevel@tonic-gate {
144*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
145*0Sstevel@tonic-gate 	char *cp;
146*0Sstevel@tonic-gate 	char *ccp;
147*0Sstevel@tonic-gate 	size_t tmpcnt;
148*0Sstevel@tonic-gate 	int charcnt = 0;
149*0Sstevel@tonic-gate 	int fileerr = 0;
150*0Sstevel@tonic-gate 	int contline;
151*0Sstevel@tonic-gate 	if (_dmap == 0)
152*0Sstevel@tonic-gate 		return (0);
153*0Sstevel@tonic-gate 	do {
154*0Sstevel@tonic-gate 		cp = buff;
155*0Sstevel@tonic-gate 		*cp = NULL;
156*0Sstevel@tonic-gate 		do {
157*0Sstevel@tonic-gate 			if ((len - charcnt <= 1) ||
158*0Sstevel@tonic-gate 			    (fgets(cp, len - charcnt, stream) == NULL)) {
159*0Sstevel@tonic-gate 				fileerr = 1;
160*0Sstevel@tonic-gate 				break;
161*0Sstevel@tonic-gate 			}
162*0Sstevel@tonic-gate 			ccp = strpbrk(cp, "\\\n");
163*0Sstevel@tonic-gate 			if (ccp != NULL) {
164*0Sstevel@tonic-gate 				if (*ccp == '\\')
165*0Sstevel@tonic-gate 					contline = 1;
166*0Sstevel@tonic-gate 				else
167*0Sstevel@tonic-gate 					contline = 0;
168*0Sstevel@tonic-gate 				*ccp = NULL;
169*0Sstevel@tonic-gate 			}
170*0Sstevel@tonic-gate 			tmpcnt = strlen(cp);
171*0Sstevel@tonic-gate 			if (tmpcnt != 0) {
172*0Sstevel@tonic-gate 				cp += tmpcnt;
173*0Sstevel@tonic-gate 				charcnt += tmpcnt;
174*0Sstevel@tonic-gate 			}
175*0Sstevel@tonic-gate 		} while ((contline) || (charcnt == 0));
176*0Sstevel@tonic-gate 		ccp = strpbrk(buff, "#");
177*0Sstevel@tonic-gate 		if (ccp != NULL)
178*0Sstevel@tonic-gate 			*ccp = NULL;
179*0Sstevel@tonic-gate 		charcnt = strlen(buff);
180*0Sstevel@tonic-gate 	} while ((fileerr == 0) && (charcnt == 0));
181*0Sstevel@tonic-gate 	if (fileerr && !charcnt)
182*0Sstevel@tonic-gate 		return (0);
183*0Sstevel@tonic-gate 	else
184*0Sstevel@tonic-gate 		return (charcnt);
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate char
187*0Sstevel@tonic-gate *getdmapfield(char *ptr)
188*0Sstevel@tonic-gate {
189*0Sstevel@tonic-gate 	static	char	*tptr;
190*0Sstevel@tonic-gate 	if (ptr == NULL)
191*0Sstevel@tonic-gate 		ptr = tptr;
192*0Sstevel@tonic-gate 	if (ptr == NULL)
193*0Sstevel@tonic-gate 		return (NULL);
194*0Sstevel@tonic-gate 	tptr = dmapskip(ptr);
195*0Sstevel@tonic-gate 	ptr = trim_white(ptr);
196*0Sstevel@tonic-gate 	if (ptr == NULL)
197*0Sstevel@tonic-gate 		return (NULL);
198*0Sstevel@tonic-gate 	if (*ptr == NULL)
199*0Sstevel@tonic-gate 		return (NULL);
200*0Sstevel@tonic-gate 	return (ptr);
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate char
203*0Sstevel@tonic-gate *getdmapdfield(char *ptr)
204*0Sstevel@tonic-gate {
205*0Sstevel@tonic-gate 	static	char	*tptr;
206*0Sstevel@tonic-gate 	if (ptr != NULL) {
207*0Sstevel@tonic-gate 		ptr = trim_white(ptr);
208*0Sstevel@tonic-gate 	} else {
209*0Sstevel@tonic-gate 		ptr = tptr;
210*0Sstevel@tonic-gate 	}
211*0Sstevel@tonic-gate 	if (ptr == NULL)
212*0Sstevel@tonic-gate 		return (NULL);
213*0Sstevel@tonic-gate 	tptr = dmapdskip(ptr);
214*0Sstevel@tonic-gate 	if (ptr == NULL)
215*0Sstevel@tonic-gate 		return (NULL);
216*0Sstevel@tonic-gate 	if (*ptr == NULL)
217*0Sstevel@tonic-gate 		return (NULL);
218*0Sstevel@tonic-gate 	return (ptr);
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate /*
221*0Sstevel@tonic-gate  * getdmapdev(dev) searches from the beginning of the file until a logical
222*0Sstevel@tonic-gate  * device matching "dev" is found and returns a pointer to the particular
223*0Sstevel@tonic-gate  * structure in which it was found.  If an EOF or an error is encountered on
224*0Sstevel@tonic-gate  * reading, these functions return a NULL pointer.
225*0Sstevel@tonic-gate  */
226*0Sstevel@tonic-gate devmap_t *
227*0Sstevel@tonic-gate getdmapdev(register char  *name)
228*0Sstevel@tonic-gate {
229*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
230*0Sstevel@tonic-gate 	devmap_t *dmap;
231*0Sstevel@tonic-gate 	char line[BUFSIZ + 1];
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate 	if (_dmap == 0)
234*0Sstevel@tonic-gate 		return (0);
235*0Sstevel@tonic-gate 	setdmapent();
236*0Sstevel@tonic-gate 	if (!dmapf)
237*0Sstevel@tonic-gate 		return (NULL);
238*0Sstevel@tonic-gate 	while (getdmapline(line, (int)sizeof (line), dmapf) != 0) {
239*0Sstevel@tonic-gate 		if ((dmap = interpret(line)) == NULL)
240*0Sstevel@tonic-gate 			continue;
241*0Sstevel@tonic-gate 		if (matchdev(&dmap, name)) {
242*0Sstevel@tonic-gate 			enddmapent();
243*0Sstevel@tonic-gate 			return (dmap);
244*0Sstevel@tonic-gate 		}
245*0Sstevel@tonic-gate 	}
246*0Sstevel@tonic-gate 	enddmapent();
247*0Sstevel@tonic-gate 	return (NULL);
248*0Sstevel@tonic-gate }
249*0Sstevel@tonic-gate /*
250*0Sstevel@tonic-gate  * getdmapnam(name) searches from the beginning of the file until a audit-name
251*0Sstevel@tonic-gate  * matching "name" is found and returns a pointer to the particular structure
252*0Sstevel@tonic-gate  * in which it was found.  If an EOF or an error is encountered on reading,
253*0Sstevel@tonic-gate  * these functions return a NULL pointer.
254*0Sstevel@tonic-gate  */
255*0Sstevel@tonic-gate devmap_t *
256*0Sstevel@tonic-gate getdmapnam(register char  *name)
257*0Sstevel@tonic-gate {
258*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
259*0Sstevel@tonic-gate 	devmap_t *dmap;
260*0Sstevel@tonic-gate 	char line[BUFSIZ + 1];
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	if (_dmap == 0)
263*0Sstevel@tonic-gate 		return (0);
264*0Sstevel@tonic-gate 	setdmapent();
265*0Sstevel@tonic-gate 	if (!dmapf)
266*0Sstevel@tonic-gate 		return (NULL);
267*0Sstevel@tonic-gate 	while (getdmapline(line, (int)sizeof (line), dmapf) != 0) {
268*0Sstevel@tonic-gate 		if ((dmap = interpret(line)) == NULL)
269*0Sstevel@tonic-gate 			continue;
270*0Sstevel@tonic-gate 		if (matchname(&dmap, name)) {
271*0Sstevel@tonic-gate 			enddmapent();
272*0Sstevel@tonic-gate 			return (dmap);
273*0Sstevel@tonic-gate 		}
274*0Sstevel@tonic-gate 	}
275*0Sstevel@tonic-gate 	enddmapent();
276*0Sstevel@tonic-gate 	return (NULL);
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate /*
280*0Sstevel@tonic-gate  * setdmapent() essentially rewinds the device_maps file to the begining.
281*0Sstevel@tonic-gate  */
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate void
284*0Sstevel@tonic-gate setdmapent(void)
285*0Sstevel@tonic-gate {
286*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 	if (_dmap == 0)
290*0Sstevel@tonic-gate 		return;
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 	if (dmapf == NULL) {
293*0Sstevel@tonic-gate 		dmapf = fopen(DEVMAP, "r");
294*0Sstevel@tonic-gate 	} else
295*0Sstevel@tonic-gate 		rewind(dmapf);
296*0Sstevel@tonic-gate }
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate /*
300*0Sstevel@tonic-gate  * enddmapent() may be called to close the device_maps file when processing
301*0Sstevel@tonic-gate  * is complete.
302*0Sstevel@tonic-gate  */
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate void
305*0Sstevel@tonic-gate enddmapent(void)
306*0Sstevel@tonic-gate {
307*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate 	if (_dmap == 0)
310*0Sstevel@tonic-gate 		return;
311*0Sstevel@tonic-gate 	if (dmapf != NULL) {
312*0Sstevel@tonic-gate 		(void) fclose(dmapf);
313*0Sstevel@tonic-gate 		dmapf = NULL;
314*0Sstevel@tonic-gate 	}
315*0Sstevel@tonic-gate }
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate /*
319*0Sstevel@tonic-gate  * setdmapfile(name) changes the default device_maps file to "name" thus
320*0Sstevel@tonic-gate  * allowing alternate device_maps files to be used.  Note: it does not
321*0Sstevel@tonic-gate  * close the previous file . If this is desired, enddmapent should be called
322*0Sstevel@tonic-gate  * prior to it.
323*0Sstevel@tonic-gate  */
324*0Sstevel@tonic-gate void
325*0Sstevel@tonic-gate setdmapfile(char *file)
326*0Sstevel@tonic-gate {
327*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
328*0Sstevel@tonic-gate 
329*0Sstevel@tonic-gate 	if (_dmap == 0)
330*0Sstevel@tonic-gate 		return;
331*0Sstevel@tonic-gate 	if (dmapf != NULL) {
332*0Sstevel@tonic-gate 		(void) fclose(dmapf);
333*0Sstevel@tonic-gate 		dmapf = NULL;
334*0Sstevel@tonic-gate 	}
335*0Sstevel@tonic-gate 	DEVMAP = file;
336*0Sstevel@tonic-gate }
337*0Sstevel@tonic-gate /*
338*0Sstevel@tonic-gate  * getdmaptype(tp) When first called, returns a pointer to the
339*0Sstevel@tonic-gate  * first devmap_t structure in the file with device-type matching
340*0Sstevel@tonic-gate  * "tp"; thereafter, it returns a pointer to the next devmap_t
341*0Sstevel@tonic-gate  * structure in the file with device-type matching "tp".
342*0Sstevel@tonic-gate  * Thus successive calls can be used to search the
343*0Sstevel@tonic-gate  * entire file for entries having device-type matching "tp".
344*0Sstevel@tonic-gate  * A null pointer is returned on error.
345*0Sstevel@tonic-gate  */
346*0Sstevel@tonic-gate devmap_t *
347*0Sstevel@tonic-gate getdmaptype(char *tp)
348*0Sstevel@tonic-gate {
349*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
350*0Sstevel@tonic-gate 	char line1[BUFSIZ + 1];
351*0Sstevel@tonic-gate 	devmap_t *dmap;
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate 	if (_dmap == 0)
354*0Sstevel@tonic-gate 		return (0);
355*0Sstevel@tonic-gate 	if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) {
356*0Sstevel@tonic-gate 		return (NULL);
357*0Sstevel@tonic-gate 	}
358*0Sstevel@tonic-gate 	do {
359*0Sstevel@tonic-gate 		if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0)
360*0Sstevel@tonic-gate 			return (NULL);
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 		if ((dmap = interpret(line1)) == NULL)
363*0Sstevel@tonic-gate 			return (NULL);
364*0Sstevel@tonic-gate 	} while (strcmp(tp, dmap->dmap_devtype) != 0);
365*0Sstevel@tonic-gate 	return (dmap);
366*0Sstevel@tonic-gate }
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate /*
369*0Sstevel@tonic-gate  * getdmapent() When first called, returns a pointer to the first devmap_t
370*0Sstevel@tonic-gate  * structure in the file; thereafter, it returns a pointer to the next devmap_t
371*0Sstevel@tonic-gate  * structure in the file. Thus successive calls can be used to search the
372*0Sstevel@tonic-gate  * entire file.  A null pointer is returned on error.
373*0Sstevel@tonic-gate  */
374*0Sstevel@tonic-gate devmap_t *
375*0Sstevel@tonic-gate getdmapent(void)
376*0Sstevel@tonic-gate {
377*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
378*0Sstevel@tonic-gate 	char line1[BUFSIZ + 1];
379*0Sstevel@tonic-gate 	devmap_t *dmap;
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 	if (_dmap == 0)
382*0Sstevel@tonic-gate 		return (0);
383*0Sstevel@tonic-gate 	if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) {
384*0Sstevel@tonic-gate 		return (NULL);
385*0Sstevel@tonic-gate 	}
386*0Sstevel@tonic-gate 	if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0)
387*0Sstevel@tonic-gate 		return (NULL);
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 	if ((dmap = interpret(line1)) == NULL)
390*0Sstevel@tonic-gate 		return (NULL);
391*0Sstevel@tonic-gate 	return (dmap);
392*0Sstevel@tonic-gate }
393*0Sstevel@tonic-gate /*
394*0Sstevel@tonic-gate  * matchdev(dmapp,dev) The dev_list in the structure pointed to by "dmapp" is
395*0Sstevel@tonic-gate  * searched for string "dev".  If a match occures then a "1" is returned
396*0Sstevel@tonic-gate  * otherwise a "0" is returned.
397*0Sstevel@tonic-gate  */
398*0Sstevel@tonic-gate static int
399*0Sstevel@tonic-gate matchdev(devmap_t **dmapp, char *dev)
400*0Sstevel@tonic-gate {
401*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
402*0Sstevel@tonic-gate 	devmap_t *dmap = *dmapp;
403*0Sstevel@tonic-gate 	char tmpdev[BUFSIZ + 1];
404*0Sstevel@tonic-gate 	int charcnt;
405*0Sstevel@tonic-gate 	int tmpcnt;
406*0Sstevel@tonic-gate 	char *cp;
407*0Sstevel@tonic-gate 	char *tcp;
408*0Sstevel@tonic-gate 	char *last;
409*0Sstevel@tonic-gate 	charcnt = strlen(dev);
410*0Sstevel@tonic-gate 	if (_dmap == 0)
411*0Sstevel@tonic-gate 		return (0);
412*0Sstevel@tonic-gate 	if (dmap->dmap_devlist == NULL)
413*0Sstevel@tonic-gate 		return (0);
414*0Sstevel@tonic-gate 	(void) strcpy(tmpdev, dmap->dmap_devlist);
415*0Sstevel@tonic-gate 	tcp = tmpdev;
416*0Sstevel@tonic-gate 	while ((cp = strtok_r(tcp, " ", &last)) != NULL) {
417*0Sstevel@tonic-gate 		tcp = NULL;
418*0Sstevel@tonic-gate 		tmpcnt = strlen(cp);
419*0Sstevel@tonic-gate 		if (tmpcnt != charcnt)
420*0Sstevel@tonic-gate 			continue;
421*0Sstevel@tonic-gate 		if (strcmp(cp, dev) == 0)
422*0Sstevel@tonic-gate 			return (1);
423*0Sstevel@tonic-gate 	}
424*0Sstevel@tonic-gate 	return (0);
425*0Sstevel@tonic-gate }
426*0Sstevel@tonic-gate /*
427*0Sstevel@tonic-gate  * matchname(dmapp,name) The audit-name in the structure pointed to by "dmapp"
428*0Sstevel@tonic-gate  * is searched for string "name".  If a match occures then a "1" is returned
429*0Sstevel@tonic-gate  * otherwise a "0" is returned.
430*0Sstevel@tonic-gate  */
431*0Sstevel@tonic-gate static int
432*0Sstevel@tonic-gate matchname(devmap_t **dmapp, char *name)
433*0Sstevel@tonic-gate {
434*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
435*0Sstevel@tonic-gate 	devmap_t *dmap = *dmapp;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 	if (_dmap == 0)
438*0Sstevel@tonic-gate 		return (0);
439*0Sstevel@tonic-gate 	if (dmap->dmap_devname == NULL)
440*0Sstevel@tonic-gate 		return (0);
441*0Sstevel@tonic-gate 	if (strlen(dmap->dmap_devname) != strlen(name))
442*0Sstevel@tonic-gate 		return (0);
443*0Sstevel@tonic-gate 	if (strcmp(dmap->dmap_devname, name) == 0)
444*0Sstevel@tonic-gate 		return (1);
445*0Sstevel@tonic-gate 	return (0);
446*0Sstevel@tonic-gate }
447*0Sstevel@tonic-gate /*
448*0Sstevel@tonic-gate  * interpret(val) string "val" is parsed and the pointers in a devmap_t
449*0Sstevel@tonic-gate  * structure are initialized to point to fields in "val". A pointer to this
450*0Sstevel@tonic-gate  * structure is returned.
451*0Sstevel@tonic-gate  */
452*0Sstevel@tonic-gate static devmap_t  *
453*0Sstevel@tonic-gate interpret(char *val)
454*0Sstevel@tonic-gate {
455*0Sstevel@tonic-gate 	register struct _dmapbuff *_dmap = _dmapalloc();
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	if (_dmap == 0)
458*0Sstevel@tonic-gate 		return (0);
459*0Sstevel@tonic-gate 	(void) strcpy(interpline, val);
460*0Sstevel@tonic-gate 	interpdevmap.dmap_devname = getdmapfield(interpline);
461*0Sstevel@tonic-gate 	interpdevmap.dmap_devtype = getdmapfield((char *)NULL);
462*0Sstevel@tonic-gate 	interpdevmap.dmap_devlist = getdmapfield((char *)NULL);
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	return (&interpdevmap);
465*0Sstevel@tonic-gate }
466