1843e1988Sjohnlev /*
2843e1988Sjohnlev * CDDL HEADER START
3843e1988Sjohnlev *
4843e1988Sjohnlev * The contents of this file are subject to the terms of the
5843e1988Sjohnlev * Common Development and Distribution License (the "License").
6843e1988Sjohnlev * You may not use this file except in compliance with the License.
7843e1988Sjohnlev *
8843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing.
10843e1988Sjohnlev * See the License for the specific language governing permissions
11843e1988Sjohnlev * and limitations under the License.
12843e1988Sjohnlev *
13843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each
14843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the
16843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying
17843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner]
18843e1988Sjohnlev *
19843e1988Sjohnlev * CDDL HEADER END
20843e1988Sjohnlev */
21843e1988Sjohnlev /*
22843e1988Sjohnlev * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23843e1988Sjohnlev * Use is subject to license terms.
24*b13c8383SAlexander Eremin * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25843e1988Sjohnlev */
26843e1988Sjohnlev
27843e1988Sjohnlev
28843e1988Sjohnlev #include <stdio.h>
29843e1988Sjohnlev #include <unistd.h>
30843e1988Sjohnlev #include <strings.h>
31843e1988Sjohnlev #include <libdevinfo.h>
32843e1988Sjohnlev
33843e1988Sjohnlev static void
usage(void)34843e1988Sjohnlev usage(void)
35843e1988Sjohnlev {
36843e1988Sjohnlev (void) fprintf(stderr,
37843e1988Sjohnlev "Usage: devprop [-n device-path] "
38843e1988Sjohnlev "[-vq] [-{b|i|l|s}] [property [...]]\n");
39843e1988Sjohnlev }
40843e1988Sjohnlev
41843e1988Sjohnlev int
main(int argc,char * argv[])42843e1988Sjohnlev main(int argc, char *argv[])
43843e1988Sjohnlev {
44843e1988Sjohnlev int c;
45843e1988Sjohnlev boolean_t verbose = B_FALSE, quote = B_FALSE,
46843e1988Sjohnlev error = B_FALSE;
47843e1988Sjohnlev int type = DI_PROP_TYPE_UNKNOWN;
48843e1988Sjohnlev char *path = "/";
49843e1988Sjohnlev di_node_t dn;
50843e1988Sjohnlev uchar_t *val_b;
51843e1988Sjohnlev int *val_i;
52843e1988Sjohnlev int64_t *val_l;
53*b13c8383SAlexander Eremin char *val_s, *ptr;
54843e1988Sjohnlev int n;
55843e1988Sjohnlev
56843e1988Sjohnlev extern char *optarg;
57843e1988Sjohnlev extern int optind;
58843e1988Sjohnlev
59843e1988Sjohnlev #define BOOL(ch, var) \
60843e1988Sjohnlev case ch: \
61843e1988Sjohnlev var = B_TRUE; \
62843e1988Sjohnlev break
63843e1988Sjohnlev
64843e1988Sjohnlev #define PER_OPT(ch, typ) \
65843e1988Sjohnlev case ch: \
66843e1988Sjohnlev if (type != DI_PROP_TYPE_UNKNOWN) { \
67843e1988Sjohnlev usage(); \
68843e1988Sjohnlev return (1); \
69843e1988Sjohnlev } \
70843e1988Sjohnlev type = (typ); \
71843e1988Sjohnlev break
72843e1988Sjohnlev
73843e1988Sjohnlev while ((c = getopt(argc, argv, ":n:vqbils")) != -1) {
74843e1988Sjohnlev switch (c) {
75843e1988Sjohnlev case 'n':
76*b13c8383SAlexander Eremin if ((path = realpath(optarg, NULL)) == NULL)
77*b13c8383SAlexander Eremin path = optarg;
78843e1988Sjohnlev break;
79843e1988Sjohnlev case ':':
80843e1988Sjohnlev usage();
81843e1988Sjohnlev return (1);
82843e1988Sjohnlev
83843e1988Sjohnlev BOOL('v', verbose);
84843e1988Sjohnlev BOOL('q', quote);
85843e1988Sjohnlev BOOL('?', error);
86843e1988Sjohnlev
87843e1988Sjohnlev PER_OPT('b', DI_PROP_TYPE_BYTE);
88843e1988Sjohnlev PER_OPT('i', DI_PROP_TYPE_INT);
89843e1988Sjohnlev PER_OPT('l', DI_PROP_TYPE_INT64);
90843e1988Sjohnlev PER_OPT('s', DI_PROP_TYPE_STRING);
91843e1988Sjohnlev }
92843e1988Sjohnlev }
93843e1988Sjohnlev
94843e1988Sjohnlev #undef BOOL
95843e1988Sjohnlev #undef PER_OPT
96843e1988Sjohnlev
97843e1988Sjohnlev if (error) {
98843e1988Sjohnlev usage();
99843e1988Sjohnlev return (1);
100843e1988Sjohnlev }
101843e1988Sjohnlev
102843e1988Sjohnlev /* default to strings */
103843e1988Sjohnlev if (type == DI_PROP_TYPE_UNKNOWN)
104843e1988Sjohnlev type = DI_PROP_TYPE_STRING;
105843e1988Sjohnlev
106843e1988Sjohnlev /*
107843e1988Sjohnlev * It's convenient to use the filesystem as a source of device
108843e1988Sjohnlev * node paths. In that case, the path will be prefixed with
109843e1988Sjohnlev * "/devices", which we strip off here as di_init() expects
110843e1988Sjohnlev * just the path to the node.
111843e1988Sjohnlev */
112*b13c8383SAlexander Eremin if (strncmp("/devices/", path, strlen("/devices/")) == 0) {
113843e1988Sjohnlev path += strlen("/devices");
114843e1988Sjohnlev
115*b13c8383SAlexander Eremin /* cut off minor name */
116*b13c8383SAlexander Eremin if ((ptr = strrchr(path, ':')) != NULL)
117*b13c8383SAlexander Eremin *ptr = '\0';
118*b13c8383SAlexander Eremin }
119*b13c8383SAlexander Eremin
120843e1988Sjohnlev if ((dn = di_init(path, DINFOPROP)) == DI_NODE_NIL) {
121843e1988Sjohnlev perror("di_init");
122843e1988Sjohnlev return (1);
123843e1988Sjohnlev }
124843e1988Sjohnlev
125843e1988Sjohnlev /* Careful with that axe, Eugene... */
126843e1988Sjohnlev #define PER_TYPE(typ, func, val, incr, form, pv, sep) \
127843e1988Sjohnlev case (typ): \
128843e1988Sjohnlev n = func(DDI_DEV_T_ANY, \
129843e1988Sjohnlev dn, argv[optind], &(val)); \
130843e1988Sjohnlev while (n > 0) { \
131843e1988Sjohnlev (void) printf((form), pv); \
132843e1988Sjohnlev incr; \
133843e1988Sjohnlev n--; \
134843e1988Sjohnlev if (n > 0) \
135843e1988Sjohnlev (void) printf(sep); \
136843e1988Sjohnlev } \
137843e1988Sjohnlev (void) printf("\n"); \
138843e1988Sjohnlev break
139843e1988Sjohnlev
140843e1988Sjohnlev while (optind < argc) {
141843e1988Sjohnlev if (verbose)
142843e1988Sjohnlev (void) printf("%s=", argv[optind]);
143843e1988Sjohnlev
144843e1988Sjohnlev switch (type) {
145843e1988Sjohnlev PER_TYPE(DI_PROP_TYPE_BYTE, di_prop_lookup_bytes,
146843e1988Sjohnlev val_b, val_b++, "%2.2x", *val_b, ".");
147843e1988Sjohnlev PER_TYPE(DI_PROP_TYPE_INT, di_prop_lookup_ints,
148843e1988Sjohnlev val_i, val_i++, "%8.8x", *val_i, ".");
149843e1988Sjohnlev PER_TYPE(DI_PROP_TYPE_INT64, di_prop_lookup_int64,
150843e1988Sjohnlev val_l, val_l++, "%16.16llx", *val_l, ".");
151843e1988Sjohnlev PER_TYPE(DI_PROP_TYPE_STRING, di_prop_lookup_strings,
152843e1988Sjohnlev val_s, val_s += strlen(val_s) + 1,
153843e1988Sjohnlev (quote ? "\"%s\"" : "%s"), val_s, " + ");
154843e1988Sjohnlev }
155843e1988Sjohnlev
156843e1988Sjohnlev optind++;
157843e1988Sjohnlev }
158843e1988Sjohnlev
159843e1988Sjohnlev #undef PER_TYPE
160843e1988Sjohnlev
161843e1988Sjohnlev di_fini(dn);
162843e1988Sjohnlev
163843e1988Sjohnlev return (0);
164843e1988Sjohnlev }
165