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