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 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> 31 #include <sys/stat.h> 32 #include <unistd.h> 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/mkdev.h> 36 #include <ftw.h> 37 #include <strings.h> 38 #include <stdlib.h> 39 #include "stdusers.h" 40 41 #define MAX_DEPTH 50 42 43 /*ARGSUSED2*/ 44 static int 45 visit_dir(const char *path, const struct stat *st, 46 int file_type, struct FTW *ft) 47 { 48 const char *uid, *gid; 49 char ftype; 50 char symsrc[MAXPATHLEN]; 51 char buffer[MAXPATHLEN]; 52 char *abs_name; 53 char name[MAXPATHLEN]; 54 char maj[10], min[10]; 55 char *p; 56 int c; 57 static int first_time = 1; 58 int inum; 59 60 /* 61 * The first directory is the current directory '.', 62 * this is relevant in out protolist - I throw it out. 63 */ 64 if (first_time) { 65 first_time = 0; 66 if ((path[0] == '.') && (path[1] == '\0')) 67 return (0); 68 } 69 70 abs_name = (char *)(path + 2); 71 maj[0] = min[0] = symsrc[0] = '-'; 72 maj[1] = min[1] = symsrc[1] = '\0'; 73 74 (void) strcpy(name, abs_name); 75 /* 76 * is this a relocatable object? if so set 77 * the symsrc appropriately. 78 * 79 * All relocatable objects start with /sun or /i86 80 * 81 * eg: 82 * /sun4d/kadb == kadb 83 * /i86pc/kadb == kadb 84 */ 85 #if defined(sparc) 86 #define ARCH_STR "sun" 87 #elif defined(i386) 88 #define ARCH_STR "i86" 89 #elif defined(__ppc) 90 #define ARCH_STR "prep" 91 #else 92 #error "Unknown instruction set" 93 #endif 94 if (strncmp(abs_name, ARCH_STR, 3) == 0) { 95 if (((st->st_mode & S_IFMT) == S_IFDIR) || 96 ((st->st_mode & S_IFMT) == S_IFLNK)) 97 return (0); 98 99 (void) strcpy(buffer, abs_name); 100 if (p = index(buffer, '/')) { 101 (void) strcpy(symsrc, abs_name); 102 *p++ = '\0'; 103 (void) strcpy(name, p); 104 } 105 } 106 107 switch (st->st_mode & S_IFMT) { 108 case S_IFCHR: 109 (void) sprintf(maj, "%ld", major(st->st_rdev)); 110 (void) sprintf(min, "%ld", minor(st->st_rdev)); 111 ftype = 'c'; 112 break; 113 case S_IFDIR: 114 ftype = 'd'; 115 break; 116 case S_IFBLK: 117 (void) sprintf(maj, "%ld", major(st->st_rdev)); 118 (void) sprintf(min, "%ld", minor(st->st_rdev)); 119 ftype = 'b'; 120 break; 121 case S_IFREG: 122 ftype = 'f'; 123 break; 124 case S_IFLNK: 125 if ((c = readlink(path, symsrc, MAXPATHLEN)) == -1) 126 perror("readlink"); 127 symsrc[c] = '\0'; 128 ftype = 's'; 129 break; 130 default: 131 ftype = '?'; 132 break; 133 } 134 135 uid = stdfindbyvalue(st->st_uid, usernames); 136 if (uid == NULL) 137 uid = "NO_SUCH_UID"; 138 139 gid = stdfindbyvalue(st->st_gid, groupnames); 140 if (gid == NULL) 141 gid = "NO_SUCH_GID"; 142 if (st->st_nlink == 1) 143 inum = 0; 144 else 145 inum = st->st_ino; 146 147 (void) printf("%c %-30s %-20s %4lo %-5s %-5s %6d %2ld %2s %2s\n", 148 ftype, name, symsrc, st->st_mode % 010000, uid, gid, 149 inum, st->st_nlink, maj, min); 150 return (0); 151 } 152 153 int 154 main(int argc, char *argv[]) 155 { 156 157 if (argc != 2) { 158 (void) fprintf(stderr, "usage: protolist <protodir>\n"); 159 exit(1); 160 } 161 162 if (chdir(argv[1]) < 0) { 163 perror("chdir"); 164 exit(1); 165 } 166 167 if (nftw(".", visit_dir, MAX_DEPTH, FTW_PHYS) != 0) { 168 perror("nftw"); 169 exit(1); 170 } 171 172 return (0); 173 } 174