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