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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <unistd.h> 30 #include <strings.h> 31 #include <libdevinfo.h> 32 33 static void 34 usage(void) 35 { 36 (void) fprintf(stderr, 37 "Usage: devprop [-n device-path] " 38 "[-vq] [-{b|i|l|s}] [property [...]]\n"); 39 } 40 41 int 42 main(int argc, char *argv[]) 43 { 44 int c; 45 boolean_t verbose = B_FALSE, quote = B_FALSE, 46 error = B_FALSE; 47 int type = DI_PROP_TYPE_UNKNOWN; 48 char *path = "/"; 49 di_node_t dn; 50 uchar_t *val_b; 51 int *val_i; 52 int64_t *val_l; 53 char *val_s; 54 int n; 55 56 extern char *optarg; 57 extern int optind; 58 59 #define BOOL(ch, var) \ 60 case ch: \ 61 var = B_TRUE; \ 62 break 63 64 #define PER_OPT(ch, typ) \ 65 case ch: \ 66 if (type != DI_PROP_TYPE_UNKNOWN) { \ 67 usage(); \ 68 return (1); \ 69 } \ 70 type = (typ); \ 71 break 72 73 while ((c = getopt(argc, argv, ":n:vqbils")) != -1) { 74 switch (c) { 75 case 'n': 76 path = optarg; 77 break; 78 case ':': 79 usage(); 80 return (1); 81 82 BOOL('v', verbose); 83 BOOL('q', quote); 84 BOOL('?', error); 85 86 PER_OPT('b', DI_PROP_TYPE_BYTE); 87 PER_OPT('i', DI_PROP_TYPE_INT); 88 PER_OPT('l', DI_PROP_TYPE_INT64); 89 PER_OPT('s', DI_PROP_TYPE_STRING); 90 } 91 } 92 93 #undef BOOL 94 #undef PER_OPT 95 96 if (error) { 97 usage(); 98 return (1); 99 } 100 101 /* default to strings */ 102 if (type == DI_PROP_TYPE_UNKNOWN) 103 type = DI_PROP_TYPE_STRING; 104 105 /* 106 * It's convenient to use the filesystem as a source of device 107 * node paths. In that case, the path will be prefixed with 108 * "/devices", which we strip off here as di_init() expects 109 * just the path to the node. 110 */ 111 if (strncmp("/devices/", path, strlen("/devices/")) == 0) 112 path += strlen("/devices"); 113 114 if ((dn = di_init(path, DINFOPROP)) == DI_NODE_NIL) { 115 perror("di_init"); 116 return (1); 117 } 118 119 /* Careful with that axe, Eugene... */ 120 #define PER_TYPE(typ, func, val, incr, form, pv, sep) \ 121 case (typ): \ 122 n = func(DDI_DEV_T_ANY, \ 123 dn, argv[optind], &(val)); \ 124 while (n > 0) { \ 125 (void) printf((form), pv); \ 126 incr; \ 127 n--; \ 128 if (n > 0) \ 129 (void) printf(sep); \ 130 } \ 131 (void) printf("\n"); \ 132 break 133 134 while (optind < argc) { 135 if (verbose) 136 (void) printf("%s=", argv[optind]); 137 138 switch (type) { 139 PER_TYPE(DI_PROP_TYPE_BYTE, di_prop_lookup_bytes, 140 val_b, val_b++, "%2.2x", *val_b, "."); 141 PER_TYPE(DI_PROP_TYPE_INT, di_prop_lookup_ints, 142 val_i, val_i++, "%8.8x", *val_i, "."); 143 PER_TYPE(DI_PROP_TYPE_INT64, di_prop_lookup_int64, 144 val_l, val_l++, "%16.16llx", *val_l, "."); 145 PER_TYPE(DI_PROP_TYPE_STRING, di_prop_lookup_strings, 146 val_s, val_s += strlen(val_s) + 1, 147 (quote ? "\"%s\"" : "%s"), val_s, " + "); 148 } 149 150 optind++; 151 } 152 153 #undef PER_TYPE 154 155 di_fini(dn); 156 157 return (0); 158 } 159