8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / prtconf / prtconf.c
blobb7551166cf191b46c44f96d85f6b24e95e14d7ce
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2011, Joyent, Inc. All rights reserved.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <strings.h>
35 #include <sys/systeminfo.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include "prtconf.h"
40 struct prt_opts opts;
41 struct prt_dbg dbg;
42 static char new_path[MAXPATHLEN];
44 #define INDENT_LENGTH 4
46 #ifdef __x86
47 static const char *usage = "%s [ -V | -x | -abcdvpPD ] [ <device_path > ]\n";
48 #else
49 static const char *usage =
50 "%s [ -F | -V | -x | -abcdvpPD ][ <device_path > ]\n";
51 #endif /* __x86 */
53 static void
54 setpname(const char *name)
56 char *p;
58 if (name == NULL)
59 opts.o_progname = "prtconf";
60 else if (p = strrchr(name, '/'))
61 opts.o_progname = (const char *) p + 1;
62 else
63 opts.o_progname = name;
66 /*PRINTFLIKE1*/
67 void
68 dprintf(const char *fmt, ...)
70 if (dbg.d_debug) {
71 va_list ap;
72 va_start(ap, fmt);
73 (void) vfprintf(stderr, fmt, ap);
74 va_end(ap);
78 void
79 indent_to_level(int ilev)
81 (void) printf("%*s", INDENT_LENGTH * ilev, "");
84 static void
85 cleanup_path(const char *input_path, char *path)
87 char *ptr, *ptr2;
88 size_t len;
90 if ((input_path == NULL) || (path == NULL))
91 return;
93 (void) strcpy(path, input_path);
95 /*LINTED*/
96 while (1) {
97 len = strlen(path);
98 if (len == 0)
99 break;
101 /* change substring "//" into "/" */
102 if (ptr = strstr(path, "//")) {
103 len = strlen(ptr + 1);
104 (void) memmove(ptr, ptr + 1, len + 1);
105 continue;
107 /* change substring "/./" into "/" */
108 if (ptr = strstr(path, "/./")) {
109 len = strlen(ptr + 2);
110 (void) memmove(ptr, ptr + 2, len + 1);
111 continue;
114 /* change substring "/<foo>/../" into "/" */
115 if (ptr = strstr(path, "/../")) {
116 len = strlen(ptr + 3);
117 *ptr = '\0';
118 ptr2 = strrchr(path, (int)'/');
119 if (ptr2 == NULL) {
120 /* path had a leading "/../" */
121 ptr2 = path;
123 (void) memmove(ptr2, ptr + 3, len + 1);
124 continue;
127 /* change trailing "/<foo>/.." into "/" */
128 if ((len >= 3) &&
129 (path[len - 3] == '/') &&
130 (path[len - 2] == '.') &&
131 (path[len - 1] == '.')) {
132 path[len - 3] = '\0';
133 ptr2 = strrchr(path, (int)'/');
134 if (ptr2 != NULL) {
135 ptr2[1] = '\0';
136 } else {
137 /* path was "/.." */
138 path[0] = '/';
139 path[1] = '\0';
141 continue;
144 /* change trailing "/." into "/" */
145 if ((len >= 2) &&
146 (path[len - 2] == '/') &&
147 (path[len - 1] == '.')) {
148 path[len - 1] = '\0';
149 continue;
152 /* remove trailing "/" unless it's the root */
153 if ((len > 1) && (path[len - 1] == '/')) {
154 path[len - 1] = '\0';
155 continue;
158 break;
164 * debug version has two more flags:
165 * -L force load driver
166 * -M: print per driver list
169 #ifdef DEBUG
170 static const char *optstring = "abcdDvVxmpPFf:M:dLuC";
171 #else
172 static const char *optstring = "abcdDvVxmpPFf:uC";
173 #endif /* DEBUG */
176 main(int argc, char *argv[])
178 long pagesize, npages;
179 int c, ret;
180 char hw_provider[SYS_NMLN];
182 setpname(argv[0]);
183 opts.o_promdev = "/dev/openprom";
185 while ((c = getopt(argc, argv, optstring)) != -1) {
186 switch (c) {
187 case 'a':
188 ++opts.o_ancestors;
189 break;
190 case 'b':
191 ++opts.o_productinfo;
192 break;
193 case 'c':
194 ++opts.o_children;
195 break;
196 case 'd':
197 ++opts.o_pciid;
198 break;
199 case 'D':
200 ++opts.o_drv_name;
201 break;
202 case 'v':
203 ++opts.o_verbose;
204 break;
205 case 'm':
206 ++opts.o_memory;
207 break;
208 case 'p':
209 ++opts.o_prominfo;
210 break;
211 case 'f':
212 opts.o_promdev = optarg;
213 break;
214 case 'V':
215 ++opts.o_promversion;
216 break;
217 case 'x':
218 ++opts.o_prom_ready64;
219 break;
220 case 'F':
221 ++opts.o_fbname;
222 ++opts.o_noheader;
223 break;
224 case 'P':
225 ++opts.o_pseudodevs;
226 break;
227 case 'C':
228 ++opts.o_forcecache;
229 break;
230 #ifdef DEBUG
231 case 'M':
232 dbg.d_drivername = optarg;
233 ++dbg.d_bydriver;
234 break;
235 case 'L':
236 ++dbg.d_forceload;
237 break;
238 #endif /* DEBUG */
240 default:
241 (void) fprintf(stderr, usage, opts.o_progname);
242 return (1);
246 (void) uname(&opts.o_uts);
248 if (opts.o_fbname)
249 return (do_fbname());
251 if (opts.o_promversion)
252 return (do_promversion());
254 if (opts.o_prom_ready64)
255 return (do_prom_version64());
257 if (opts.o_productinfo)
258 return (do_productinfo());
260 opts.o_devices_path = NULL;
261 opts.o_devt = DDI_DEV_T_NONE;
262 opts.o_target = 0;
263 if (optind < argc) {
264 struct stat sinfo;
265 char *path = argv[optind];
266 int error;
268 if (opts.o_prominfo) {
269 /* PROM tree cannot be used with path */
270 (void) fprintf(stderr, "%s: path and -p option are "
271 "mutually exclusive\n", opts.o_progname);
272 return (1);
275 if (strlen(path) >= MAXPATHLEN) {
276 (void) fprintf(stderr, "%s: "
277 "path specified is too long\n", opts.o_progname);
278 return (1);
281 if (error = stat(path, &sinfo)) {
283 /* an invalid path was specified */
284 (void) fprintf(stderr, "%s: invalid path specified\n",
285 opts.o_progname);
286 return (1);
288 } else if (((sinfo.st_mode & S_IFMT) == S_IFCHR) ||
289 ((sinfo.st_mode & S_IFMT) == S_IFBLK)) {
291 opts.o_devt = sinfo.st_rdev;
292 error = 0;
294 } else if ((sinfo.st_mode & S_IFMT) == S_IFDIR) {
295 size_t len, plen;
297 /* clean up the path */
298 cleanup_path(path, new_path);
300 len = strlen(new_path);
301 plen = strlen("/devices");
302 if (len < plen) {
303 /* This is not a valid /devices path */
304 error = 1;
305 } else if ((len == plen) &&
306 (strcmp(new_path, "/devices") == 0)) {
307 /* /devices is the root nexus */
308 opts.o_devices_path = "/";
309 error = 0;
310 } else if (strncmp(new_path, "/devices/", plen + 1)) {
311 /* This is not a valid /devices path */
312 error = 1;
313 } else {
314 /* a /devices/ path was specified */
315 opts.o_devices_path = new_path + plen;
316 error = 0;
319 } else {
320 /* an invalid device path was specified */
321 error = 1;
324 if (error) {
325 (void) fprintf(stderr, "%s: "
326 "invalid device path specified\n",
327 opts.o_progname);
328 return (1);
331 opts.o_target = 1;
334 if ((opts.o_ancestors || opts.o_children) && (!opts.o_target)) {
335 (void) fprintf(stderr, "%s: options require a device path\n",
336 opts.o_progname);
337 return (1);
340 if (opts.o_target) {
341 prtconf_devinfo();
342 return (0);
345 if (!opts.o_memory) {
346 ret = sysinfo(SI_HW_PROVIDER, hw_provider,
347 sizeof (hw_provider));
349 * If 0 bytes are returned (the system returns '1', for the \0),
350 * we're probably on x86, default to "Unknown Hardware Vendor".
352 if (ret <= 1) {
353 (void) strncpy(hw_provider, "Unknown Hardware Vendor",
354 sizeof (hw_provider));
356 (void) printf("System Configuration: %s %s\n", hw_provider,
357 opts.o_uts.machine);
360 pagesize = sysconf(_SC_PAGESIZE);
361 npages = sysconf(_SC_PHYS_PAGES);
362 if (pagesize == -1 || npages == -1) {
363 if (opts.o_memory) {
364 (void) printf("0\n");
365 return (1);
366 } else {
367 (void) printf("Memory size: unable to determine\n");
369 } else {
370 const int64_t mbyte = 1024 * 1024;
371 int64_t ii = (int64_t)pagesize * npages;
373 if (opts.o_memory) {
374 (void) printf("%ld\n", (long)((ii+mbyte-1) / mbyte));
375 return (0);
376 } else {
377 (void) printf("Memory size: %ld Megabytes\n",
378 (long)((ii+mbyte-1) / mbyte));
382 if (opts.o_prominfo) {
383 (void) printf("System Peripherals (PROM Nodes):\n\n");
384 if (do_prominfo() == 0)
385 return (0);
386 (void) fprintf(stderr, "%s: Defaulting to non-PROM mode...\n",
387 opts.o_progname);
390 (void) printf("System Peripherals (Software Nodes):\n\n");
392 (void) prtconf_devinfo();
394 return (0);