xref: /illumos-gate/usr/src/tools/protolist/protolist.c (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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  * Copyright (c) 1998 - 2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/mkdev.h>
35 #include <ftw.h>
36 #include <strings.h>
37 #include <stdlib.h>
38 
39 #define	MAX_DEPTH	50
40 
41 /*ARGSUSED2*/
42 static int
43 visit_dir(const char *path, const struct stat *st,
44 	int file_type, struct FTW *ft)
45 {
46 	char	*uid, *gid, ftype;
47 	char	symsrc[MAXPATHLEN];
48 	char	buffer[MAXPATHLEN];
49 	char	*abs_name;
50 	char	name[MAXPATHLEN];
51 	char	maj[10], min[10];
52 	char	*p;
53 	int	c;
54 	static int first_time = 1;
55 	int	inum;
56 
57 	/*
58 	 * The first directory is the current directory '.',
59 	 * this is relevent in out protolist - I throw it out.
60 	 */
61 	if (first_time) {
62 		first_time = 0;
63 		if ((path[0] == '.') && (path[1] == '\0'))
64 			return (0);
65 	}
66 
67 	abs_name = (char *)(path + 2);
68 	maj[0] = min[0] = symsrc[0] = '-';
69 	maj[1] = min[1] = symsrc[1] = '\0';
70 
71 	(void) strcpy(name, abs_name);
72 	/*
73 	 * is this a relocatable object?  if so set
74 	 * the symsrc appropriately.
75 	 *
76 	 * All relocatable objects start with /sun or /i86
77 	 *
78 	 * eg:
79 	 *    /sun4d/kadb == kadb
80 	 *    /i86pc/kadb == kadb
81 	 */
82 #if defined(sparc)
83 #define	ARCH_STR "sun"
84 #elif defined(i386)
85 #define	ARCH_STR "i86"
86 #elif defined(__ppc)
87 #define	ARCH_STR "prep"
88 #else
89 #error "Unknown instruction set"
90 #endif
91 	if (strncmp(abs_name, ARCH_STR, 3) == 0) {
92 		if (((st->st_mode & S_IFMT) == S_IFDIR) ||
93 		    ((st->st_mode & S_IFMT) == S_IFLNK))
94 			return (0);
95 
96 		(void) strcpy(buffer, abs_name);
97 		if (p = index(buffer, '/')) {
98 			(void) strcpy(symsrc, abs_name);
99 			*p++ = '\0';
100 			(void) strcpy(name, p);
101 		}
102 	}
103 
104 	switch (st->st_mode & S_IFMT) {
105 	case S_IFCHR:
106 		(void) sprintf(maj, "%ld", major(st->st_rdev));
107 		(void) sprintf(min, "%ld", minor(st->st_rdev));
108 		ftype = 'c';
109 		break;
110 	case S_IFDIR:
111 		ftype = 'd';
112 		break;
113 	case S_IFBLK:
114 		(void) sprintf(maj, "%ld", major(st->st_rdev));
115 		(void) sprintf(min, "%ld", minor(st->st_rdev));
116 		ftype = 'b';
117 		break;
118 	case S_IFREG:
119 		ftype = 'f';
120 		break;
121 	case S_IFLNK:
122 		if ((c = readlink(path, symsrc, MAXPATHLEN)) == -1)
123 			perror("readlink");
124 		symsrc[c] = '\0';
125 		ftype = 's';
126 		break;
127 	default:
128 		ftype = '?';
129 		break;
130 	}
131 
132 	switch (st->st_uid) {
133 	case 0:
134 		uid = "root";
135 		break;
136 	case 1:
137 		uid = "daemon";
138 		break;
139 	case 2:
140 		uid = "bin";
141 		break;
142 	case 3:
143 		uid = "sys";
144 		break;
145 	case 4:
146 		uid = "adm";
147 		break;
148 	case 5:
149 		uid = "uucp";
150 		break;
151 	case 9:
152 		uid = "nuucp";
153 		break;
154 	case 25:
155 		uid = "smmsp";
156 		break;
157 	case 37:
158 		uid = "listen";
159 		break;
160 	case 71:
161 		uid = "lp";
162 		break;
163 	case 60001:
164 	case 65534:
165 		uid = "nobody";
166 		break;
167 	case 60002:
168 		uid = "noaccess";
169 		break;
170 	default:
171 		uid = "NO_SUCH_UID";
172 		break;
173 	}
174 
175 	switch (st->st_gid) {
176 	case 0:
177 		gid = "root";
178 		break;
179 	case 1:
180 		gid = "other";
181 		break;
182 	case 2:
183 		gid = "bin";
184 		break;
185 	case 3:
186 		gid = "sys";
187 		break;
188 	case 4:
189 		gid = "adm";
190 		break;
191 	case 5:
192 		gid = "uucp";
193 		break;
194 	case 6:
195 		gid = "mail";
196 		break;
197 	case 7:
198 		gid = "tty";
199 		break;
200 	case 8:
201 		gid = "lp";
202 		break;
203 	case 9:
204 		gid = "nuucp";
205 		break;
206 	case 10:
207 		gid = "staff";
208 		break;
209 	case 12:
210 		gid = "daemon";
211 		break;
212 	case 25:
213 		gid = "smmsp";
214 		break;
215 	case 60001:
216 		gid = "nobody";
217 		break;
218 	case 60002:
219 		gid = "noaccess";
220 		break;
221 	case 65534:
222 		gid = "nogroup";
223 		break;
224 	default:
225 		gid = "NO_SUCH_GID";
226 		break;
227 	}
228 	if (st->st_nlink == 1)
229 		inum = 0;
230 	else
231 		inum = st->st_ino;
232 
233 	(void) printf("%c %-30s %-20s %4lo %-5s %-5s %6d %2ld %2s %2s\n",
234 		ftype, name, symsrc, st->st_mode % 010000, uid, gid,
235 		inum, st->st_nlink, maj, min);
236 	return (0);
237 }
238 
239 int
240 main(int argc, char *argv[])
241 {
242 
243 	if (argc != 2) {
244 		(void) fprintf(stderr, "usage: protolist <protodir>\n");
245 		exit(1);
246 	}
247 
248 	if (chdir(argv[1]) < 0) {
249 		perror("chdir");
250 		exit(1);
251 	}
252 
253 	if (nftw(".", visit_dir, MAX_DEPTH, FTW_PHYS) != 0) {
254 		perror("nftw");
255 		exit(1);
256 	}
257 
258 	return (0);
259 }
260