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