xref: /titanic_52/usr/src/lib/libbsm/common/getdment.c (revision 004388ebfdfe2ed7dfd2d153a876dfcc22d2c006)
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 /*
2245916cd2Sjpk  * 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>
2945916cd2Sjpk #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <bsm/devices.h>
3145916cd2Sjpk #include <bsm/devalloc.h>
327c478bd9Sstevel@tonic-gate 
3345916cd2Sjpk char *strtok_r(char *, const char *, char **);
3445916cd2Sjpk 
3545916cd2Sjpk /* externs from getdaent.c */
3645916cd2Sjpk extern char *trim_white(char *);
3745916cd2Sjpk extern int pack_white(char *);
3845916cd2Sjpk extern char *getdadmfield(char *, char *);
3945916cd2Sjpk extern int getdadmline(char *, int, FILE *);
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static struct _dmapbuff {
4245916cd2Sjpk 	FILE		*_dmapf;	/* for /etc/security/device_maps */
437c478bd9Sstevel@tonic-gate 	devmap_t	_interpdevmap;
4445916cd2Sjpk 	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)
5045916cd2Sjpk #define	interpdmline	(_dmap->_interpdmline)
5145916cd2Sjpk #define	DEVMAPS_FILE	(_dmap->_DEVMAP)
5245916cd2Sjpk 
5345916cd2Sjpk devmap_t	*dmap_interpret(char *, devmap_t *);
5445916cd2Sjpk static devmap_t	*dmap_interpretf(char *, devmap_t *);
5545916cd2Sjpk static devmap_t *dmap_dlexpand(devmap_t *);
5645916cd2Sjpk 
5745916cd2Sjpk int	dmap_matchdev(devmap_t *, char *);
5845916cd2Sjpk int	dmap_matchname(devmap_t *, char *);
5945916cd2Sjpk 
6045916cd2Sjpk 
617c478bd9Sstevel@tonic-gate /*
6245916cd2Sjpk  * _dmapalloc -
6345916cd2Sjpk  *	allocates common buffers and structures.
6445916cd2Sjpk  *	returns pointer to the new structure, else returns NULL on error.
657c478bd9Sstevel@tonic-gate  */
6645916cd2Sjpk static struct _dmapbuff *
6745916cd2Sjpk _dmapalloc(void)
687c478bd9Sstevel@tonic-gate {
6945916cd2Sjpk 	struct _dmapbuff *_dmap = __dmapbuff;
7045916cd2Sjpk 
7145916cd2Sjpk 	if (_dmap == NULL) {
7245916cd2Sjpk 		_dmap = (struct _dmapbuff *)calloc((unsigned)1,
7345916cd2Sjpk 		    (unsigned)sizeof (*__dmapbuff));
7445916cd2Sjpk 		if (_dmap == NULL)
757c478bd9Sstevel@tonic-gate 			return (NULL);
7645916cd2Sjpk 		DEVMAPS_FILE = "/etc/security/device_maps";
7745916cd2Sjpk 		dmapf = NULL;
7845916cd2Sjpk 		__dmapbuff = _dmap;
797c478bd9Sstevel@tonic-gate 	}
8045916cd2Sjpk 
8145916cd2Sjpk 	return (_dmap);
827c478bd9Sstevel@tonic-gate }
8345916cd2Sjpk 
847c478bd9Sstevel@tonic-gate /*
8545916cd2Sjpk  * setdmapent -
8645916cd2Sjpk  *	rewinds the device_maps file to the beginning.
8745916cd2Sjpk  */
8845916cd2Sjpk void
8945916cd2Sjpk setdmapent(void)
9045916cd2Sjpk {
9145916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
9245916cd2Sjpk 
9345916cd2Sjpk 	if (_dmap == NULL)
9445916cd2Sjpk 		return;
9545916cd2Sjpk 	if (dmapf == NULL)
96*004388ebScasper 		dmapf = fopen(DEVMAPS_FILE, "rF");
9745916cd2Sjpk 	else
9845916cd2Sjpk 		rewind(dmapf);
9945916cd2Sjpk }
10045916cd2Sjpk 
10145916cd2Sjpk /*
10245916cd2Sjpk  * enddmapent -
10345916cd2Sjpk  *	closes device_maps file.
10445916cd2Sjpk  */
10545916cd2Sjpk void
10645916cd2Sjpk enddmapent(void)
10745916cd2Sjpk {
10845916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
10945916cd2Sjpk 
11045916cd2Sjpk 	if (_dmap == NULL)
11145916cd2Sjpk 		return;
11245916cd2Sjpk 	if (dmapf != NULL) {
11345916cd2Sjpk 		(void) fclose(dmapf);
11445916cd2Sjpk 		dmapf = NULL;
11545916cd2Sjpk 	}
11645916cd2Sjpk }
11745916cd2Sjpk 
11845916cd2Sjpk void
11945916cd2Sjpk freedmapent(devmap_t *dmap)
12045916cd2Sjpk {
12145916cd2Sjpk 	char	**darp;
12245916cd2Sjpk 
12345916cd2Sjpk 	if ((darp = dmap->dmap_devarray) != NULL) {
12445916cd2Sjpk 		while (*darp != NULL)
12545916cd2Sjpk 			free(*darp++);
12645916cd2Sjpk 		free(dmap->dmap_devarray);
12745916cd2Sjpk 		dmap->dmap_devarray = NULL;
12845916cd2Sjpk 	}
12945916cd2Sjpk }
13045916cd2Sjpk 
13145916cd2Sjpk /*
13245916cd2Sjpk  * setdmapfile -
13345916cd2Sjpk  *	changes the default device_maps file to the one specified.
13445916cd2Sjpk  *	It does not close the previous file. If this is desired, enddmapent
13545916cd2Sjpk  *	should be called prior to setdampfile.
13645916cd2Sjpk  */
13745916cd2Sjpk void
13845916cd2Sjpk setdmapfile(char *file)
13945916cd2Sjpk {
14045916cd2Sjpk 	struct _dmapbuff *_dmap = _dmapalloc();
14145916cd2Sjpk 
14245916cd2Sjpk 	if (_dmap == NULL)
14345916cd2Sjpk 		return;
14445916cd2Sjpk 	if (dmapf != NULL) {
14545916cd2Sjpk 		(void) fclose(dmapf);
14645916cd2Sjpk 		dmapf = NULL;
14745916cd2Sjpk 	}
14845916cd2Sjpk 	DEVMAPS_FILE = file;
14945916cd2Sjpk }
15045916cd2Sjpk 
15145916cd2Sjpk /*
15245916cd2Sjpk  * getdmapent -
15345916cd2Sjpk  * 	When first called, returns a pointer to the first devmap_t structure
15445916cd2Sjpk  * 	in device_maps; thereafter, it returns a pointer to the next devmap_t
15545916cd2Sjpk  *	structure in the file. Thus successive calls can be used to read the
15645916cd2Sjpk  *	entire file.
15745916cd2Sjpk  *	call to getdmapent should be bracketed by setdmapent and enddmapent.
15845916cd2Sjpk  * 	returns pointer to devmap_t found, else returns NULL if no entry found
15945916cd2Sjpk  * 	or on error.
16045916cd2Sjpk  */
16145916cd2Sjpk devmap_t *
16245916cd2Sjpk getdmapent(void)
16345916cd2Sjpk {
16445916cd2Sjpk 	devmap_t		*dmap;
16545916cd2Sjpk 	struct _dmapbuff 	*_dmap = _dmapalloc();
16645916cd2Sjpk 
16745916cd2Sjpk 	if ((_dmap == 0) || (dmapf == NULL))
16845916cd2Sjpk 		return (NULL);
16945916cd2Sjpk 
17045916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
17145916cd2Sjpk 	    dmapf) != 0) {
17245916cd2Sjpk 		if ((dmap = dmap_interpret(interpdmline,
17345916cd2Sjpk 		    &interpdevmap)) == NULL)
17445916cd2Sjpk 			continue;
17545916cd2Sjpk 		return (dmap);
17645916cd2Sjpk 	}
17745916cd2Sjpk 
17845916cd2Sjpk 	return (NULL);
17945916cd2Sjpk }
18045916cd2Sjpk 
18145916cd2Sjpk /*
18245916cd2Sjpk  * getdmapnam -
18345916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
18445916cd2Sjpk  *	its name.
18545916cd2Sjpk  *	call to getdmapnam should be bracketed by setdmapent and enddmapent.
18645916cd2Sjpk  * 	returns pointer to devmapt_t for the device if it is found, else
18745916cd2Sjpk  * 	returns NULL if device not found or in case of error.
18845916cd2Sjpk  */
18945916cd2Sjpk devmap_t *
19045916cd2Sjpk getdmapnam(char *name)
19145916cd2Sjpk {
19245916cd2Sjpk 	devmap_t		*dmap;
19345916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
19445916cd2Sjpk 
19545916cd2Sjpk 	if ((name == NULL) || (_dmap == 0) || (dmapf == NULL))
19645916cd2Sjpk 		return (NULL);
19745916cd2Sjpk 
19845916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
19945916cd2Sjpk 	    dmapf) != 0) {
20045916cd2Sjpk 		if (strstr(interpdmline, name) == NULL)
20145916cd2Sjpk 			continue;
20245916cd2Sjpk 		if ((dmap = dmap_interpretf(interpdmline,
20345916cd2Sjpk 		    &interpdevmap)) == NULL)
20445916cd2Sjpk 			continue;
20545916cd2Sjpk 		if (dmap_matchname(dmap, name)) {
20645916cd2Sjpk 			if ((dmap = dmap_dlexpand(dmap)) == NULL)
20745916cd2Sjpk 				continue;
20845916cd2Sjpk 			enddmapent();
20945916cd2Sjpk 			return (dmap);
21045916cd2Sjpk 		}
21145916cd2Sjpk 		freedmapent(dmap);
21245916cd2Sjpk 	}
21345916cd2Sjpk 
21445916cd2Sjpk 	return (NULL);
21545916cd2Sjpk }
21645916cd2Sjpk 
21745916cd2Sjpk /*
21845916cd2Sjpk  * getdmapdev -
21945916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
22045916cd2Sjpk  *	its logical name.
22145916cd2Sjpk  *	call to getdmapdev should be bracketed by setdmapent and enddmapent.
22245916cd2Sjpk  * 	returns  pointer to the devmap_t for the device if device is found,
22345916cd2Sjpk  *	else returns NULL if device not found or on error.
22445916cd2Sjpk  */
22545916cd2Sjpk devmap_t *
22645916cd2Sjpk getdmapdev(char *dev)
22745916cd2Sjpk {
22845916cd2Sjpk 	devmap_t		*dmap;
22945916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
23045916cd2Sjpk 
23145916cd2Sjpk 	if ((dev == NULL) || (_dmap == 0) || (dmapf == NULL))
23245916cd2Sjpk 		return (NULL);
23345916cd2Sjpk 
23445916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
23545916cd2Sjpk 	    dmapf) != 0) {
23645916cd2Sjpk 		if ((dmap = dmap_interpret(interpdmline,
23745916cd2Sjpk 		    &interpdevmap)) == NULL)
23845916cd2Sjpk 			continue;
23945916cd2Sjpk 		if (dmap_matchdev(dmap, dev)) {
24045916cd2Sjpk 			enddmapent();
24145916cd2Sjpk 			return (dmap);
24245916cd2Sjpk 		}
24345916cd2Sjpk 		freedmapent(dmap);
24445916cd2Sjpk 	}
24545916cd2Sjpk 
24645916cd2Sjpk 	return (NULL);
24745916cd2Sjpk }
24845916cd2Sjpk 
24945916cd2Sjpk /*
25045916cd2Sjpk  * getdmaptype -
25145916cd2Sjpk  *	searches from the beginning of device_maps for the device specified by
25245916cd2Sjpk  *	its type.
25345916cd2Sjpk  *	call to getdmaptype should be bracketed by setdmapent and enddmapent.
25445916cd2Sjpk  * 	returns pointer to devmap_t found, else returns NULL if no entry found
25545916cd2Sjpk  * 	or on error.
25645916cd2Sjpk  */
25745916cd2Sjpk devmap_t *
25845916cd2Sjpk getdmaptype(char *type)
25945916cd2Sjpk {
26045916cd2Sjpk 	devmap_t		*dmap;
26145916cd2Sjpk 	struct _dmapbuff	*_dmap = _dmapalloc();
26245916cd2Sjpk 
26345916cd2Sjpk 	if ((type == NULL) || (_dmap == 0) || (dmapf == NULL))
26445916cd2Sjpk 		return (NULL);
26545916cd2Sjpk 
26645916cd2Sjpk 	while (getdadmline(interpdmline, (int)sizeof (interpdmline),
26745916cd2Sjpk 	    dmapf) != 0) {
26845916cd2Sjpk 		if ((dmap = dmap_interpretf(interpdmline,
26945916cd2Sjpk 		    &interpdevmap)) == NULL)
27045916cd2Sjpk 			continue;
27145916cd2Sjpk 		if (dmap->dmap_devtype != NULL &&
27245916cd2Sjpk 		    strcmp(type, dmap->dmap_devtype) == 0) {
27345916cd2Sjpk 			if ((dmap = dmap_dlexpand(dmap)) == NULL)
27445916cd2Sjpk 				continue;
27545916cd2Sjpk 			return (dmap);
27645916cd2Sjpk 		}
27745916cd2Sjpk 		freedmapent(dmap);
27845916cd2Sjpk 	}
27945916cd2Sjpk 
28045916cd2Sjpk 	return (NULL);
28145916cd2Sjpk }
28245916cd2Sjpk 
28345916cd2Sjpk /*
28445916cd2Sjpk  * dmap_matchdev -
28545916cd2Sjpk  * 	checks if the specified devmap_t is for the device specified.
28645916cd2Sjpk  *	returns 1 if it is, else returns 0.
28745916cd2Sjpk  */
28845916cd2Sjpk int
28945916cd2Sjpk dmap_matchdev(devmap_t *dmap, char *dev)
29045916cd2Sjpk {
29145916cd2Sjpk 	char **dva;
29245916cd2Sjpk 	char *dv;
29345916cd2Sjpk 
29445916cd2Sjpk 	if (dmap->dmap_devarray == NULL)
29545916cd2Sjpk 		return (0);
29645916cd2Sjpk 	for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva ++) {
29745916cd2Sjpk 		if (strcmp(dv, dev) == 0)
29845916cd2Sjpk 			return (1);
29945916cd2Sjpk 	}
30045916cd2Sjpk 
30145916cd2Sjpk 	return (0);
30245916cd2Sjpk }
30345916cd2Sjpk 
30445916cd2Sjpk /*
30545916cd2Sjpk  * dmap_matchtype -
30645916cd2Sjpk  *	checks if the specified devmap_t is for the device specified.
30745916cd2Sjpk  *	returns 1 if it is, else returns 0.
30845916cd2Sjpk  */
30945916cd2Sjpk int
31045916cd2Sjpk dmap_matchtype(devmap_t *dmap, char *type)
31145916cd2Sjpk {
31245916cd2Sjpk 	if ((dmap->dmap_devtype == NULL) || (type == NULL))
31345916cd2Sjpk 		return (0);
31445916cd2Sjpk 
31545916cd2Sjpk 	return ((strcmp(dmap->dmap_devtype, type) == 0));
31645916cd2Sjpk }
31745916cd2Sjpk 
31845916cd2Sjpk /*
31945916cd2Sjpk  * dmap_matchname -
32045916cd2Sjpk  * 	checks if the specified devmap_t is for the device specified.
32145916cd2Sjpk  * 	returns 1 if it is, else returns 0.
32245916cd2Sjpk  */
32345916cd2Sjpk int
32445916cd2Sjpk dmap_matchname(devmap_t *dmap, char *name)
32545916cd2Sjpk {
32645916cd2Sjpk 	if (dmap->dmap_devname == NULL)
32745916cd2Sjpk 		return (0);
32845916cd2Sjpk 
32945916cd2Sjpk 	return ((strcmp(dmap->dmap_devname, name) == 0));
33045916cd2Sjpk }
33145916cd2Sjpk 
33245916cd2Sjpk /*
33345916cd2Sjpk  * dm_match -
33445916cd2Sjpk  *	calls dmap_matchname or dmap_matchtype as appropriate.
33545916cd2Sjpk  */
33645916cd2Sjpk int
33745916cd2Sjpk dm_match(devmap_t *dmap, da_args *dargs)
33845916cd2Sjpk {
33945916cd2Sjpk 	if (dargs->devinfo->devname)
34045916cd2Sjpk 		return (dmap_matchname(dmap, dargs->devinfo->devname));
34145916cd2Sjpk 	else if (dargs->devinfo->devtype)
34245916cd2Sjpk 		return (dmap_matchtype(dmap, dargs->devinfo->devtype));
34345916cd2Sjpk 
34445916cd2Sjpk 	return (0);
34545916cd2Sjpk }
34645916cd2Sjpk 
34745916cd2Sjpk /*
34845916cd2Sjpk  * dmap_interpret -
34945916cd2Sjpk  *	calls dmap_interpretf and dmap_dlexpand to parse devmap_t line.
35045916cd2Sjpk  *	returns  pointer to parsed devmapt_t entry, else returns NULL on error.
35145916cd2Sjpk  */
35245916cd2Sjpk devmap_t  *
35345916cd2Sjpk dmap_interpret(char *val, devmap_t *dm)
35445916cd2Sjpk {
35545916cd2Sjpk 	if (dmap_interpretf(val, dm) == NULL)
35645916cd2Sjpk 		return (NULL);
35745916cd2Sjpk 
35845916cd2Sjpk 	return (dmap_dlexpand(dm));
35945916cd2Sjpk }
36045916cd2Sjpk 
36145916cd2Sjpk /*
36245916cd2Sjpk  * dmap_interpretf -
36345916cd2Sjpk  * 	parses string "val" and initializes pointers in the given devmap_t to
36445916cd2Sjpk  * 	fields in "val".
36545916cd2Sjpk  * 	returns pointer to updated devmap_t.
36645916cd2Sjpk  */
36745916cd2Sjpk static devmap_t  *
36845916cd2Sjpk dmap_interpretf(char *val, devmap_t *dm)
36945916cd2Sjpk {
37045916cd2Sjpk 	dm->dmap_devname = getdadmfield(val, KV_TOKEN_DELIMIT);
37145916cd2Sjpk 	dm->dmap_devtype = getdadmfield(NULL, KV_TOKEN_DELIMIT);
37245916cd2Sjpk 	dm->dmap_devlist = getdadmfield(NULL, KV_TOKEN_DELIMIT);
37345916cd2Sjpk 	dm->dmap_devarray = NULL;
37445916cd2Sjpk 	if (dm->dmap_devname == NULL ||
37545916cd2Sjpk 	    dm->dmap_devtype == NULL ||
37645916cd2Sjpk 	    dm->dmap_devlist == NULL)
37745916cd2Sjpk 		return (NULL);
37845916cd2Sjpk 
37945916cd2Sjpk 	return (dm);
38045916cd2Sjpk }
38145916cd2Sjpk 
38245916cd2Sjpk /*
38345916cd2Sjpk  * dmap_dlexpand -
38445916cd2Sjpk  * 	expands dmap_devlist of the form `devlist_generate`
38545916cd2Sjpk  *	returns unexpanded form if there is no '\`' or in case of error.
38645916cd2Sjpk  */
38745916cd2Sjpk static devmap_t *
38845916cd2Sjpk dmap_dlexpand(devmap_t *dmp)
38945916cd2Sjpk {
39045916cd2Sjpk 	char	tmplist[DA_BUFSIZE + 1];
39145916cd2Sjpk 	char	*cp, *cpl, **darp;
39245916cd2Sjpk 	int	count;
39345916cd2Sjpk 	FILE	*expansion;
39445916cd2Sjpk 
39545916cd2Sjpk 	dmp->dmap_devarray = NULL;
39645916cd2Sjpk 	if (dmp->dmap_devlist == NULL)
39745916cd2Sjpk 		return (NULL);
39845916cd2Sjpk 	if (*(dmp->dmap_devlist) != '`') {
39945916cd2Sjpk 		(void) strcpy(tmplist, dmp->dmap_devlist);
40045916cd2Sjpk 	} else {
40145916cd2Sjpk 		(void) strcpy(tmplist, dmp->dmap_devlist + 1);
40245916cd2Sjpk 		if ((cp = strchr(tmplist, '`')) != NULL)
40345916cd2Sjpk 			*cp = '\0';
404*004388ebScasper 		if ((expansion = popen(tmplist, "rF")) == NULL)
40545916cd2Sjpk 			return (NULL);
40645916cd2Sjpk 		count = fread(tmplist, 1, sizeof (tmplist) - 1, expansion);
40745916cd2Sjpk 		(void) pclose(expansion);
40845916cd2Sjpk 		tmplist[count] = '\0';
40945916cd2Sjpk 	}
41045916cd2Sjpk 
41145916cd2Sjpk 	/* cleanup the list */
41245916cd2Sjpk 	count = pack_white(tmplist);
41345916cd2Sjpk 	dmp->dmap_devarray = darp =
41445916cd2Sjpk 	    (char **)malloc((count + 2) * sizeof (char *));
41545916cd2Sjpk 	if (darp == NULL)
41645916cd2Sjpk 		return (NULL);
41745916cd2Sjpk 	cp = tmplist;
41845916cd2Sjpk 	while ((cp = strtok_r(cp, " ", &cpl)) != NULL) {
41945916cd2Sjpk 		*darp = strdup(cp);
42045916cd2Sjpk 		if (*darp == NULL) {
42145916cd2Sjpk 			freedmapent(dmp);
42245916cd2Sjpk 			return (NULL);
42345916cd2Sjpk 		}
42445916cd2Sjpk 		darp++;
42545916cd2Sjpk 		cp = NULL;
42645916cd2Sjpk 	}
42745916cd2Sjpk 	*darp = NULL;
42845916cd2Sjpk 
42945916cd2Sjpk 	return (dmp);
43045916cd2Sjpk }
43145916cd2Sjpk 
43245916cd2Sjpk /*
43345916cd2Sjpk  * dmapskip -
43445916cd2Sjpk  * 	scans input string to find next colon or end of line.
43545916cd2Sjpk  *	returns pointer to next char.
4367c478bd9Sstevel@tonic-gate  */
4377c478bd9Sstevel@tonic-gate static char *
43845916cd2Sjpk 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';
44645916cd2Sjpk 
4477c478bd9Sstevel@tonic-gate 	return (p);
4487c478bd9Sstevel@tonic-gate }
44945916cd2Sjpk 
4507c478bd9Sstevel@tonic-gate /*
45145916cd2Sjpk  * dmapdskip -
45245916cd2Sjpk  * 	scans input string to find next space or end of line.
45345916cd2Sjpk  *	returns pointer to next char.
4547c478bd9Sstevel@tonic-gate  */
4557c478bd9Sstevel@tonic-gate static char *
45645916cd2Sjpk dmapdskip(p)
45745916cd2Sjpk 	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';
46345916cd2Sjpk 
4647c478bd9Sstevel@tonic-gate 	return (p);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate 
46745916cd2Sjpk char *
46845916cd2Sjpk getdmapfield(char *ptr)
4697c478bd9Sstevel@tonic-gate {
4707c478bd9Sstevel@tonic-gate 	static	char	*tptr;
47145916cd2Sjpk 
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);
48245916cd2Sjpk 
4837c478bd9Sstevel@tonic-gate 	return (ptr);
4847c478bd9Sstevel@tonic-gate }
48545916cd2Sjpk 
48645916cd2Sjpk char *
48745916cd2Sjpk 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);
50245916cd2Sjpk 
5037c478bd9Sstevel@tonic-gate 	return (ptr);
5047c478bd9Sstevel@tonic-gate }
505