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*7e3e5701SJan Parcel * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <string.h> 27*7e3e5701SJan Parcel #include <strings.h> 2845916cd2Sjpk #include <stdlib.h> 29*7e3e5701SJan Parcel #include <unistd.h> 30*7e3e5701SJan Parcel #include <limits.h> 31*7e3e5701SJan Parcel #include <device_info.h> 327c478bd9Sstevel@tonic-gate #include <bsm/devices.h> 3345916cd2Sjpk #include <bsm/devalloc.h> 347c478bd9Sstevel@tonic-gate 3545916cd2Sjpk char *strtok_r(char *, const char *, char **); 3645916cd2Sjpk 3745916cd2Sjpk /* externs from getdaent.c */ 3845916cd2Sjpk extern char *trim_white(char *); 3945916cd2Sjpk extern int pack_white(char *); 4045916cd2Sjpk extern char *getdadmfield(char *, char *); 4145916cd2Sjpk extern int getdadmline(char *, int, FILE *); 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate static struct _dmapbuff { 4445916cd2Sjpk FILE *_dmapf; /* for /etc/security/device_maps */ 457c478bd9Sstevel@tonic-gate devmap_t _interpdevmap; 4645916cd2Sjpk char _interpdmline[DA_BUFSIZE + 1]; 477c478bd9Sstevel@tonic-gate char *_DEVMAP; 487c478bd9Sstevel@tonic-gate } *__dmapbuff; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #define dmapf (_dmap->_dmapf) 517c478bd9Sstevel@tonic-gate #define interpdevmap (_dmap->_interpdevmap) 5245916cd2Sjpk #define interpdmline (_dmap->_interpdmline) 5345916cd2Sjpk #define DEVMAPS_FILE (_dmap->_DEVMAP) 5445916cd2Sjpk 5545916cd2Sjpk devmap_t *dmap_interpret(char *, devmap_t *); 5645916cd2Sjpk static devmap_t *dmap_interpretf(char *, devmap_t *); 5745916cd2Sjpk static devmap_t *dmap_dlexpand(devmap_t *); 5845916cd2Sjpk 5945916cd2Sjpk int dmap_matchdev(devmap_t *, char *); 6045916cd2Sjpk int dmap_matchname(devmap_t *, char *); 6145916cd2Sjpk 6245916cd2Sjpk 637c478bd9Sstevel@tonic-gate /* 6445916cd2Sjpk * _dmapalloc - 6545916cd2Sjpk * allocates common buffers and structures. 6645916cd2Sjpk * returns pointer to the new structure, else returns NULL on error. 677c478bd9Sstevel@tonic-gate */ 6845916cd2Sjpk static struct _dmapbuff * 6945916cd2Sjpk _dmapalloc(void) 707c478bd9Sstevel@tonic-gate { 7145916cd2Sjpk struct _dmapbuff *_dmap = __dmapbuff; 7245916cd2Sjpk 7345916cd2Sjpk if (_dmap == NULL) { 7445916cd2Sjpk _dmap = (struct _dmapbuff *)calloc((unsigned)1, 7545916cd2Sjpk (unsigned)sizeof (*__dmapbuff)); 7645916cd2Sjpk if (_dmap == NULL) 777c478bd9Sstevel@tonic-gate return (NULL); 7845916cd2Sjpk DEVMAPS_FILE = "/etc/security/device_maps"; 7945916cd2Sjpk dmapf = NULL; 8045916cd2Sjpk __dmapbuff = _dmap; 817c478bd9Sstevel@tonic-gate } 8245916cd2Sjpk 8345916cd2Sjpk return (_dmap); 847c478bd9Sstevel@tonic-gate } 8545916cd2Sjpk 867c478bd9Sstevel@tonic-gate /* 8745916cd2Sjpk * setdmapent - 8845916cd2Sjpk * rewinds the device_maps file to the beginning. 8945916cd2Sjpk */ 9045916cd2Sjpk void 9145916cd2Sjpk setdmapent(void) 9245916cd2Sjpk { 9345916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 9445916cd2Sjpk 9545916cd2Sjpk if (_dmap == NULL) 9645916cd2Sjpk return; 9745916cd2Sjpk if (dmapf == NULL) 98004388ebScasper dmapf = fopen(DEVMAPS_FILE, "rF"); 9945916cd2Sjpk else 10045916cd2Sjpk rewind(dmapf); 10145916cd2Sjpk } 10245916cd2Sjpk 10345916cd2Sjpk /* 10445916cd2Sjpk * enddmapent - 10545916cd2Sjpk * closes device_maps file. 10645916cd2Sjpk */ 10745916cd2Sjpk void 10845916cd2Sjpk enddmapent(void) 10945916cd2Sjpk { 11045916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 11145916cd2Sjpk 11245916cd2Sjpk if (_dmap == NULL) 11345916cd2Sjpk return; 11445916cd2Sjpk if (dmapf != NULL) { 11545916cd2Sjpk (void) fclose(dmapf); 11645916cd2Sjpk dmapf = NULL; 11745916cd2Sjpk } 11845916cd2Sjpk } 11945916cd2Sjpk 12045916cd2Sjpk void 12145916cd2Sjpk freedmapent(devmap_t *dmap) 12245916cd2Sjpk { 12345916cd2Sjpk char **darp; 12445916cd2Sjpk 12545916cd2Sjpk if ((darp = dmap->dmap_devarray) != NULL) { 12645916cd2Sjpk while (*darp != NULL) 12745916cd2Sjpk free(*darp++); 12845916cd2Sjpk free(dmap->dmap_devarray); 12945916cd2Sjpk dmap->dmap_devarray = NULL; 13045916cd2Sjpk } 13145916cd2Sjpk } 13245916cd2Sjpk 13345916cd2Sjpk /* 13445916cd2Sjpk * setdmapfile - 13545916cd2Sjpk * changes the default device_maps file to the one specified. 13645916cd2Sjpk * It does not close the previous file. If this is desired, enddmapent 13745916cd2Sjpk * should be called prior to setdampfile. 13845916cd2Sjpk */ 13945916cd2Sjpk void 14045916cd2Sjpk setdmapfile(char *file) 14145916cd2Sjpk { 14245916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 14345916cd2Sjpk 14445916cd2Sjpk if (_dmap == NULL) 14545916cd2Sjpk return; 14645916cd2Sjpk if (dmapf != NULL) { 14745916cd2Sjpk (void) fclose(dmapf); 14845916cd2Sjpk dmapf = NULL; 14945916cd2Sjpk } 15045916cd2Sjpk DEVMAPS_FILE = file; 15145916cd2Sjpk } 15245916cd2Sjpk 15345916cd2Sjpk /* 15445916cd2Sjpk * getdmapent - 15545916cd2Sjpk * When first called, returns a pointer to the first devmap_t structure 15645916cd2Sjpk * in device_maps; thereafter, it returns a pointer to the next devmap_t 15745916cd2Sjpk * structure in the file. Thus successive calls can be used to read the 15845916cd2Sjpk * entire file. 15945916cd2Sjpk * call to getdmapent should be bracketed by setdmapent and enddmapent. 16045916cd2Sjpk * returns pointer to devmap_t found, else returns NULL if no entry found 16145916cd2Sjpk * or on error. 16245916cd2Sjpk */ 16345916cd2Sjpk devmap_t * 16445916cd2Sjpk getdmapent(void) 16545916cd2Sjpk { 16645916cd2Sjpk devmap_t *dmap; 16745916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 16845916cd2Sjpk 16945916cd2Sjpk if ((_dmap == 0) || (dmapf == NULL)) 17045916cd2Sjpk return (NULL); 17145916cd2Sjpk 17245916cd2Sjpk while (getdadmline(interpdmline, (int)sizeof (interpdmline), 17345916cd2Sjpk dmapf) != 0) { 17445916cd2Sjpk if ((dmap = dmap_interpret(interpdmline, 17545916cd2Sjpk &interpdevmap)) == NULL) 17645916cd2Sjpk continue; 17745916cd2Sjpk return (dmap); 17845916cd2Sjpk } 17945916cd2Sjpk 18045916cd2Sjpk return (NULL); 18145916cd2Sjpk } 18245916cd2Sjpk 18345916cd2Sjpk /* 18445916cd2Sjpk * getdmapnam - 18545916cd2Sjpk * searches from the beginning of device_maps for the device specified by 18645916cd2Sjpk * its name. 18745916cd2Sjpk * call to getdmapnam should be bracketed by setdmapent and enddmapent. 18845916cd2Sjpk * returns pointer to devmapt_t for the device if it is found, else 18945916cd2Sjpk * returns NULL if device not found or in case of error. 19045916cd2Sjpk */ 19145916cd2Sjpk devmap_t * 19245916cd2Sjpk getdmapnam(char *name) 19345916cd2Sjpk { 19445916cd2Sjpk devmap_t *dmap; 19545916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 19645916cd2Sjpk 19745916cd2Sjpk if ((name == NULL) || (_dmap == 0) || (dmapf == NULL)) 19845916cd2Sjpk return (NULL); 19945916cd2Sjpk 20045916cd2Sjpk while (getdadmline(interpdmline, (int)sizeof (interpdmline), 20145916cd2Sjpk dmapf) != 0) { 20245916cd2Sjpk if (strstr(interpdmline, name) == NULL) 20345916cd2Sjpk continue; 20445916cd2Sjpk if ((dmap = dmap_interpretf(interpdmline, 20545916cd2Sjpk &interpdevmap)) == NULL) 20645916cd2Sjpk continue; 20745916cd2Sjpk if (dmap_matchname(dmap, name)) { 20845916cd2Sjpk if ((dmap = dmap_dlexpand(dmap)) == NULL) 20945916cd2Sjpk continue; 21045916cd2Sjpk enddmapent(); 21145916cd2Sjpk return (dmap); 21245916cd2Sjpk } 21345916cd2Sjpk freedmapent(dmap); 21445916cd2Sjpk } 21545916cd2Sjpk 21645916cd2Sjpk return (NULL); 21745916cd2Sjpk } 21845916cd2Sjpk 21945916cd2Sjpk /* 22045916cd2Sjpk * getdmapdev - 22145916cd2Sjpk * searches from the beginning of device_maps for the device specified by 22245916cd2Sjpk * its logical name. 22345916cd2Sjpk * call to getdmapdev should be bracketed by setdmapent and enddmapent. 22445916cd2Sjpk * returns pointer to the devmap_t for the device if device is found, 22545916cd2Sjpk * else returns NULL if device not found or on error. 22645916cd2Sjpk */ 22745916cd2Sjpk devmap_t * 22845916cd2Sjpk getdmapdev(char *dev) 22945916cd2Sjpk { 23045916cd2Sjpk devmap_t *dmap; 23145916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 23245916cd2Sjpk 23345916cd2Sjpk if ((dev == NULL) || (_dmap == 0) || (dmapf == NULL)) 23445916cd2Sjpk return (NULL); 23545916cd2Sjpk 23645916cd2Sjpk while (getdadmline(interpdmline, (int)sizeof (interpdmline), 23745916cd2Sjpk dmapf) != 0) { 23845916cd2Sjpk if ((dmap = dmap_interpret(interpdmline, 23945916cd2Sjpk &interpdevmap)) == NULL) 24045916cd2Sjpk continue; 24145916cd2Sjpk if (dmap_matchdev(dmap, dev)) { 24245916cd2Sjpk enddmapent(); 24345916cd2Sjpk return (dmap); 24445916cd2Sjpk } 24545916cd2Sjpk freedmapent(dmap); 24645916cd2Sjpk } 24745916cd2Sjpk 24845916cd2Sjpk return (NULL); 24945916cd2Sjpk } 25045916cd2Sjpk 25145916cd2Sjpk /* 25245916cd2Sjpk * getdmaptype - 25345916cd2Sjpk * searches from the beginning of device_maps for the device specified by 25445916cd2Sjpk * its type. 25545916cd2Sjpk * call to getdmaptype should be bracketed by setdmapent and enddmapent. 25645916cd2Sjpk * returns pointer to devmap_t found, else returns NULL if no entry found 25745916cd2Sjpk * or on error. 25845916cd2Sjpk */ 25945916cd2Sjpk devmap_t * 26045916cd2Sjpk getdmaptype(char *type) 26145916cd2Sjpk { 26245916cd2Sjpk devmap_t *dmap; 26345916cd2Sjpk struct _dmapbuff *_dmap = _dmapalloc(); 26445916cd2Sjpk 26545916cd2Sjpk if ((type == NULL) || (_dmap == 0) || (dmapf == NULL)) 26645916cd2Sjpk return (NULL); 26745916cd2Sjpk 26845916cd2Sjpk while (getdadmline(interpdmline, (int)sizeof (interpdmline), 26945916cd2Sjpk dmapf) != 0) { 27045916cd2Sjpk if ((dmap = dmap_interpretf(interpdmline, 27145916cd2Sjpk &interpdevmap)) == NULL) 27245916cd2Sjpk continue; 27345916cd2Sjpk if (dmap->dmap_devtype != NULL && 27445916cd2Sjpk strcmp(type, dmap->dmap_devtype) == 0) { 27545916cd2Sjpk if ((dmap = dmap_dlexpand(dmap)) == NULL) 27645916cd2Sjpk continue; 27745916cd2Sjpk return (dmap); 27845916cd2Sjpk } 27945916cd2Sjpk freedmapent(dmap); 28045916cd2Sjpk } 28145916cd2Sjpk 28245916cd2Sjpk return (NULL); 28345916cd2Sjpk } 28445916cd2Sjpk 28545916cd2Sjpk /* 286*7e3e5701SJan Parcel * dmap_match_one_dev - 287*7e3e5701SJan Parcel * Checks if the specified devmap_t contains strings 288*7e3e5701SJan Parcel * for the same logical link as the device specified. 289*7e3e5701SJan Parcel * This guarantees that the beginnings of a devlist build 290*7e3e5701SJan Parcel * match a more-complete devlist for the same device. 291*7e3e5701SJan Parcel * 292*7e3e5701SJan Parcel * Returns 1 for a match, else returns 0. 293*7e3e5701SJan Parcel */ 294*7e3e5701SJan Parcel static int 295*7e3e5701SJan Parcel dmap_match_one_dev(devmap_t *dmap, char *dev) 296*7e3e5701SJan Parcel { 297*7e3e5701SJan Parcel char **dva; 298*7e3e5701SJan Parcel char *dv; 299*7e3e5701SJan Parcel 300*7e3e5701SJan Parcel if (dmap->dmap_devarray == NULL) 301*7e3e5701SJan Parcel return (0); 302*7e3e5701SJan Parcel 303*7e3e5701SJan Parcel for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva++) { 304*7e3e5701SJan Parcel if (strstr(dev, dv) != NULL) 305*7e3e5701SJan Parcel return (1); 306*7e3e5701SJan Parcel } 307*7e3e5701SJan Parcel return (0); 308*7e3e5701SJan Parcel } 309*7e3e5701SJan Parcel 310*7e3e5701SJan Parcel /* 31145916cd2Sjpk * dmap_matchdev - 31245916cd2Sjpk * checks if the specified devmap_t is for the device specified. 31345916cd2Sjpk * returns 1 if it is, else returns 0. 31445916cd2Sjpk */ 31545916cd2Sjpk int 31645916cd2Sjpk dmap_matchdev(devmap_t *dmap, char *dev) 31745916cd2Sjpk { 31845916cd2Sjpk char **dva; 31945916cd2Sjpk char *dv; 32045916cd2Sjpk 32145916cd2Sjpk if (dmap->dmap_devarray == NULL) 32245916cd2Sjpk return (0); 32345916cd2Sjpk for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva ++) { 32445916cd2Sjpk if (strcmp(dv, dev) == 0) 32545916cd2Sjpk return (1); 32645916cd2Sjpk } 32745916cd2Sjpk 32845916cd2Sjpk return (0); 32945916cd2Sjpk } 33045916cd2Sjpk 33145916cd2Sjpk /* 332*7e3e5701SJan Parcel * Requires a match of the /dev/?dsk links, not just the logical devname 333*7e3e5701SJan Parcel * Returns 1 for match found, 0 for match not found, 2 for invalid arguments. 334*7e3e5701SJan Parcel */ 335*7e3e5701SJan Parcel int 336*7e3e5701SJan Parcel dmap_exact_dev(devmap_t *dmap, char *dev, int *num) 337*7e3e5701SJan Parcel { 338*7e3e5701SJan Parcel char *dv; 339*7e3e5701SJan Parcel 340*7e3e5701SJan Parcel if ((dev == NULL) || (dmap->dmap_devname == NULL)) 341*7e3e5701SJan Parcel return (2); 342*7e3e5701SJan Parcel dv = dmap->dmap_devname; 343*7e3e5701SJan Parcel dv += strcspn(dmap->dmap_devname, "0123456789"); 344*7e3e5701SJan Parcel if (sscanf(dv, "%d", num) != 1) 345*7e3e5701SJan Parcel return (2); 346*7e3e5701SJan Parcel /* during some add processes, dev can be shorter than dmap */ 347*7e3e5701SJan Parcel return (dmap_match_one_dev(dmap, dev)); 348*7e3e5701SJan Parcel } 349*7e3e5701SJan Parcel 350*7e3e5701SJan Parcel /* 35145916cd2Sjpk * dmap_matchtype - 35245916cd2Sjpk * checks if the specified devmap_t is for the device specified. 35345916cd2Sjpk * returns 1 if it is, else returns 0. 35445916cd2Sjpk */ 35545916cd2Sjpk int 35645916cd2Sjpk dmap_matchtype(devmap_t *dmap, char *type) 35745916cd2Sjpk { 35845916cd2Sjpk if ((dmap->dmap_devtype == NULL) || (type == NULL)) 35945916cd2Sjpk return (0); 36045916cd2Sjpk 36145916cd2Sjpk return ((strcmp(dmap->dmap_devtype, type) == 0)); 36245916cd2Sjpk } 36345916cd2Sjpk 36445916cd2Sjpk /* 36545916cd2Sjpk * dmap_matchname - 36645916cd2Sjpk * checks if the specified devmap_t is for the device specified. 36745916cd2Sjpk * returns 1 if it is, else returns 0. 36845916cd2Sjpk */ 36945916cd2Sjpk int 37045916cd2Sjpk dmap_matchname(devmap_t *dmap, char *name) 37145916cd2Sjpk { 37245916cd2Sjpk if (dmap->dmap_devname == NULL) 37345916cd2Sjpk return (0); 37445916cd2Sjpk 37545916cd2Sjpk return ((strcmp(dmap->dmap_devname, name) == 0)); 37645916cd2Sjpk } 37745916cd2Sjpk 37845916cd2Sjpk /* 379*7e3e5701SJan Parcel * dmap_physname: path to /devices device 380*7e3e5701SJan Parcel * Returns: 381*7e3e5701SJan Parcel * strdup'd (i.e. malloc'd) real device file if successful 382*7e3e5701SJan Parcel * NULL on error 383*7e3e5701SJan Parcel */ 384*7e3e5701SJan Parcel char * 385*7e3e5701SJan Parcel dmap_physname(devmap_t *dmap) 386*7e3e5701SJan Parcel { 387*7e3e5701SJan Parcel char *oldlink; 388*7e3e5701SJan Parcel char stage_link[PATH_MAX + 1]; 389*7e3e5701SJan Parcel 390*7e3e5701SJan Parcel if ((dmap == NULL) || (dmap->dmap_devarray == NULL) || 391*7e3e5701SJan Parcel (dmap->dmap_devarray[0] == NULL)) 392*7e3e5701SJan Parcel return (NULL); 393*7e3e5701SJan Parcel 394*7e3e5701SJan Parcel (void) strncpy(stage_link, dmap->dmap_devarray[0], sizeof (stage_link)); 395*7e3e5701SJan Parcel 396*7e3e5701SJan Parcel if (devfs_resolve_link(stage_link, &oldlink) == 0) 397*7e3e5701SJan Parcel return (oldlink); 398*7e3e5701SJan Parcel return (NULL); 399*7e3e5701SJan Parcel } 400*7e3e5701SJan Parcel 401*7e3e5701SJan Parcel /* 40245916cd2Sjpk * dm_match - 40345916cd2Sjpk * calls dmap_matchname or dmap_matchtype as appropriate. 40445916cd2Sjpk */ 40545916cd2Sjpk int 40645916cd2Sjpk dm_match(devmap_t *dmap, da_args *dargs) 40745916cd2Sjpk { 40845916cd2Sjpk if (dargs->devinfo->devname) 40945916cd2Sjpk return (dmap_matchname(dmap, dargs->devinfo->devname)); 41045916cd2Sjpk else if (dargs->devinfo->devtype) 41145916cd2Sjpk return (dmap_matchtype(dmap, dargs->devinfo->devtype)); 41245916cd2Sjpk 41345916cd2Sjpk return (0); 41445916cd2Sjpk } 41545916cd2Sjpk 41645916cd2Sjpk /* 41745916cd2Sjpk * dmap_interpret - 41845916cd2Sjpk * calls dmap_interpretf and dmap_dlexpand to parse devmap_t line. 41945916cd2Sjpk * returns pointer to parsed devmapt_t entry, else returns NULL on error. 42045916cd2Sjpk */ 42145916cd2Sjpk devmap_t * 42245916cd2Sjpk dmap_interpret(char *val, devmap_t *dm) 42345916cd2Sjpk { 42445916cd2Sjpk if (dmap_interpretf(val, dm) == NULL) 42545916cd2Sjpk return (NULL); 42645916cd2Sjpk 42745916cd2Sjpk return (dmap_dlexpand(dm)); 42845916cd2Sjpk } 42945916cd2Sjpk 43045916cd2Sjpk /* 43145916cd2Sjpk * dmap_interpretf - 43245916cd2Sjpk * parses string "val" and initializes pointers in the given devmap_t to 43345916cd2Sjpk * fields in "val". 43445916cd2Sjpk * returns pointer to updated devmap_t. 43545916cd2Sjpk */ 43645916cd2Sjpk static devmap_t * 43745916cd2Sjpk dmap_interpretf(char *val, devmap_t *dm) 43845916cd2Sjpk { 43945916cd2Sjpk dm->dmap_devname = getdadmfield(val, KV_TOKEN_DELIMIT); 44045916cd2Sjpk dm->dmap_devtype = getdadmfield(NULL, KV_TOKEN_DELIMIT); 44145916cd2Sjpk dm->dmap_devlist = getdadmfield(NULL, KV_TOKEN_DELIMIT); 44245916cd2Sjpk dm->dmap_devarray = NULL; 44345916cd2Sjpk if (dm->dmap_devname == NULL || 44445916cd2Sjpk dm->dmap_devtype == NULL || 44545916cd2Sjpk dm->dmap_devlist == NULL) 44645916cd2Sjpk return (NULL); 44745916cd2Sjpk 44845916cd2Sjpk return (dm); 44945916cd2Sjpk } 45045916cd2Sjpk 45145916cd2Sjpk /* 45245916cd2Sjpk * dmap_dlexpand - 45345916cd2Sjpk * expands dmap_devlist of the form `devlist_generate` 45445916cd2Sjpk * returns unexpanded form if there is no '\`' or in case of error. 45545916cd2Sjpk */ 45645916cd2Sjpk static devmap_t * 45745916cd2Sjpk dmap_dlexpand(devmap_t *dmp) 45845916cd2Sjpk { 45945916cd2Sjpk char tmplist[DA_BUFSIZE + 1]; 46045916cd2Sjpk char *cp, *cpl, **darp; 46145916cd2Sjpk int count; 46245916cd2Sjpk FILE *expansion; 46345916cd2Sjpk 46445916cd2Sjpk dmp->dmap_devarray = NULL; 46545916cd2Sjpk if (dmp->dmap_devlist == NULL) 46645916cd2Sjpk return (NULL); 46745916cd2Sjpk if (*(dmp->dmap_devlist) != '`') { 46845916cd2Sjpk (void) strcpy(tmplist, dmp->dmap_devlist); 46945916cd2Sjpk } else { 47045916cd2Sjpk (void) strcpy(tmplist, dmp->dmap_devlist + 1); 47145916cd2Sjpk if ((cp = strchr(tmplist, '`')) != NULL) 47245916cd2Sjpk *cp = '\0'; 473004388ebScasper if ((expansion = popen(tmplist, "rF")) == NULL) 47445916cd2Sjpk return (NULL); 47545916cd2Sjpk count = fread(tmplist, 1, sizeof (tmplist) - 1, expansion); 47645916cd2Sjpk (void) pclose(expansion); 47745916cd2Sjpk tmplist[count] = '\0'; 47845916cd2Sjpk } 47945916cd2Sjpk 48045916cd2Sjpk /* cleanup the list */ 48145916cd2Sjpk count = pack_white(tmplist); 48245916cd2Sjpk dmp->dmap_devarray = darp = 48345916cd2Sjpk (char **)malloc((count + 2) * sizeof (char *)); 48445916cd2Sjpk if (darp == NULL) 48545916cd2Sjpk return (NULL); 48645916cd2Sjpk cp = tmplist; 48745916cd2Sjpk while ((cp = strtok_r(cp, " ", &cpl)) != NULL) { 48845916cd2Sjpk *darp = strdup(cp); 48945916cd2Sjpk if (*darp == NULL) { 49045916cd2Sjpk freedmapent(dmp); 49145916cd2Sjpk return (NULL); 49245916cd2Sjpk } 49345916cd2Sjpk darp++; 49445916cd2Sjpk cp = NULL; 49545916cd2Sjpk } 49645916cd2Sjpk *darp = NULL; 49745916cd2Sjpk 49845916cd2Sjpk return (dmp); 49945916cd2Sjpk } 50045916cd2Sjpk 50145916cd2Sjpk /* 50245916cd2Sjpk * dmapskip - 50345916cd2Sjpk * scans input string to find next colon or end of line. 50445916cd2Sjpk * returns pointer to next char. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate static char * 50745916cd2Sjpk dmapskip(char *p) 5087c478bd9Sstevel@tonic-gate { 5097c478bd9Sstevel@tonic-gate while (*p && *p != ':' && *p != '\n') 5107c478bd9Sstevel@tonic-gate ++p; 5117c478bd9Sstevel@tonic-gate if (*p == '\n') 5127c478bd9Sstevel@tonic-gate *p = '\0'; 5137c478bd9Sstevel@tonic-gate else if (*p != '\0') 5147c478bd9Sstevel@tonic-gate *p++ = '\0'; 51545916cd2Sjpk 5167c478bd9Sstevel@tonic-gate return (p); 5177c478bd9Sstevel@tonic-gate } 51845916cd2Sjpk 5197c478bd9Sstevel@tonic-gate /* 52045916cd2Sjpk * dmapdskip - 52145916cd2Sjpk * scans input string to find next space or end of line. 52245916cd2Sjpk * returns pointer to next char. 5237c478bd9Sstevel@tonic-gate */ 5247c478bd9Sstevel@tonic-gate static char * 52545916cd2Sjpk dmapdskip(p) 52645916cd2Sjpk register char *p; 5277c478bd9Sstevel@tonic-gate { 5287c478bd9Sstevel@tonic-gate while (*p && *p != ' ' && *p != '\n') 5297c478bd9Sstevel@tonic-gate ++p; 5307c478bd9Sstevel@tonic-gate if (*p != '\0') 5317c478bd9Sstevel@tonic-gate *p++ = '\0'; 53245916cd2Sjpk 5337c478bd9Sstevel@tonic-gate return (p); 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate 53645916cd2Sjpk char * 53745916cd2Sjpk getdmapfield(char *ptr) 5387c478bd9Sstevel@tonic-gate { 5397c478bd9Sstevel@tonic-gate static char *tptr; 54045916cd2Sjpk 5417c478bd9Sstevel@tonic-gate if (ptr == NULL) 5427c478bd9Sstevel@tonic-gate ptr = tptr; 5437c478bd9Sstevel@tonic-gate if (ptr == NULL) 5447c478bd9Sstevel@tonic-gate return (NULL); 5457c478bd9Sstevel@tonic-gate tptr = dmapskip(ptr); 5467c478bd9Sstevel@tonic-gate ptr = trim_white(ptr); 5477c478bd9Sstevel@tonic-gate if (ptr == NULL) 5487c478bd9Sstevel@tonic-gate return (NULL); 5497c478bd9Sstevel@tonic-gate if (*ptr == NULL) 5507c478bd9Sstevel@tonic-gate return (NULL); 55145916cd2Sjpk 5527c478bd9Sstevel@tonic-gate return (ptr); 5537c478bd9Sstevel@tonic-gate } 55445916cd2Sjpk 55545916cd2Sjpk char * 55645916cd2Sjpk getdmapdfield(char *ptr) 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate static char *tptr; 5597c478bd9Sstevel@tonic-gate if (ptr != NULL) { 5607c478bd9Sstevel@tonic-gate ptr = trim_white(ptr); 5617c478bd9Sstevel@tonic-gate } else { 5627c478bd9Sstevel@tonic-gate ptr = tptr; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate if (ptr == NULL) 5657c478bd9Sstevel@tonic-gate return (NULL); 5667c478bd9Sstevel@tonic-gate tptr = dmapdskip(ptr); 5677c478bd9Sstevel@tonic-gate if (ptr == NULL) 5687c478bd9Sstevel@tonic-gate return (NULL); 5697c478bd9Sstevel@tonic-gate if (*ptr == NULL) 5707c478bd9Sstevel@tonic-gate return (NULL); 57145916cd2Sjpk 5727c478bd9Sstevel@tonic-gate return (ptr); 5737c478bd9Sstevel@tonic-gate } 574