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 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 25 */ 26 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, *ptr; 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 if ((path = realpath(optarg, NULL)) == NULL) 77 path = optarg; 78 break; 79 case ':': 80 usage(); 81 return (1); 82 83 BOOL('v', verbose); 84 BOOL('q', quote); 85 BOOL('?', error); 86 87 PER_OPT('b', DI_PROP_TYPE_BYTE); 88 PER_OPT('i', DI_PROP_TYPE_INT); 89 PER_OPT('l', DI_PROP_TYPE_INT64); 90 PER_OPT('s', DI_PROP_TYPE_STRING); 91 } 92 } 93 94 #undef BOOL 95 #undef PER_OPT 96 97 if (error) { 98 usage(); 99 return (1); 100 } 101 102 /* default to strings */ 103 if (type == DI_PROP_TYPE_UNKNOWN) 104 type = DI_PROP_TYPE_STRING; 105 106 /* 107 * It's convenient to use the filesystem as a source of device 108 * node paths. In that case, the path will be prefixed with 109 * "/devices", which we strip off here as di_init() expects 110 * just the path to the node. 111 */ 112 if (strncmp("/devices/", path, strlen("/devices/")) == 0) { 113 path += strlen("/devices"); 114 115 /* cut off minor name */ 116 if ((ptr = strrchr(path, ':')) != NULL) 117 *ptr = '\0'; 118 } 119 120 if ((dn = di_init(path, DINFOPROP)) == DI_NODE_NIL) { 121 perror("di_init"); 122 return (1); 123 } 124 125 /* Careful with that axe, Eugene... */ 126 #define PER_TYPE(typ, func, val, incr, form, pv, sep) \ 127 case (typ): \ 128 n = func(DDI_DEV_T_ANY, \ 129 dn, argv[optind], &(val)); \ 130 while (n > 0) { \ 131 (void) printf((form), pv); \ 132 incr; \ 133 n--; \ 134 if (n > 0) \ 135 (void) printf(sep); \ 136 } \ 137 (void) printf("\n"); \ 138 break 139 140 while (optind < argc) { 141 if (verbose) 142 (void) printf("%s=", argv[optind]); 143 144 switch (type) { 145 PER_TYPE(DI_PROP_TYPE_BYTE, di_prop_lookup_bytes, 146 val_b, val_b++, "%2.2x", *val_b, "."); 147 PER_TYPE(DI_PROP_TYPE_INT, di_prop_lookup_ints, 148 val_i, val_i++, "%8.8x", *val_i, "."); 149 PER_TYPE(DI_PROP_TYPE_INT64, di_prop_lookup_int64, 150 val_l, val_l++, "%16.16llx", *val_l, "."); 151 PER_TYPE(DI_PROP_TYPE_STRING, di_prop_lookup_strings, 152 val_s, val_s += strlen(val_s) + 1, 153 (quote ? "\"%s\"" : "%s"), val_s, " + "); 154 } 155 156 optind++; 157 } 158 159 #undef PER_TYPE 160 161 di_fini(dn); 162 163 return (0); 164 } 165