xref: /illumos-gate/usr/src/cmd/sysdef/sdevinfo.c (revision bc1f688b4872ace323eaddbb1a6365d054e7bf56)
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  * Copyright (c) 1990 - 1997, Sun Microsystems, Inc.
24  */
25 
26 #pragma	ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * For machines that support the openprom, fetch and print the list
30  * of devices that the kernel has fetched from the prom or conjured up.
31  */
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <fcntl.h>
37 #include <stdarg.h>
38 #include <libdevinfo.h>
39 
40 static char *progname = "sysdef";
41 extern int devflag;		/* SunOS4.x devinfo compatible output */
42 extern int drvname_flag;	/* print out the driver name too */
43 
44 static int _error(char *opt_noperror, ...);
45 static int dump_node(di_node_t node, void *arg);
46 
47 void
48 sysdef_devinfo(void)
49 {
50 	di_node_t root_node;
51 
52 	/* take a snapshot of kernel devinfo tree */
53 	if ((root_node = di_init("/", DINFOSUBTREE)) == DI_NODE_NIL) {
54 		exit(_error("di_init() failed."));
55 	}
56 
57 	/*
58 	 * ...and call di_walk_node to report it out...
59 	 */
60 	di_walk_node(root_node, DI_WALK_CLDFIRST, NULL, dump_node);
61 
62 	di_fini(root_node);
63 }
64 
65 /*
66  * print out information about this node
67  */
68 static int
69 dump_node(di_node_t node, void *arg)
70 {
71 	int i;
72 	char *driver_name;
73 	di_node_t tmp;
74 	int indent_level = 0;
75 
76 	/* find indent level */
77 	tmp = node;
78 	while ((tmp = di_parent_node(tmp)) != DI_NODE_NIL)
79 		indent_level++;
80 
81 	/* we would start at 0, except that we skip the root node */
82 	if (!devflag)
83 		indent_level--;
84 
85 	for (i = 0; i < indent_level; i++)
86 		(void) putchar('\t');
87 
88 	if (indent_level >= 0) {
89 		if (devflag) {
90 			/*
91 			 * 4.x devinfo(8) compatible..
92 			 */
93 			(void) printf("Node '%s', unit #%d",
94 				di_node_name(node),
95 				di_instance(node));
96 			if (drvname_flag) {
97 				if (driver_name = di_driver_name(node)) {
98 					(void) printf(" (driver name: %s)",
99 					    driver_name);
100 				}
101 			} else if (di_state(node) & DI_DRIVER_DETACHED) {
102 				(void) printf(" (no driver)");
103 			}
104 		} else {
105 			/*
106 			 * prtconf(1M) compatible..
107 			 */
108 			(void) printf("%s", di_node_name(node));
109 			if (di_instance(node) >= 0)
110 				(void) printf(", instance #%d",
111 				    di_instance(node));
112 			if (drvname_flag) {
113 				if (driver_name = di_driver_name(node)) {
114 					(void) printf(" (driver name: %s)",
115 					    driver_name);
116 				}
117 			} else if (di_state(node) & DI_DRIVER_DETACHED) {
118 				(void) printf(" (driver not attached)");
119 			}
120 		}
121 		(void) printf("\n");
122 	}
123 	return (DI_WALK_CONTINUE);
124 }
125 
126 /*
127  * utility routines
128  */
129 
130 /* _error([no_perror, ] fmt [, arg ...]) */
131 static int
132 _error(char *opt_noperror, ...)
133 {
134 	int saved_errno;
135 	va_list ap;
136 	int no_perror = 0;
137 	char *fmt;
138 	extern int errno, _doprnt();
139 
140 	saved_errno = errno;
141 
142 	if (progname)
143 		(void) fprintf(stderr, "%s: ", progname);
144 
145 	va_start(ap, opt_noperror);
146 	if (opt_noperror == NULL) {
147 		no_perror = 1;
148 		fmt = va_arg(ap, char *);
149 	} else
150 		fmt = opt_noperror;
151 	(void) _doprnt(fmt, ap, stderr);
152 	va_end(ap);
153 
154 	if (no_perror)
155 		(void) fprintf(stderr, "\n");
156 	else {
157 		(void) fprintf(stderr, ": ");
158 		errno = saved_errno;
159 		perror("");
160 	}
161 
162 	return (1);
163 }
164