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 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 27 28 /* 29 * convert device to linename (as in /dev/linename) 30 * return ptr to LSZ-byte string, "?" if not found 31 * device must be character device 32 * maintains small list in tlist structure for speed 33 */ 34 35 #include <stdio.h> 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include "acctdef.h" 39 #include <dirent.h> 40 #include <string.h> 41 #include <sys/stat.h> 42 43 static tsize1; 44 static struct tlist { 45 char tname[LSZ]; /* linename */ 46 dev_t tdev; /* device */ 47 } tl[TSIZE1]; 48 49 char *strncpy(); 50 dev_t lintodev(); 51 52 static char dev_dir[] = "/dev"; 53 static char *def_srch_dirs[] = { "/dev/term", 54 "/dev/pts", 55 "/dev/xt", 56 NULL }; 57 char file_name[MAX_DEV_PATH]; /* name being returned */ 58 59 char * 60 devtolin(device) 61 dev_t device; 62 { 63 register struct tlist *tp; 64 char **srch_dirs; /* priority directories to search first */ 65 int found = 0; 66 int dirno = 0; 67 68 for (tp = tl; tp < &tl[tsize1]; tp++) 69 if (device == tp->tdev) 70 return(tp->tname); 71 72 srch_dirs = def_srch_dirs; 73 74 while ((!found) && (srch_dirs[dirno] != NULL)) { 75 /* if /dev is one of the priority directories we should only 76 search its top level for now (set depth = MAX_SEARCH_DEPTH) */ 77 78 found = srch_dir(device, srch_dirs[dirno], 79 ((strcmp(srch_dirs[dirno], dev_dir) == 0) ? 80 MAX_SRCH_DEPTH : 1), 81 NULL); 82 dirno++; 83 } 84 85 /* if not yet found search remaining /dev directory skipping the 86 priority directories */ 87 88 if (!found) 89 found = srch_dir(device, dev_dir, 0, srch_dirs); 90 91 /* if found then put it (without the "/dev/" prefix) in the tlist 92 structure and return the path name without the "/dev/" prefix */ 93 94 if (found) { 95 if (tsize1 < TSIZE1) { 96 tp->tdev = device; 97 CPYN(tp->tname, file_name+5); 98 tsize1++; 99 } 100 return(file_name+5); 101 } else 102 /* if not found put "?" in the tlist structure for that device and 103 return "?" */ 104 105 if (tsize1 < TSIZE1) { 106 tp->tdev = device; 107 CPYN(tp->tname, "?"); 108 tsize1++; 109 } 110 return("?"); 111 112 } 113 114 static int 115 srch_dir(device, path, depth, skip_dirs) 116 dev_t device; /* device we are looking for */ 117 char *path; /* current path */ 118 int depth; /* current depth */ 119 char *skip_dirs[]; /* directories that don't need searched */ 120 { 121 DIR *fdev; 122 struct dirent *d; 123 int dirno = 0; 124 int found = 0; 125 int path_len; 126 char *last_comp; 127 struct stat sb; 128 129 /* do we need to search this directory? */ 130 131 if ((skip_dirs != NULL) && (depth != 0)) 132 while (skip_dirs[dirno] != NULL) 133 if (strcmp(skip_dirs[dirno++], path) == 0) 134 return(0); 135 136 137 /* open the directory */ 138 139 if ((fdev = opendir(path)) == NULL) 140 return(0); 141 142 /* initialize file name using path name */ 143 144 path_len = strlen(path); 145 strcpy(file_name, path); 146 last_comp = file_name + path_len; 147 *last_comp++ = '/'; 148 149 /* start searching this directory */ 150 151 while ((!found) && ((d = readdir(fdev)) != NULL)) 152 if (d->d_ino != 0) { 153 154 /* if name would not be too long append it to 155 directory name, otherwise skip this entry */ 156 157 if ((int) (path_len + strlen(d->d_name) + 2) > MAX_DEV_PATH) 158 continue; 159 else 160 strcpy(last_comp, d->d_name); 161 162 /* if this directory entry has the device number we need, 163 then the name is found. Otherwise if it's a directory 164 (not . or ..) and we haven't gone too deep, recurse. */ 165 166 if (lintodev(file_name+5) == device) { 167 found = 1; 168 break; 169 } else if ((depth < MAX_SRCH_DEPTH) && 170 (strcmp(d->d_name, ".") != 0) && 171 (strcmp(d->d_name, "..") != 0) && 172 (stat(file_name, &sb) != -1) && 173 ((sb.st_mode & S_IFMT) == S_IFDIR)) 174 found = srch_dir(device, file_name, depth+1, skip_dirs); 175 } 176 closedir(fdev); 177 return(found); 178 } 179