Home | History | Annotate | Download | only in protolist
      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