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 27 #include <stdio.h> 28 #include <unistd.h> 29 #include <strings.h> 30 #include <libdevinfo.h> 31 32 static void 33 usage(void) 34 { 35 (void) fprintf(stderr, 36 "Usage: devprop [-n device-path] " 37 "[-vq] [-{b|i|l|s}] [property [...]]\n"); 38 } 39 40 int 41 main(int argc, char *argv[]) 42 { 43 int c; 44 boolean_t verbose = B_FALSE, quote = B_FALSE, 45 error = B_FALSE; 46 int type = DI_PROP_TYPE_UNKNOWN; 47 char *path = "/"; 48 di_node_t dn; 49 uchar_t *val_b; 50 int *val_i; 51 int64_t *val_l; 52 char *val_s, *ptr; 53 int n; 54 55 extern char *optarg; 56 extern int optind; 57 58 #define BOOL(ch, var) \ 59 case ch: \ 60 var = B_TRUE; \ 61 break 62 63 #define PER_OPT(ch, typ) \ 64 case ch: \ 65 if (type != DI_PROP_TYPE_UNKNOWN) { \ 66 usage(); \ 67 return (1); \ 68 } \ 69 type = (typ); \ 70 break 71 72 while ((c = getopt(argc, argv, ":n:vqbils")) != -1) { 73 switch (c) { 74 case 'n': 75 if ((path = realpath(optarg, NULL)) == NULL) 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 /* cut off minor name */ 115 if ((ptr = strrchr(path, ':')) != NULL) 116 *ptr = '\0'; 117 } 118 119 if ((dn = di_init(path, DINFOPROP)) == DI_NODE_NIL) { 120 perror("di_init"); 121 return (1); 122 } 123 124 /* Careful with that axe, Eugene... */ 125 #define PER_TYPE(typ, func, val, incr, form, pv, sep) \ 126 case (typ): \ 127 n = func(DDI_DEV_T_ANY, \ 128 dn, argv[optind], &(val)); \ 129 while (n > 0) { \ 130 (void) printf((form), pv); \ 131 incr; \ 132 n--; \ 133 if (n > 0) \ 134 (void) printf(sep); \ 135 } \ 136 (void) printf("\n"); \ 137 break 138 139 while (optind < argc) { 140 if (verbose) 141 (void) printf("%s=", argv[optind]); 142 143 switch (type) { 144 PER_TYPE(DI_PROP_TYPE_BYTE, di_prop_lookup_bytes, 145 val_b, val_b++, "%2.2x", *val_b, "."); 146 PER_TYPE(DI_PROP_TYPE_INT, di_prop_lookup_ints, 147 val_i, val_i++, "%8.8x", *val_i, "."); 148 PER_TYPE(DI_PROP_TYPE_INT64, di_prop_lookup_int64, 149 val_l, val_l++, "%16.16llx", *val_l, "."); 150 PER_TYPE(DI_PROP_TYPE_STRING, di_prop_lookup_strings, 151 val_s, val_s += strlen(val_s) + 1, 152 (quote ? "\"%s\"" : "%s"), val_s, " + "); 153 } 154 155 optind++; 156 } 157 158 #undef PER_TYPE 159 160 di_fini(dn); 161 162 return (0); 163 }