1*facf4a8dSllai1 /* 2*facf4a8dSllai1 * CDDL HEADER START 3*facf4a8dSllai1 * 4*facf4a8dSllai1 * The contents of this file are subject to the terms of the 5*facf4a8dSllai1 * Common Development and Distribution License (the "License"). 6*facf4a8dSllai1 * You may not use this file except in compliance with the License. 7*facf4a8dSllai1 * 8*facf4a8dSllai1 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*facf4a8dSllai1 * or http://www.opensolaris.org/os/licensing. 10*facf4a8dSllai1 * See the License for the specific language governing permissions 11*facf4a8dSllai1 * and limitations under the License. 12*facf4a8dSllai1 * 13*facf4a8dSllai1 * When distributing Covered Code, include this CDDL HEADER in each 14*facf4a8dSllai1 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*facf4a8dSllai1 * If applicable, add the following below this CDDL HEADER, with the 16*facf4a8dSllai1 * fields enclosed by brackets "[]" replaced with your own identifying 17*facf4a8dSllai1 * information: Portions Copyright [yyyy] [name of copyright owner] 18*facf4a8dSllai1 * 19*facf4a8dSllai1 * CDDL HEADER END 20*facf4a8dSllai1 */ 21*facf4a8dSllai1 /* 22*facf4a8dSllai1 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*facf4a8dSllai1 * Use is subject to license terms. 24*facf4a8dSllai1 */ 25*facf4a8dSllai1 26*facf4a8dSllai1 #pragma ident "%Z%%M% %I% %E% SMI" 27*facf4a8dSllai1 28*facf4a8dSllai1 #include <stdio.h> 29*facf4a8dSllai1 #include <unistd.h> 30*facf4a8dSllai1 #include <fcntl.h> 31*facf4a8dSllai1 #include <string.h> 32*facf4a8dSllai1 #include <thread.h> 33*facf4a8dSllai1 #include <synch.h> 34*facf4a8dSllai1 #include <limits.h> 35*facf4a8dSllai1 #include <stdlib.h> 36*facf4a8dSllai1 #include <string.h> 37*facf4a8dSllai1 #include <strings.h> 38*facf4a8dSllai1 #include <dirent.h> 39*facf4a8dSllai1 #include <regex.h> 40*facf4a8dSllai1 #include <errno.h> 41*facf4a8dSllai1 #include <stdarg.h> 42*facf4a8dSllai1 #include <libdevinfo.h> 43*facf4a8dSllai1 #include <sys/modctl.h> 44*facf4a8dSllai1 #include <syslog.h> 45*facf4a8dSllai1 46*facf4a8dSllai1 #include <assert.h> 47*facf4a8dSllai1 48*facf4a8dSllai1 49*facf4a8dSllai1 struct finddevhdl { 50*facf4a8dSllai1 int npaths; 51*facf4a8dSllai1 int curpath; 52*facf4a8dSllai1 char **paths; 53*facf4a8dSllai1 }; 54*facf4a8dSllai1 55*facf4a8dSllai1 56*facf4a8dSllai1 int 57*facf4a8dSllai1 device_exists(const char *devname) 58*facf4a8dSllai1 { 59*facf4a8dSllai1 int rv; 60*facf4a8dSllai1 61*facf4a8dSllai1 rv = modctl(MODDEVEXISTS, devname, strlen(devname)); 62*facf4a8dSllai1 return ((rv == 0) ? 1 : 0); 63*facf4a8dSllai1 } 64*facf4a8dSllai1 65*facf4a8dSllai1 int 66*facf4a8dSllai1 finddev_readdir(const char *dir, finddevhdl_t *handlep) 67*facf4a8dSllai1 { 68*facf4a8dSllai1 struct finddevhdl *handle; 69*facf4a8dSllai1 int n; 70*facf4a8dSllai1 int rv; 71*facf4a8dSllai1 int64_t bufsiz; 72*facf4a8dSllai1 char *pathlist; 73*facf4a8dSllai1 char *p; 74*facf4a8dSllai1 int len; 75*facf4a8dSllai1 76*facf4a8dSllai1 *handlep = NULL; 77*facf4a8dSllai1 handle = calloc(1, sizeof (struct finddevhdl)); 78*facf4a8dSllai1 if (handle == NULL) 79*facf4a8dSllai1 return (ENOMEM); 80*facf4a8dSllai1 81*facf4a8dSllai1 handle->npaths = 0; 82*facf4a8dSllai1 handle->curpath = 0; 83*facf4a8dSllai1 handle->paths = NULL; 84*facf4a8dSllai1 85*facf4a8dSllai1 rv = modctl(MODDEVREADDIR, dir, strlen(dir), NULL, &bufsiz); 86*facf4a8dSllai1 if (rv != 0) { 87*facf4a8dSllai1 free(handle); 88*facf4a8dSllai1 return (rv); 89*facf4a8dSllai1 } 90*facf4a8dSllai1 91*facf4a8dSllai1 for (;;) { 92*facf4a8dSllai1 assert(bufsiz != 0); 93*facf4a8dSllai1 if ((pathlist = malloc(bufsiz)) == NULL) { 94*facf4a8dSllai1 free(handle); 95*facf4a8dSllai1 return (ENOMEM); 96*facf4a8dSllai1 } 97*facf4a8dSllai1 98*facf4a8dSllai1 rv = modctl(MODDEVREADDIR, dir, strlen(dir), 99*facf4a8dSllai1 pathlist, &bufsiz); 100*facf4a8dSllai1 if (rv == 0) { 101*facf4a8dSllai1 for (n = 0, p = pathlist; 102*facf4a8dSllai1 (len = strlen(p)) > 0; p += len+1) { 103*facf4a8dSllai1 n++; 104*facf4a8dSllai1 } 105*facf4a8dSllai1 handle->npaths = n; 106*facf4a8dSllai1 handle->paths = calloc(n, sizeof (char *)); 107*facf4a8dSllai1 if (handle->paths == NULL) { 108*facf4a8dSllai1 free(handle); 109*facf4a8dSllai1 free(pathlist); 110*facf4a8dSllai1 return (ENOMEM); 111*facf4a8dSllai1 } 112*facf4a8dSllai1 for (n = 0, p = pathlist; 113*facf4a8dSllai1 (len = strlen(p)) > 0; p += len+1, n++) { 114*facf4a8dSllai1 handle->paths[n] = strdup(p); 115*facf4a8dSllai1 if (handle->paths[n] == NULL) { 116*facf4a8dSllai1 finddev_close((finddevhdl_t)handle); 117*facf4a8dSllai1 free(pathlist); 118*facf4a8dSllai1 return (ENOMEM); 119*facf4a8dSllai1 } 120*facf4a8dSllai1 } 121*facf4a8dSllai1 *handlep = (finddevhdl_t)handle; 122*facf4a8dSllai1 free(pathlist); 123*facf4a8dSllai1 return (0); 124*facf4a8dSllai1 } 125*facf4a8dSllai1 free(pathlist); 126*facf4a8dSllai1 switch (errno) { 127*facf4a8dSllai1 case EAGAIN: 128*facf4a8dSllai1 break; 129*facf4a8dSllai1 case ENOENT: 130*facf4a8dSllai1 default: 131*facf4a8dSllai1 free(handle); 132*facf4a8dSllai1 return (errno); 133*facf4a8dSllai1 } 134*facf4a8dSllai1 } 135*facf4a8dSllai1 /*NOTREACHED*/ 136*facf4a8dSllai1 } 137*facf4a8dSllai1 138*facf4a8dSllai1 void 139*facf4a8dSllai1 finddev_close(finddevhdl_t arg) 140*facf4a8dSllai1 { 141*facf4a8dSllai1 struct finddevhdl *handle = (struct finddevhdl *)arg; 142*facf4a8dSllai1 int i; 143*facf4a8dSllai1 144*facf4a8dSllai1 for (i = 0; i < handle->npaths; i++) { 145*facf4a8dSllai1 if (handle->paths[i]) 146*facf4a8dSllai1 free(handle->paths[i]); 147*facf4a8dSllai1 } 148*facf4a8dSllai1 free(handle->paths); 149*facf4a8dSllai1 free(handle); 150*facf4a8dSllai1 } 151*facf4a8dSllai1 152*facf4a8dSllai1 const char * 153*facf4a8dSllai1 finddev_next(finddevhdl_t arg) 154*facf4a8dSllai1 { 155*facf4a8dSllai1 struct finddevhdl *handle = (struct finddevhdl *)arg; 156*facf4a8dSllai1 const char *path = NULL; 157*facf4a8dSllai1 158*facf4a8dSllai1 if (handle->curpath < handle->npaths) { 159*facf4a8dSllai1 path = handle->paths[handle->curpath]; 160*facf4a8dSllai1 handle->curpath++; 161*facf4a8dSllai1 } 162*facf4a8dSllai1 return (path); 163*facf4a8dSllai1 } 164