17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 25*414388d7Ssl108498 /* 26*414388d7Ssl108498 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 27*414388d7Ssl108498 * Use is subject to license terms. 28*414388d7Ssl108498 */ 29*414388d7Ssl108498 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* 327c478bd9Sstevel@tonic-gate * convert device to linename (as in /dev/linename) 337c478bd9Sstevel@tonic-gate * return ptr to LSZ-byte string, "?" if not found 347c478bd9Sstevel@tonic-gate * device must be character device 357c478bd9Sstevel@tonic-gate * maintains small list in tlist structure for speed 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <stdio.h> 397c478bd9Sstevel@tonic-gate #include <sys/types.h> 407c478bd9Sstevel@tonic-gate #include <sys/param.h> 417c478bd9Sstevel@tonic-gate #include "acctdef.h" 427c478bd9Sstevel@tonic-gate #include <dirent.h> 437c478bd9Sstevel@tonic-gate #include <string.h> 447c478bd9Sstevel@tonic-gate #include <sys/stat.h> 457c478bd9Sstevel@tonic-gate 46*414388d7Ssl108498 static int tsize1; 477c478bd9Sstevel@tonic-gate static struct tlist { 487c478bd9Sstevel@tonic-gate char tname[LSZ]; /* linename */ 497c478bd9Sstevel@tonic-gate dev_t tdev; /* device */ 507c478bd9Sstevel@tonic-gate } tl[TSIZE1]; 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate char *strncpy(); 537c478bd9Sstevel@tonic-gate dev_t lintodev(); 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate static char dev_dir[] = "/dev"; 567c478bd9Sstevel@tonic-gate static char *def_srch_dirs[] = { "/dev/term", 577c478bd9Sstevel@tonic-gate "/dev/pts", 587c478bd9Sstevel@tonic-gate "/dev/xt", 597c478bd9Sstevel@tonic-gate NULL }; 607c478bd9Sstevel@tonic-gate char file_name[MAX_DEV_PATH]; /* name being returned */ 617c478bd9Sstevel@tonic-gate 62*414388d7Ssl108498 static int srch_dir(); 63*414388d7Ssl108498 647c478bd9Sstevel@tonic-gate char * 657c478bd9Sstevel@tonic-gate devtolin(device) 667c478bd9Sstevel@tonic-gate dev_t device; 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate register struct tlist *tp; 697c478bd9Sstevel@tonic-gate char **srch_dirs; /* priority directories to search first */ 707c478bd9Sstevel@tonic-gate int found = 0; 717c478bd9Sstevel@tonic-gate int dirno = 0; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate for (tp = tl; tp < &tl[tsize1]; tp++) 747c478bd9Sstevel@tonic-gate if (device == tp->tdev) 757c478bd9Sstevel@tonic-gate return(tp->tname); 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate srch_dirs = def_srch_dirs; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate while ((!found) && (srch_dirs[dirno] != NULL)) { 807c478bd9Sstevel@tonic-gate /* if /dev is one of the priority directories we should only 817c478bd9Sstevel@tonic-gate search its top level for now (set depth = MAX_SEARCH_DEPTH) */ 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate found = srch_dir(device, srch_dirs[dirno], 847c478bd9Sstevel@tonic-gate ((strcmp(srch_dirs[dirno], dev_dir) == 0) ? 857c478bd9Sstevel@tonic-gate MAX_SRCH_DEPTH : 1), 867c478bd9Sstevel@tonic-gate NULL); 877c478bd9Sstevel@tonic-gate dirno++; 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* if not yet found search remaining /dev directory skipping the 917c478bd9Sstevel@tonic-gate priority directories */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate if (!found) 947c478bd9Sstevel@tonic-gate found = srch_dir(device, dev_dir, 0, srch_dirs); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* if found then put it (without the "/dev/" prefix) in the tlist 977c478bd9Sstevel@tonic-gate structure and return the path name without the "/dev/" prefix */ 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate if (found) { 1007c478bd9Sstevel@tonic-gate if (tsize1 < TSIZE1) { 1017c478bd9Sstevel@tonic-gate tp->tdev = device; 1027c478bd9Sstevel@tonic-gate CPYN(tp->tname, file_name+5); 1037c478bd9Sstevel@tonic-gate tsize1++; 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate return(file_name+5); 1067c478bd9Sstevel@tonic-gate } else 1077c478bd9Sstevel@tonic-gate /* if not found put "?" in the tlist structure for that device and 1087c478bd9Sstevel@tonic-gate return "?" */ 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate if (tsize1 < TSIZE1) { 1117c478bd9Sstevel@tonic-gate tp->tdev = device; 1127c478bd9Sstevel@tonic-gate CPYN(tp->tname, "?"); 1137c478bd9Sstevel@tonic-gate tsize1++; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate return("?"); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate static int 1207c478bd9Sstevel@tonic-gate srch_dir(device, path, depth, skip_dirs) 1217c478bd9Sstevel@tonic-gate dev_t device; /* device we are looking for */ 1227c478bd9Sstevel@tonic-gate char *path; /* current path */ 1237c478bd9Sstevel@tonic-gate int depth; /* current depth */ 1247c478bd9Sstevel@tonic-gate char *skip_dirs[]; /* directories that don't need searched */ 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate DIR *fdev; 1277c478bd9Sstevel@tonic-gate struct dirent *d; 1287c478bd9Sstevel@tonic-gate int dirno = 0; 1297c478bd9Sstevel@tonic-gate int found = 0; 1307c478bd9Sstevel@tonic-gate int path_len; 1317c478bd9Sstevel@tonic-gate char *last_comp; 1327c478bd9Sstevel@tonic-gate struct stat sb; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* do we need to search this directory? */ 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate if ((skip_dirs != NULL) && (depth != 0)) 1377c478bd9Sstevel@tonic-gate while (skip_dirs[dirno] != NULL) 1387c478bd9Sstevel@tonic-gate if (strcmp(skip_dirs[dirno++], path) == 0) 1397c478bd9Sstevel@tonic-gate return(0); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate /* open the directory */ 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if ((fdev = opendir(path)) == NULL) 1457c478bd9Sstevel@tonic-gate return(0); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate /* initialize file name using path name */ 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate path_len = strlen(path); 1507c478bd9Sstevel@tonic-gate strcpy(file_name, path); 1517c478bd9Sstevel@tonic-gate last_comp = file_name + path_len; 1527c478bd9Sstevel@tonic-gate *last_comp++ = '/'; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* start searching this directory */ 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate while ((!found) && ((d = readdir(fdev)) != NULL)) 1577c478bd9Sstevel@tonic-gate if (d->d_ino != 0) { 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate /* if name would not be too long append it to 1607c478bd9Sstevel@tonic-gate directory name, otherwise skip this entry */ 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate if ((int) (path_len + strlen(d->d_name) + 2) > MAX_DEV_PATH) 1637c478bd9Sstevel@tonic-gate continue; 1647c478bd9Sstevel@tonic-gate else 1657c478bd9Sstevel@tonic-gate strcpy(last_comp, d->d_name); 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* if this directory entry has the device number we need, 1687c478bd9Sstevel@tonic-gate then the name is found. Otherwise if it's a directory 1697c478bd9Sstevel@tonic-gate (not . or ..) and we haven't gone too deep, recurse. */ 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate if (lintodev(file_name+5) == device) { 1727c478bd9Sstevel@tonic-gate found = 1; 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate } else if ((depth < MAX_SRCH_DEPTH) && 1757c478bd9Sstevel@tonic-gate (strcmp(d->d_name, ".") != 0) && 1767c478bd9Sstevel@tonic-gate (strcmp(d->d_name, "..") != 0) && 1777c478bd9Sstevel@tonic-gate (stat(file_name, &sb) != -1) && 1787c478bd9Sstevel@tonic-gate ((sb.st_mode & S_IFMT) == S_IFDIR)) 1797c478bd9Sstevel@tonic-gate found = srch_dir(device, file_name, depth+1, skip_dirs); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate closedir(fdev); 1827c478bd9Sstevel@tonic-gate return(found); 1837c478bd9Sstevel@tonic-gate } 184