Home | History | Annotate | Download | only in devprop
      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