xref: /titanic_53/usr/src/lib/libbsm/common/getdment.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 
287c478bd9Sstevel@tonic-gate #include <string.h>
29*45916cd2Sjpk #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <bsm/devices.h>
31*45916cd2Sjpk #include <bsm/devalloc.h>
327c478bd9Sstevel@tonic-gate 
33*45916cd2Sjpk char *strtok_r(char *, const char *, char **);
34*45916cd2Sjpk 
35*45916cd2Sjpk /* externs from getdaent.c */
36*45916cd2Sjpk extern char *trim_white(char *);
37*45916cd2Sjpk extern int pack_white(char *);
38*45916cd2Sjpk extern char *getdadmfield(char *, char *);
39*45916cd2Sjpk extern int getdadmline(char *, int, FILE *);
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static struct _dmapbuff {
42*45916cd2Sjpk 	FILE		*_dmapf;	/* for /etc/security/device_maps */
437c478bd9Sstevel@tonic-gate 	devmap_t	_interpdevmap;
44*45916cd2Sjpk 	char		_interpdmline[DA_BUFSIZE + 1];
457c478bd9Sstevel@tonic-gate 	char		*_DEVMAP;
467c478bd9Sstevel@tonic-gate } *__dmapbuff;
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #define	dmapf	(_dmap->_dmapf)
497c478bd9Sstevel@tonic-gate #define	interpdevmap	(_dmap->_interpdevmap)
50*45916cd2Sjpk #define	interpdmline	(_dmap->_interpdmline)
51*45916cd2Sjpk #define	DEVMAPS_FILE	(_dmap->_DEVMAP)
52*45916cd2Sjpk 
53*45916cd2Sjpk devmap_t	*dmap_interpret(char *, devmap_t *);
54*45916cd2Sjpk static devmap_t	*dmap_interpretf(char *, devmap_t *);
55*45916cd2Sjpk static devmap_t *dmap_dlexpand(devmap_t *);
56*45916cd2Sjpk 
57*45916cd2Sjpk int	dmap_matchdev(devmap_t *, char *);
58*45916cd2Sjpk int	dmap_matchname(devmap_t *, char *);
59*45916cd2Sjpk 
60*45916cd2Sjpk 
617c478bd9Sstevel@tonic-gate /*
62*45916cd2Sjpk  * _dmapalloc -
63*45916cd2Sjpk  *	allocates common buffers and structures.
64*45916cd2Sjpk  *	returns pointer to the new structure, else returns NULL on error.
657c478bd9Sstevel@tonic-gate  */
66*45916cd2Sjpk static struct _dmapbuff *
67*45916cd2Sjpk _dmapalloc(void)
687c478bd9Sstevel@tonic-gate {
69*45916cd2Sjpk 	struct _dmapbuff *_dmap = __dmapbuff;
70*45916cd2Sjpk 
71*45916cd2Sjpk 	if (_dmap == NULL) {
72*45916cd2Sjpk 		_dmap = (struct _dmapbuff *)calloc((unsigned)1,
73*45916cd2Sjpk 		    (unsigned)sizeof (*__dmapbuff));
74*45916cd2Sjpk 		if (_dmap == NULL)
757c478bd9Sstevel@tonic-gate 			return (NULL);
76*45916cd2Sjpk 		DEVMAPS_FILE = "/etc/security/device_maps";
77*45916cd2Sjpk 		dmapf = NULL;
78*45916cd2Sjpk 		__dmapbuff = _dmap;
797c478bd9Sstevel@tonic-gate 	}
80*45916cd2Sjpk 
81*45916cd2Sjpk 	return (_dmap);
827c478bd9Sstevel@tonic-gate }
83*45916cd2Sjpk 
847c478bd9Sstevel@tonic-gate /*
85*45916cd2Sjpk  * setdmapent -
86*45916cd2Sjpk  *	rewinds the device_maps file to the beginning.
87*45916cd2Sjpk  */
88*45916cd2Sjpk void
89*45916cd2Sjpk setdmapent(void)
90*45916cd2Sjpk {
91*45916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
92*45916cd2Sjpk 
93*45916cd2Sjpk 	if (_dmap == NULL)
94*45916cd2Sjpk 		return;
95*45916cd2Sjpk 	if (dmapf == NULL)
96*45916cd2Sjpk 		dmapf = fopen(DEVMAPS_FILE, "r");
97*45916cd2Sjpk 	else
98*45916cd2Sjpk 		rewind(dmapf);
99*45916cd2Sjpk }
100*45916cd2Sjpk 
101*45916cd2Sjpk /*
102*45916cd2Sjpk  * enddmapent -
103*45916cd2Sjpk  *	closes device_maps file.
104*45916cd2Sjpk  */
105*45916cd2Sjpk void
106*45916cd2Sjpk enddmapent(void)
107*45916cd2Sjpk {
108*45916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
109*45916cd2Sjpk 
110*45916cd2Sjpk 	if (_dmap == NULL)
111*45916cd2Sjpk 		return;
112*45916cd2Sjpk 	if (dmapf != NULL) {
113*45916cd2Sjpk 		(void) fclose(dmapf);
114*45916cd2Sjpk 		dmapf = NULL;
115*45916cd2Sjpk 	}
116*45916cd2Sjpk }
117*45916cd2Sjpk 
118*45916cd2Sjpk void
119*45916cd2Sjpk freedmapent(devmap_t *dmap)
120*45916cd2Sjpk {
121*45916cd2Sjpk 	char	**darp;
122*45916cd2Sjpk 
123*45916cd2Sjpk 	if ((darp = dmap->dmap_devarray) != NULL) {
124*45916cd2Sjpk 		while (*darp != NULL)
125*45916cd2Sjpk 			free(*darp++);
126*45916cd2Sjpk 		free(dmap->dmap_devarray);
127*45916cd2Sjpk 		dmap->dmap_devarray = NULL;
128*45916cd2Sjpk 	}
129*45916cd2Sjpk }
130*45916cd2Sjpk 
131*45916cd2Sjpk /*
132*45916cd2Sjpk  * setdmapfile -
133*45916cd2Sjpk  *	changes the default device_maps file to the one specified.
134*45916cd2Sjpk  *	It does not close the previous file. If this is desired, enddmapent
135*45916cd2Sjpk  *	should be called prior to setdampfile.
136*45916cd2Sjpk  */
137*45916cd2Sjpk void
138*45916cd2Sjpk setdmapfile(char *file)
139*45916cd2Sjpk {
140*45916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
141*45916cd2Sjpk 
142*45916cd2Sjpk 	if (_dmap == NULL)
143*45916cd2Sjpk 		return;
144*45916cd2Sjpk 	if (dmapf != NULL) {
145*45916cd2Sjpk 		(void) fclose(dmapf);
146*45916cd2Sjpk 		dmapf = NULL;
147*45916cd2Sjpk 	}
148*45916cd2Sjpk 	DEVMAPS_FILE = file;
149*45916cd2Sjpk }
150*45916cd2Sjpk 
151*45916cd2Sjpk /*
152*45916cd2Sjpk  * getdmapent -
153*45916cd2Sjpk  * 	When first called, returns a pointer to the first devmap_t structure
154*45916cd2Sjpk  * 	in device_maps; thereafter, it returns a pointer to the next devmap_t
155*45916cd2Sjpk  *	structure in the file. Thus successive calls can be used to read the
156*45916cd2Sjpk  *	entire file.
157*45916cd2Sjpk  *	call to getdmapent should be bracketed by setdmapent and enddmapent.
158*45916cd2Sjpk  * 	returns pointer to devmap_t found, else returns NULL if no entry found
159*45916cd2Sjpk  * 	or on error.
160*45916cd2Sjpk  */
161*45916cd2Sjpk devmap_t *
162*45916cd2Sjpk getdmapent(void)
163*45916cd2Sjpk {
164*45916cd2Sjpk 	devmap_t		*dmap;
165*45916cd2Sjpk 	struct _dmapbuff 	*_dmap = _dmapalloc();
166*45916cd2Sjpk 
167*45916cd2Sjpk 	if ((_dmap == 0) || (dmapf == NULL))
168*45916cd2Sjpk 		return (NULL);
169*45916cd2Sjpk 
170*45916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
171*45916cd2Sjpk 	    dmapf) != 0) {
172*45916cd2Sjpk 		if ((dmap = dmap_interpret(interpdmline,
173*45916cd2Sjpk 		    &interpdevmap)) == NULL)
174*45916cd2Sjpk 			continue;
175*45916cd2Sjpk 		return (dmap);
176*45916cd2Sjpk 	}
177*45916cd2Sjpk 
178*45916cd2Sjpk 	return (NULL);
179*45916cd2Sjpk }
180*45916cd2Sjpk 
181*45916cd2Sjpk /*
182*45916cd2Sjpk  * getdmapnam -
183*45916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
184*45916cd2Sjpk  *	its name.
185*45916cd2Sjpk  *	call to getdmapnam should be bracketed by setdmapent and enddmapent.
186*45916cd2Sjpk  * 	returns pointer to devmapt_t for the device if it is found, else
187*45916cd2Sjpk  * 	returns NULL if device not found or in case of error.
188*45916cd2Sjpk  */
189*45916cd2Sjpk devmap_t *
190*45916cd2Sjpk getdmapnam(char *name)
191*45916cd2Sjpk {
192*45916cd2Sjpk 	devmap_t		*dmap;
193*45916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
194*45916cd2Sjpk 
195*45916cd2Sjpk 	if ((name == NULL) || (_dmap == 0) || (dmapf == NULL))
196*45916cd2Sjpk 		return (NULL);
197*45916cd2Sjpk 
198*45916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
199*45916cd2Sjpk 	    dmapf) != 0) {
200*45916cd2Sjpk 		if (strstr(interpdmline, name) == NULL)
201*45916cd2Sjpk 			continue;
202*45916cd2Sjpk 		if ((dmap = dmap_interpretf(interpdmline,
203*45916cd2Sjpk 		    &interpdevmap)) == NULL)
204*45916cd2Sjpk 			continue;
205*45916cd2Sjpk 		if (dmap_matchname(dmap, name)) {
206*45916cd2Sjpk 			if ((dmap = dmap_dlexpand(dmap)) == NULL)
207*45916cd2Sjpk 				continue;
208*45916cd2Sjpk 			enddmapent();
209*45916cd2Sjpk 			return (dmap);
210*45916cd2Sjpk 		}
211*45916cd2Sjpk 		freedmapent(dmap);
212*45916cd2Sjpk 	}
213*45916cd2Sjpk 
214*45916cd2Sjpk 	return (NULL);
215*45916cd2Sjpk }
216*45916cd2Sjpk 
217*45916cd2Sjpk /*
218*45916cd2Sjpk  * getdmapdev -
219*45916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
220*45916cd2Sjpk  *	its logical name.
221*45916cd2Sjpk  *	call to getdmapdev should be bracketed by setdmapent and enddmapent.
222*45916cd2Sjpk  * 	returns  pointer to the devmap_t for the device if device is found,
223*45916cd2Sjpk  *	else returns NULL if device not found or on error.
224*45916cd2Sjpk  */
225*45916cd2Sjpk devmap_t *
226*45916cd2Sjpk getdmapdev(char *dev)
227*45916cd2Sjpk {
228*45916cd2Sjpk 	devmap_t		*dmap;
229*45916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
230*45916cd2Sjpk 
231*45916cd2Sjpk 	if ((dev == NULL) || (_dmap == 0) || (dmapf == NULL))
232*45916cd2Sjpk 		return (NULL);
233*45916cd2Sjpk 
234*45916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
235*45916cd2Sjpk 	    dmapf) != 0) {
236*45916cd2Sjpk 		if ((dmap = dmap_interpret(interpdmline,
237*45916cd2Sjpk 		    &interpdevmap)) == NULL)
238*45916cd2Sjpk 			continue;
239*45916cd2Sjpk 		if (dmap_matchdev(dmap, dev)) {
240*45916cd2Sjpk 			enddmapent();
241*45916cd2Sjpk 			return (dmap);
242*45916cd2Sjpk 		}
243*45916cd2Sjpk 		freedmapent(dmap);
244*45916cd2Sjpk 	}
245*45916cd2Sjpk 
246*45916cd2Sjpk 	return (NULL);
247*45916cd2Sjpk }
248*45916cd2Sjpk 
249*45916cd2Sjpk /*
250*45916cd2Sjpk  * getdmaptype -
251*45916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
252*45916cd2Sjpk  *	its type.
253*45916cd2Sjpk  *	call to getdmaptype should be bracketed by setdmapent and enddmapent.
254*45916cd2Sjpk  * 	returns pointer to devmap_t found, else returns NULL if no entry found
255*45916cd2Sjpk  * 	or on error.
256*45916cd2Sjpk  */
257*45916cd2Sjpk devmap_t *
258*45916cd2Sjpk getdmaptype(char *type)
259*45916cd2Sjpk {
260*45916cd2Sjpk 	devmap_t		*dmap;
261*45916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
262*45916cd2Sjpk 
263*45916cd2Sjpk 	if ((type == NULL) || (_dmap == 0) || (dmapf == NULL))
264*45916cd2Sjpk 		return (NULL);
265*45916cd2Sjpk 
266*45916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
267*45916cd2Sjpk 	    dmapf) != 0) {
268*45916cd2Sjpk 		if ((dmap = dmap_interpretf(interpdmline,
269*45916cd2Sjpk 		    &interpdevmap)) == NULL)
270*45916cd2Sjpk 			continue;
271*45916cd2Sjpk 		if (dmap->dmap_devtype != NULL &&
272*45916cd2Sjpk 		    strcmp(type, dmap->dmap_devtype) == 0) {
273*45916cd2Sjpk 			if ((dmap = dmap_dlexpand(dmap)) == NULL)
274*45916cd2Sjpk 				continue;
275*45916cd2Sjpk 			return (dmap);
276*45916cd2Sjpk 		}
277*45916cd2Sjpk 		freedmapent(dmap);
278*45916cd2Sjpk 	}
279*45916cd2Sjpk 
280*45916cd2Sjpk 	return (NULL);
281*45916cd2Sjpk }
282*45916cd2Sjpk 
283*45916cd2Sjpk /*
284*45916cd2Sjpk  * dmap_matchdev -
285*45916cd2Sjpk  * 	checks if the specified devmap_t is for the device specified.
286*45916cd2Sjpk  *	returns 1 if it is, else returns 0.
287*45916cd2Sjpk  */
288*45916cd2Sjpk int
289*45916cd2Sjpk dmap_matchdev(devmap_t *dmap, char *dev)
290*45916cd2Sjpk {
291*45916cd2Sjpk 	char **dva;
292*45916cd2Sjpk 	char *dv;
293*45916cd2Sjpk 
294*45916cd2Sjpk 	if (dmap->dmap_devarray == NULL)
295*45916cd2Sjpk 		return (0);
296*45916cd2Sjpk 	for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva ++) {
297*45916cd2Sjpk 		if (strcmp(dv, dev) == 0)
298*45916cd2Sjpk 			return (1);
299*45916cd2Sjpk 	}
300*45916cd2Sjpk 
301*45916cd2Sjpk 	return (0);
302*45916cd2Sjpk }
303*45916cd2Sjpk 
304*45916cd2Sjpk /*
305*45916cd2Sjpk  * dmap_matchtype -
306*45916cd2Sjpk  *	checks if the specified devmap_t is for the device specified.
307*45916cd2Sjpk  *	returns 1 if it is, else returns 0.
308*45916cd2Sjpk  */
309*45916cd2Sjpk int
310*45916cd2Sjpk dmap_matchtype(devmap_t *dmap, char *type)
311*45916cd2Sjpk {
312*45916cd2Sjpk 	if ((dmap->dmap_devtype == NULL) || (type == NULL))
313*45916cd2Sjpk 		return (0);
314*45916cd2Sjpk 
315*45916cd2Sjpk 	return ((strcmp(dmap->dmap_devtype, type) == 0));
316*45916cd2Sjpk }
317*45916cd2Sjpk 
318*45916cd2Sjpk /*
319*45916cd2Sjpk  * dmap_matchname -
320*45916cd2Sjpk  * 	checks if the specified devmap_t is for the device specified.
321*45916cd2Sjpk  * 	returns 1 if it is, else returns 0.
322*45916cd2Sjpk  */
323*45916cd2Sjpk int
324*45916cd2Sjpk dmap_matchname(devmap_t *dmap, char *name)
325*45916cd2Sjpk {
326*45916cd2Sjpk 	if (dmap->dmap_devname == NULL)
327*45916cd2Sjpk 		return (0);
328*45916cd2Sjpk 
329*45916cd2Sjpk 	return ((strcmp(dmap->dmap_devname, name) == 0));
330*45916cd2Sjpk }
331*45916cd2Sjpk 
332*45916cd2Sjpk /*
333*45916cd2Sjpk  * dm_match -
334*45916cd2Sjpk  *	calls dmap_matchname or dmap_matchtype as appropriate.
335*45916cd2Sjpk  */
336*45916cd2Sjpk int
337*45916cd2Sjpk dm_match(devmap_t *dmap, da_args *dargs)
338*45916cd2Sjpk {
339*45916cd2Sjpk 	if (dargs->devinfo->devname)
340*45916cd2Sjpk 		return (dmap_matchname(dmap, dargs->devinfo->devname));
341*45916cd2Sjpk 	else if (dargs->devinfo->devtype)
342*45916cd2Sjpk 		return (dmap_matchtype(dmap, dargs->devinfo->devtype));
343*45916cd2Sjpk 
344*45916cd2Sjpk 	return (0);
345*45916cd2Sjpk }
346*45916cd2Sjpk 
347*45916cd2Sjpk /*
348*45916cd2Sjpk  * dmap_interpret -
349*45916cd2Sjpk  *	calls dmap_interpretf and dmap_dlexpand to parse devmap_t line.
350*45916cd2Sjpk  *	returns  pointer to parsed devmapt_t entry, else returns NULL on error.
351*45916cd2Sjpk  */
352*45916cd2Sjpk devmap_t  *
353*45916cd2Sjpk dmap_interpret(char *val, devmap_t *dm)
354*45916cd2Sjpk {
355*45916cd2Sjpk 	if (dmap_interpretf(val, dm) == NULL)
356*45916cd2Sjpk 		return (NULL);
357*45916cd2Sjpk 
358*45916cd2Sjpk 	return (dmap_dlexpand(dm));
359*45916cd2Sjpk }
360*45916cd2Sjpk 
361*45916cd2Sjpk /*
362*45916cd2Sjpk  * dmap_interpretf -
363*45916cd2Sjpk  * 	parses string "val" and initializes pointers in the given devmap_t to
364*45916cd2Sjpk  * 	fields in "val".
365*45916cd2Sjpk  * 	returns pointer to updated devmap_t.
366*45916cd2Sjpk  */
367*45916cd2Sjpk static devmap_t  *
368*45916cd2Sjpk dmap_interpretf(char *val, devmap_t *dm)
369*45916cd2Sjpk {
370*45916cd2Sjpk 	dm->dmap_devname = getdadmfield(val, KV_TOKEN_DELIMIT);
371*45916cd2Sjpk 	dm->dmap_devtype = getdadmfield(NULL, KV_TOKEN_DELIMIT);
372*45916cd2Sjpk 	dm->dmap_devlist = getdadmfield(NULL, KV_TOKEN_DELIMIT);
373*45916cd2Sjpk 	dm->dmap_devarray = NULL;
374*45916cd2Sjpk 	if (dm->dmap_devname == NULL ||
375*45916cd2Sjpk 	    dm->dmap_devtype == NULL ||
376*45916cd2Sjpk 	    dm->dmap_devlist == NULL)
377*45916cd2Sjpk 		return (NULL);
378*45916cd2Sjpk 
379*45916cd2Sjpk 	return (dm);
380*45916cd2Sjpk }
381*45916cd2Sjpk 
382*45916cd2Sjpk /*
383*45916cd2Sjpk  * dmap_dlexpand -
384*45916cd2Sjpk  * 	expands dmap_devlist of the form `devlist_generate`
385*45916cd2Sjpk  *	returns unexpanded form if there is no '\`' or in case of error.
386*45916cd2Sjpk  */
387*45916cd2Sjpk static devmap_t *
388*45916cd2Sjpk dmap_dlexpand(devmap_t *dmp)
389*45916cd2Sjpk {
390*45916cd2Sjpk 	char	tmplist[DA_BUFSIZE + 1];
391*45916cd2Sjpk 	char	*cp, *cpl, **darp;
392*45916cd2Sjpk 	int	count;
393*45916cd2Sjpk 	FILE	*expansion;
394*45916cd2Sjpk 
395*45916cd2Sjpk 	dmp->dmap_devarray = NULL;
396*45916cd2Sjpk 	if (dmp->dmap_devlist == NULL)
397*45916cd2Sjpk 		return (NULL);
398*45916cd2Sjpk 	if (*(dmp->dmap_devlist) != '`') {
399*45916cd2Sjpk 		(void) strcpy(tmplist, dmp->dmap_devlist);
400*45916cd2Sjpk 	} else {
401*45916cd2Sjpk 		(void) strcpy(tmplist, dmp->dmap_devlist + 1);
402*45916cd2Sjpk 		if ((cp = strchr(tmplist, '`')) != NULL)
403*45916cd2Sjpk 			*cp = '\0';
404*45916cd2Sjpk 		if ((expansion = popen(tmplist, "r")) == NULL)
405*45916cd2Sjpk 			return (NULL);
406*45916cd2Sjpk 		count = fread(tmplist, 1, sizeof (tmplist) - 1, expansion);
407*45916cd2Sjpk 		(void) pclose(expansion);
408*45916cd2Sjpk 		tmplist[count] = '\0';
409*45916cd2Sjpk 	}
410*45916cd2Sjpk 
411*45916cd2Sjpk 	/* cleanup the list */
412*45916cd2Sjpk 	count = pack_white(tmplist);
413*45916cd2Sjpk 	dmp->dmap_devarray = darp =
414*45916cd2Sjpk 	    (char **)malloc((count + 2) * sizeof (char *));
415*45916cd2Sjpk 	if (darp == NULL)
416*45916cd2Sjpk 		return (NULL);
417*45916cd2Sjpk 	cp = tmplist;
418*45916cd2Sjpk 	while ((cp = strtok_r(cp, " ", &cpl)) != NULL) {
419*45916cd2Sjpk 		*darp = strdup(cp);
420*45916cd2Sjpk 		if (*darp == NULL) {
421*45916cd2Sjpk 			freedmapent(dmp);
422*45916cd2Sjpk 			return (NULL);
423*45916cd2Sjpk 		}
424*45916cd2Sjpk 		darp++;
425*45916cd2Sjpk 		cp = NULL;
426*45916cd2Sjpk 	}
427*45916cd2Sjpk 	*darp = NULL;
428*45916cd2Sjpk 
429*45916cd2Sjpk 	return (dmp);
430*45916cd2Sjpk }
431*45916cd2Sjpk 
432*45916cd2Sjpk /*
433*45916cd2Sjpk  * dmapskip -
434*45916cd2Sjpk  * 	scans input string to find next colon or end of line.
435*45916cd2Sjpk  *	returns pointer to next char.
4367c478bd9Sstevel@tonic-gate  */
4377c478bd9Sstevel@tonic-gate static char *
438*45916cd2Sjpk dmapskip(char *p)
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate 	while (*p && *p != ':' && *p != '\n')
4417c478bd9Sstevel@tonic-gate 		++p;
4427c478bd9Sstevel@tonic-gate 	if (*p == '\n')
4437c478bd9Sstevel@tonic-gate 		*p = '\0';
4447c478bd9Sstevel@tonic-gate 	else if (*p != '\0')
4457c478bd9Sstevel@tonic-gate 		*p++ = '\0';
446*45916cd2Sjpk 
4477c478bd9Sstevel@tonic-gate 	return (p);
4487c478bd9Sstevel@tonic-gate }
449*45916cd2Sjpk 
4507c478bd9Sstevel@tonic-gate /*
451*45916cd2Sjpk  * dmapdskip -
452*45916cd2Sjpk  * 	scans input string to find next space or end of line.
453*45916cd2Sjpk  *	returns pointer to next char.
4547c478bd9Sstevel@tonic-gate  */
4557c478bd9Sstevel@tonic-gate static char *
456*45916cd2Sjpk dmapdskip(p)
457*45916cd2Sjpk 	register char *p;
4587c478bd9Sstevel@tonic-gate {
4597c478bd9Sstevel@tonic-gate 	while (*p && *p != ' ' && *p != '\n')
4607c478bd9Sstevel@tonic-gate 		++p;
4617c478bd9Sstevel@tonic-gate 	if (*p != '\0')
4627c478bd9Sstevel@tonic-gate 		*p++ = '\0';
463*45916cd2Sjpk 
4647c478bd9Sstevel@tonic-gate 	return (p);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate 
467*45916cd2Sjpk char *
468*45916cd2Sjpk getdmapfield(char *ptr)
4697c478bd9Sstevel@tonic-gate {
4707c478bd9Sstevel@tonic-gate 	static	char	*tptr;
471*45916cd2Sjpk 
4727c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
4737c478bd9Sstevel@tonic-gate 		ptr = tptr;
4747c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
4757c478bd9Sstevel@tonic-gate 		return (NULL);
4767c478bd9Sstevel@tonic-gate 	tptr = dmapskip(ptr);
4777c478bd9Sstevel@tonic-gate 	ptr = trim_white(ptr);
4787c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
4797c478bd9Sstevel@tonic-gate 		return (NULL);
4807c478bd9Sstevel@tonic-gate 	if (*ptr == NULL)
4817c478bd9Sstevel@tonic-gate 		return (NULL);
482*45916cd2Sjpk 
4837c478bd9Sstevel@tonic-gate 	return (ptr);
4847c478bd9Sstevel@tonic-gate }
485*45916cd2Sjpk 
486*45916cd2Sjpk char *
487*45916cd2Sjpk getdmapdfield(char *ptr)
4887c478bd9Sstevel@tonic-gate {
4897c478bd9Sstevel@tonic-gate 	static	char	*tptr;
4907c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
4917c478bd9Sstevel@tonic-gate 		ptr = trim_white(ptr);
4927c478bd9Sstevel@tonic-gate 	} else {
4937c478bd9Sstevel@tonic-gate 		ptr = tptr;
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
4967c478bd9Sstevel@tonic-gate 		return (NULL);
4977c478bd9Sstevel@tonic-gate 	tptr = dmapdskip(ptr);
4987c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
4997c478bd9Sstevel@tonic-gate 		return (NULL);
5007c478bd9Sstevel@tonic-gate 	if (*ptr == NULL)
5017c478bd9Sstevel@tonic-gate 		return (NULL);
502*45916cd2Sjpk 
5037c478bd9Sstevel@tonic-gate 	return (ptr);
5047c478bd9Sstevel@tonic-gate }
505