protolist.c revision 1384:525a0af43917
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*/
44static int
45visit_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 relevent 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
153int
154main(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