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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 /* 26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 30 31 /* 32 * convert device to linename (as in /dev/linename) 33 * return ptr to LSZ-byte string, "?" if not found 34 * device must be character device 35 * maintains small list in tlist structure for speed 36 */ 37 38 #include <stdio.h> 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include "acctdef.h" 42 #include <dirent.h> 43 #include <string.h> 44 #include <sys/stat.h> 45 46 static int tsize1; 47 static struct tlist { 48 char tname[LSZ]; /* linename */ 49 dev_t tdev; /* device */ 50 } tl[TSIZE1]; 51 52 char *strncpy(); 53 dev_t lintodev(); 54 55 static char dev_dir[] = "/dev"; 56 static char *def_srch_dirs[] = { "/dev/term", 57 "/dev/pts", 58 "/dev/xt", 59 NULL }; 60 char file_name[MAX_DEV_PATH]; /* name being returned */ 61 62 static int srch_dir(); 63 64 char * 65 devtolin(device) 66 dev_t device; 67 { 68 register struct tlist *tp; 69 char **srch_dirs; /* priority directories to search first */ 70 int found = 0; 71 int dirno = 0; 72 73 for (tp = tl; tp < &tl[tsize1]; tp++) 74 if (device == tp->tdev) 75 return(tp->tname); 76 77 srch_dirs = def_srch_dirs; 78 79 while ((!found) && (srch_dirs[dirno] != NULL)) { 80 /* if /dev is one of the priority directories we should only 81 search its top level for now (set depth = MAX_SEARCH_DEPTH) */ 82 83 found = srch_dir(device, srch_dirs[dirno], 84 ((strcmp(srch_dirs[dirno], dev_dir) == 0) ? 85 MAX_SRCH_DEPTH : 1), 86 NULL); 87 dirno++; 88 } 89 90 /* if not yet found search remaining /dev directory skipping the 91 priority directories */ 92 93 if (!found) 94 found = srch_dir(device, dev_dir, 0, srch_dirs); 95 96 /* if found then put it (without the "/dev/" prefix) in the tlist 97 structure and return the path name without the "/dev/" prefix */ 98 99 if (found) { 100 if (tsize1 < TSIZE1) { 101 tp->tdev = device; 102 CPYN(tp->tname, file_name+5); 103 tsize1++; 104 } 105 return(file_name+5); 106 } else 107 /* if not found put "?" in the tlist structure for that device and 108 return "?" */ 109 110 if (tsize1 < TSIZE1) { 111 tp->tdev = device; 112 CPYN(tp->tname, "?"); 113 tsize1++; 114 } 115 return("?"); 116 117 } 118 119 static int 120 srch_dir(device, path, depth, skip_dirs) 121 dev_t device; /* device we are looking for */ 122 char *path; /* current path */ 123 int depth; /* current depth */ 124 char *skip_dirs[]; /* directories that don't need searched */ 125 { 126 DIR *fdev; 127 struct dirent *d; 128 int dirno = 0; 129 int found = 0; 130 int path_len; 131 char *last_comp; 132 struct stat sb; 133 134 /* do we need to search this directory? */ 135 136 if ((skip_dirs != NULL) && (depth != 0)) 137 while (skip_dirs[dirno] != NULL) 138 if (strcmp(skip_dirs[dirno++], path) == 0) 139 return(0); 140 141 142 /* open the directory */ 143 144 if ((fdev = opendir(path)) == NULL) 145 return(0); 146 147 /* initialize file name using path name */ 148 149 path_len = strlen(path); 150 strcpy(file_name, path); 151 last_comp = file_name + path_len; 152 *last_comp++ = '/'; 153 154 /* start searching this directory */ 155 156 while ((!found) && ((d = readdir(fdev)) != NULL)) 157 if (d->d_ino != 0) { 158 159 /* if name would not be too long append it to 160 directory name, otherwise skip this entry */ 161 162 if ((int) (path_len + strlen(d->d_name) + 2) > MAX_DEV_PATH) 163 continue; 164 else 165 strcpy(last_comp, d->d_name); 166 167 /* if this directory entry has the device number we need, 168 then the name is found. Otherwise if it's a directory 169 (not . or ..) and we haven't gone too deep, recurse. */ 170 171 if (lintodev(file_name+5) == device) { 172 found = 1; 173 break; 174 } else if ((depth < MAX_SRCH_DEPTH) && 175 (strcmp(d->d_name, ".") != 0) && 176 (strcmp(d->d_name, "..") != 0) && 177 (stat(file_name, &sb) != -1) && 178 ((sb.st_mode & S_IFMT) == S_IFDIR)) 179 found = srch_dir(device, file_name, depth+1, skip_dirs); 180 } 181 closedir(fdev); 182 return(found); 183 } 184