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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdio.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/mkdev.h>
33 #include <ftw.h>
34 #include <strings.h>
35 #include <stdlib.h>
36 #include "stdusers.h"
37
38 #define MAX_DEPTH 50
39
40 /*ARGSUSED2*/
41 static int
visit_dir(const char * path,const struct stat * st,int file_type,struct FTW * ft)42 visit_dir(const char *path, const struct stat *st,
43 int file_type, struct FTW *ft)
44 {
45 const char *uid, *gid;
46 char 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 relevant in our protolist, so 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 uid = stdfindbyvalue(st->st_uid, usernames);
133 if (uid == NULL)
134 uid = "NO_SUCH_UID";
135
136 gid = stdfindbyvalue(st->st_gid, groupnames);
137 if (gid == NULL)
138 gid = "NO_SUCH_GID";
139 if (st->st_nlink == 1)
140 inum = 0;
141 else
142 inum = st->st_ino;
143
144 (void) printf("%c %-30s %-20s %4lo %-5s %-5s %6d %2ld %2s %2s\n",
145 ftype, name, symsrc, st->st_mode % 010000, uid, gid,
146 inum, st->st_nlink, maj, min);
147 return (0);
148 }
149
150 int
main(int argc,char * argv[])151 main(int argc, char *argv[])
152 {
153
154 if (argc != 2) {
155 (void) fprintf(stderr, "usage: protolist <protodir>\n");
156 exit(1);
157 }
158
159 if (chdir(argv[1]) < 0) {
160 perror("chdir");
161 exit(1);
162 }
163
164 if (nftw(".", visit_dir, MAX_DEPTH, FTW_PHYS) != 0) {
165 perror("nftw");
166 exit(1);
167 }
168
169 return (0);
170 }
171