Home | History | Annotate | Download | only in prtconf
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  8638  Vikram  * Common Development and Distribution License (the "License").
      6  8638  Vikram  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21     0  stevel /*
     22  8638  Vikram  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23     0  stevel  * Use is subject to license terms.
     24     0  stevel  */
     25     0  stevel 
     26     0  stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     27     0  stevel /*	  All Rights Reserved	*/
     28     0  stevel 
     29     0  stevel 
     30     0  stevel #include <stdio.h>
     31     0  stevel #include <stdarg.h>
     32     0  stevel #include <stdlib.h>
     33     0  stevel #include <unistd.h>
     34     0  stevel #include <strings.h>
     35     0  stevel #include <sys/systeminfo.h>
     36     0  stevel #include <sys/types.h>
     37     0  stevel #include <sys/stat.h>
     38     0  stevel #include "prtconf.h"
     39     0  stevel 
     40     0  stevel struct prt_opts	opts;
     41     0  stevel struct prt_dbg	dbg;
     42     0  stevel static char	new_path[MAXPATHLEN];
     43     0  stevel 
     44     0  stevel #define	INDENT_LENGTH	4
     45     0  stevel 
     46     0  stevel #ifdef	__x86
     47  9074    Judy static const char *usage = "%s [ -V | -x | -abcdvpPD ] [ <device_path > ]\n";
     48     0  stevel #else
     49  9074    Judy static const char *usage =
     50  9074    Judy 	"%s [ -F | -V | -x | -abcdvpPD ][ <device_path > ]\n";
     51     0  stevel #endif	/* __x86 */
     52     0  stevel 
     53     0  stevel static void
     54     0  stevel setprogname(const char *name)
     55     0  stevel {
     56     0  stevel 	char *p;
     57     0  stevel 
     58     0  stevel 	if (name == NULL)
     59     0  stevel 		opts.o_progname = "prtconf";
     60     0  stevel 	else if (p = strrchr(name, '/'))
     61     0  stevel 		opts.o_progname = (const char *) p + 1;
     62     0  stevel 	else
     63     0  stevel 		opts.o_progname = name;
     64     0  stevel }
     65     0  stevel 
     66     0  stevel /*PRINTFLIKE1*/
     67     0  stevel void
     68     0  stevel dprintf(const char *fmt, ...)
     69     0  stevel {
     70     0  stevel 	if (dbg.d_debug) {
     71     0  stevel 		va_list ap;
     72     0  stevel 		va_start(ap, fmt);
     73     0  stevel 		(void) vfprintf(stderr, fmt, ap);
     74     0  stevel 		va_end(ap);
     75     0  stevel 	}
     76     0  stevel }
     77     0  stevel 
     78     0  stevel void
     79     0  stevel indent_to_level(int ilev)
     80     0  stevel {
     81     0  stevel 	(void) printf("%*s", INDENT_LENGTH * ilev, "");
     82     0  stevel }
     83     0  stevel 
     84     0  stevel static void
     85     0  stevel cleanup_path(const char *input_path, char *path)
     86     0  stevel {
     87     0  stevel 	char	*ptr, *ptr2;
     88     0  stevel 	size_t	len;
     89     0  stevel 
     90     0  stevel 	if ((input_path == NULL) || (path == NULL))
     91     0  stevel 		return;
     92     0  stevel 
     93     0  stevel 	(void) strcpy(path, input_path);
     94     0  stevel 
     95     0  stevel 	/*LINTED*/
     96     0  stevel 	while (1) {
     97     0  stevel 		len = strlen(path);
     98     0  stevel 		if (len == 0)
     99     0  stevel 			break;
    100     0  stevel 
    101     0  stevel 		/* change substring "//" into "/" */
    102     0  stevel 		if (ptr = strstr(path, "//")) {
    103     0  stevel 			len = strlen(ptr + 1);
    104     0  stevel 			(void) memmove(ptr, ptr + 1, len + 1);
    105     0  stevel 			continue;
    106     0  stevel 		}
    107     0  stevel 		/* change substring "/./" into "/" */
    108     0  stevel 		if (ptr = strstr(path, "/./")) {
    109     0  stevel 			len = strlen(ptr + 2);
    110     0  stevel 			(void) memmove(ptr, ptr + 2, len + 1);
    111     0  stevel 			continue;
    112     0  stevel 		}
    113     0  stevel 
    114     0  stevel 		/* change substring "/<foo>/../" into "/" */
    115     0  stevel 		if (ptr = strstr(path, "/../")) {
    116     0  stevel 			len = strlen(ptr + 3);
    117     0  stevel 			*ptr = '\0';
    118     0  stevel 			ptr2 = strrchr(path, (int)'/');
    119     0  stevel 			if (ptr2 == NULL) {
    120     0  stevel 				/* path had a leading "/../" */
    121     0  stevel 				ptr2 = path;
    122     0  stevel 			}
    123     0  stevel 			(void) memmove(ptr2, ptr + 3, len + 1);
    124     0  stevel 			continue;
    125     0  stevel 		}
    126     0  stevel 
    127     0  stevel 		/* change trailing "/<foo>/.." into "/" */
    128     0  stevel 		if ((len >= 3) &&
    129     0  stevel 		    (path[len - 3] == '/') &&
    130     0  stevel 		    (path[len - 2] == '.') &&
    131     0  stevel 		    (path[len - 1] == '.')) {
    132     0  stevel 			path[len - 3] = '\0';
    133     0  stevel 			ptr2 = strrchr(path, (int)'/');
    134     0  stevel 			if (ptr2 != NULL) {
    135     0  stevel 				ptr2[1] = '\0';
    136     0  stevel 			} else {
    137     0  stevel 				/* path was "/.." */
    138     0  stevel 				path[0] = '/';
    139     0  stevel 				path[1] = '\0';
    140     0  stevel 			}
    141     0  stevel 			continue;
    142     0  stevel 		}
    143     0  stevel 
    144     0  stevel 		/* change trailing "/." into "/" */
    145     0  stevel 		if ((len >= 2) &&
    146     0  stevel 		    (path[len - 2] == '/') &&
    147     0  stevel 		    (path[len - 1] == '.')) {
    148     0  stevel 			path[len - 1] = '\0';
    149     0  stevel 			continue;
    150     0  stevel 		}
    151     0  stevel 
    152     0  stevel 		/* remove trailing "/" unless it's the root */
    153     0  stevel 		if ((len > 1) && (path[len - 1] == '/')) {
    154     0  stevel 			path[len - 1] = '\0';
    155     0  stevel 			continue;
    156     0  stevel 		}
    157     0  stevel 
    158     0  stevel 		break;
    159     0  stevel 	}
    160     0  stevel }
    161     0  stevel 
    162     0  stevel 
    163     0  stevel /*
    164     0  stevel  * debug version has two more flags:
    165     0  stevel  *	-L force load driver
    166     0  stevel  *	-M: print per driver list
    167     0  stevel  */
    168     0  stevel 
    169     0  stevel #ifdef	DEBUG
    170  9074    Judy static const char *optstring = "abcdDvVxpPFf:M:dLuC";
    171     0  stevel #else
    172  9074    Judy static const char *optstring = "abcdDvVxpPFf:uC";
    173     0  stevel #endif	/* DEBUG */
    174     0  stevel 
    175     0  stevel int
    176     0  stevel main(int argc, char *argv[])
    177     0  stevel {
    178     0  stevel 	long pagesize, npages;
    179     0  stevel 	int c, ret;
    180     0  stevel 	char hw_provider[SYS_NMLN];
    181     0  stevel 
    182     0  stevel 	setprogname(argv[0]);
    183     0  stevel 	opts.o_promdev = "/dev/openprom";
    184     0  stevel 
    185     0  stevel 	while ((c = getopt(argc, argv, optstring)) != -1)  {
    186     0  stevel 		switch (c)  {
    187     0  stevel 		case 'a':
    188     0  stevel 			++opts.o_ancestors;
    189     0  stevel 			break;
    190     0  stevel 		case 'b':
    191     0  stevel 			++opts.o_productinfo;
    192     0  stevel 			break;
    193     0  stevel 		case 'c':
    194     0  stevel 			++opts.o_children;
    195  9074    Judy 			break;
    196  9074    Judy 		case 'd':
    197  9074    Judy 			++opts.o_pciid;
    198     0  stevel 			break;
    199     0  stevel 		case 'D':
    200     0  stevel 			++opts.o_drv_name;
    201     0  stevel 			break;
    202     0  stevel 		case 'v':
    203     0  stevel 			++opts.o_verbose;
    204     0  stevel 			break;
    205     0  stevel 		case 'p':
    206     0  stevel 			++opts.o_prominfo;
    207     0  stevel 			break;
    208     0  stevel 		case 'f':
    209     0  stevel 			opts.o_promdev = optarg;
    210     0  stevel 			break;
    211     0  stevel 		case 'V':
    212     0  stevel 			++opts.o_promversion;
    213     0  stevel 			break;
    214     0  stevel 		case 'x':
    215     0  stevel 			++opts.o_prom_ready64;
    216     0  stevel 			break;
    217     0  stevel 		case 'F':
    218     0  stevel 			++opts.o_fbname;
    219     0  stevel 			++opts.o_noheader;
    220     0  stevel 			break;
    221     0  stevel 		case 'P':
    222     0  stevel 			++opts.o_pseudodevs;
    223     0  stevel 			break;
    224     0  stevel 		case 'C':
    225     0  stevel 			++opts.o_forcecache;
    226     0  stevel 			break;
    227     0  stevel #ifdef	DEBUG
    228     0  stevel 		case 'M':
    229     0  stevel 			dbg.d_drivername = optarg;
    230     0  stevel 			++dbg.d_bydriver;
    231     0  stevel 			break;
    232     0  stevel 		case 'L':
    233     0  stevel 			++dbg.d_forceload;
    234     0  stevel 			break;
    235     0  stevel #endif	/* DEBUG */
    236     0  stevel 
    237     0  stevel 		default:
    238     0  stevel 			(void) fprintf(stderr, usage, opts.o_progname);
    239     0  stevel 			return (1);
    240     0  stevel 		}
    241     0  stevel 	}
    242     0  stevel 
    243     0  stevel 	(void) uname(&opts.o_uts);
    244     0  stevel 
    245     0  stevel 	if (opts.o_fbname)
    246     0  stevel 		return (do_fbname());
    247     0  stevel 
    248     0  stevel 	if (opts.o_promversion)
    249     0  stevel 		return (do_promversion());
    250     0  stevel 
    251     0  stevel 	if (opts.o_prom_ready64)
    252     0  stevel 		return (do_prom_version64());
    253     0  stevel 
    254     0  stevel 	if (opts.o_productinfo)
    255     0  stevel 		return (do_productinfo());
    256     0  stevel 
    257     0  stevel 	opts.o_devices_path = NULL;
    258     0  stevel 	opts.o_devt = DDI_DEV_T_NONE;
    259     0  stevel 	opts.o_target = 0;
    260     0  stevel 	if (optind < argc) {
    261     0  stevel 		struct stat	sinfo;
    262     0  stevel 		char		*path = argv[optind];
    263     0  stevel 		int		error;
    264     0  stevel 
    265  8638  Vikram 		if (opts.o_prominfo) {
    266  8638  Vikram 			/* PROM tree cannot be used with path */
    267  8638  Vikram 			(void) fprintf(stderr, "%s: path and -p option are "
    268  8638  Vikram 			    "mutually exclusive\n", opts.o_progname);
    269  8638  Vikram 			return (1);
    270  8638  Vikram 		}
    271  8638  Vikram 
    272     0  stevel 		if (strlen(path) >= MAXPATHLEN) {
    273     0  stevel 			(void) fprintf(stderr, "%s: "
    274     0  stevel 			    "path specified is too long\n", opts.o_progname);
    275     0  stevel 			return (1);
    276     0  stevel 		}
    277     0  stevel 
    278     0  stevel 		if (error = stat(path, &sinfo)) {
    279     0  stevel 
    280     0  stevel 			/* an invalid path was specified */
    281     0  stevel 			(void) fprintf(stderr, "%s: invalid path specified\n",
    282  8638  Vikram 			    opts.o_progname);
    283     0  stevel 			return (1);
    284     0  stevel 
    285     0  stevel 		} else if (((sinfo.st_mode & S_IFMT) == S_IFCHR) ||
    286  8638  Vikram 		    ((sinfo.st_mode & S_IFMT) == S_IFBLK)) {
    287     0  stevel 
    288     0  stevel 			opts.o_devt = sinfo.st_rdev;
    289     0  stevel 			error = 0;
    290     0  stevel 
    291     0  stevel 		} else if ((sinfo.st_mode & S_IFMT) == S_IFDIR) {
    292     0  stevel 			size_t	len, plen;
    293     0  stevel 
    294     0  stevel 			/* clean up the path */
    295     0  stevel 			cleanup_path(path, new_path);
    296     0  stevel 
    297     0  stevel 			len = strlen(new_path);
    298     0  stevel 			plen = strlen("/devices");
    299     0  stevel 			if (len < plen) {
    300     0  stevel 				/* This is not a valid /devices path */
    301     0  stevel 				error = 1;
    302     0  stevel 			} else if ((len == plen) &&
    303     0  stevel 			    (strcmp(new_path, "/devices") == 0)) {
    304     0  stevel 				/* /devices is the root nexus */
    305     0  stevel 				opts.o_devices_path = "/";
    306     0  stevel 				error = 0;
    307     0  stevel 			} else if (strncmp(new_path, "/devices/", plen + 1)) {
    308     0  stevel 				/* This is not a valid /devices path */
    309     0  stevel 				error = 1;
    310     0  stevel 			} else {
    311     0  stevel 				/* a /devices/ path was specified */
    312     0  stevel 				opts.o_devices_path = new_path + plen;
    313     0  stevel 				error = 0;
    314     0  stevel 			}
    315     0  stevel 
    316     0  stevel 		} else {
    317     0  stevel 			/* an invalid device path was specified */
    318     0  stevel 			error = 1;
    319     0  stevel 		}
    320     0  stevel 
    321     0  stevel 		if (error) {
    322     0  stevel 			(void) fprintf(stderr, "%s: "
    323     0  stevel 			    "invalid device path specified\n",
    324     0  stevel 			    opts.o_progname);
    325     0  stevel 			return (1);
    326     0  stevel 		}
    327     0  stevel 
    328     0  stevel 		opts.o_target = 1;
    329     0  stevel 	}
    330     0  stevel 
    331     0  stevel 	if ((opts.o_ancestors || opts.o_children) && (!opts.o_target)) {
    332     0  stevel 		(void) fprintf(stderr, "%s: options require a device path\n",
    333     0  stevel 		    opts.o_progname);
    334     0  stevel 		return (1);
    335     0  stevel 	}
    336     0  stevel 
    337     0  stevel 	if (opts.o_target) {
    338     0  stevel 		prtconf_devinfo();
    339     0  stevel 		return (0);
    340     0  stevel 	}
    341     0  stevel 
    342     0  stevel 	ret = sysinfo(SI_HW_PROVIDER, hw_provider, sizeof (hw_provider));
    343     0  stevel 	/*
    344     0  stevel 	 * If 0 bytes are returned (the system returns '1', for the \0),
    345     0  stevel 	 * we're probably on x86, and there has been no si-hw-provider
    346     0  stevel 	 * set in /etc/bootrc, so just default to Sun.
    347     0  stevel 	 */
    348     0  stevel 	if (ret <= 1) {
    349     0  stevel 		(void) strncpy(hw_provider, "Sun Microsystems",
    350     0  stevel 		    sizeof (hw_provider));
    351     0  stevel 	} else {
    352     0  stevel 		/*
    353     0  stevel 		 * Provide backward compatibility by stripping out the _.
    354     0  stevel 		 */
    355     0  stevel 		if (strcmp(hw_provider, "Sun_Microsystems") == 0)
    356     0  stevel 			hw_provider[3] = ' ';
    357     0  stevel 	}
    358     0  stevel 	(void) printf("System Configuration:  %s  %s\n", hw_provider,
    359     0  stevel 	    opts.o_uts.machine);
    360     0  stevel 
    361     0  stevel 	pagesize = sysconf(_SC_PAGESIZE);
    362     0  stevel 	npages = sysconf(_SC_PHYS_PAGES);
    363     0  stevel 	(void) printf("Memory size: ");
    364     0  stevel 	if (pagesize == -1 || npages == -1)
    365     0  stevel 		(void) printf("unable to determine\n");
    366     0  stevel 	else {
    367     0  stevel 		const int64_t kbyte = 1024;
    368     0  stevel 		const int64_t mbyte = 1024 * 1024;
    369     0  stevel 		int64_t ii = (int64_t)pagesize * npages;
    370     0  stevel 
    371     0  stevel 		if (ii >= mbyte)
    372     0  stevel 			(void) printf("%ld Megabytes\n",
    373  8638  Vikram 			    (long)((ii+mbyte-1) / mbyte));
    374     0  stevel 		else
    375     0  stevel 			(void) printf("%ld Kilobytes\n",
    376  8638  Vikram 			    (long)((ii+kbyte-1) / kbyte));
    377     0  stevel 	}
    378     0  stevel 
    379     0  stevel 	if (opts.o_prominfo) {
    380     0  stevel 		(void) printf("System Peripherals (PROM Nodes):\n\n");
    381     0  stevel 		if (do_prominfo() == 0)
    382     0  stevel 			return (0);
    383     0  stevel 		(void) fprintf(stderr, "%s: Defaulting to non-PROM mode...\n",
    384     0  stevel 		    opts.o_progname);
    385     0  stevel 	}
    386     0  stevel 
    387     0  stevel 	(void) printf("System Peripherals (Software Nodes):\n\n");
    388     0  stevel 
    389     0  stevel 	(void) prtconf_devinfo();
    390     0  stevel 
    391     0  stevel 	return (0);
    392     0  stevel }
    393