xref: /illumos-gate/usr/src/tools/protolist/protolist.c (revision a38ddfee9c8c6b6c5a2947ff52fd2338362a4444)
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