1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 32*7c478bd9Sstevel@tonic-gate #include <string.h> 33*7c478bd9Sstevel@tonic-gate #include <alloca.h> 34*7c478bd9Sstevel@tonic-gate #include <libintl.h> 35*7c478bd9Sstevel@tonic-gate #include <locale.h> 36*7c478bd9Sstevel@tonic-gate #include <unistd.h> 37*7c478bd9Sstevel@tonic-gate #include <assert.h> 38*7c478bd9Sstevel@tonic-gate #include <inttypes.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/termios.h> 40*7c478bd9Sstevel@tonic-gate #include <picl.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* 43*7c478bd9Sstevel@tonic-gate * Constant definitions and macros 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate #define COL_DELIM "|" 46*7c478bd9Sstevel@tonic-gate #define ROOT_LEVEL 0 47*7c478bd9Sstevel@tonic-gate #define LEVEL_INDENT 4 48*7c478bd9Sstevel@tonic-gate #define PROP_INDENT 2 49*7c478bd9Sstevel@tonic-gate #define NCOLS 80 50*7c478bd9Sstevel@tonic-gate #define NODEINFO_LEFT_MARGIN(x) (x * LEVEL_INDENT) 51*7c478bd9Sstevel@tonic-gate #define PROPINFO_LEFT_MARGIN(x) (x * LEVEL_INDENT + PROP_INDENT) 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define PRIxPICLTBL PRIx64 54*7c478bd9Sstevel@tonic-gate #define PRIxPICLHDL PRIx64 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Program variables 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate static char *prog; 60*7c478bd9Sstevel@tonic-gate static int verbose_mode = 0; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /* 63*7c478bd9Sstevel@tonic-gate * Error codes 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate #define EM_USAGE 0 66*7c478bd9Sstevel@tonic-gate #define EM_INIT 1 67*7c478bd9Sstevel@tonic-gate #define EM_GETROOT 2 68*7c478bd9Sstevel@tonic-gate #define EM_GETPVAL 3 69*7c478bd9Sstevel@tonic-gate #define EM_GETNXTBYCOL 4 70*7c478bd9Sstevel@tonic-gate #define EM_GETNXTBYROW 5 71*7c478bd9Sstevel@tonic-gate #define EM_GETPINFO 6 72*7c478bd9Sstevel@tonic-gate #define EM_GETPVALBYNAME 7 73*7c478bd9Sstevel@tonic-gate #define EM_GETPROPBYNAME 8 74*7c478bd9Sstevel@tonic-gate #define EM_INT_INVSIZE 9 75*7c478bd9Sstevel@tonic-gate #define EM_UINT_INVSIZE 10 76*7c478bd9Sstevel@tonic-gate #define EM_FLOAT_INVSIZE 11 77*7c478bd9Sstevel@tonic-gate #define EM_TS_INVALID 12 78*7c478bd9Sstevel@tonic-gate #define EM_TABLE_INVSIZE 13 79*7c478bd9Sstevel@tonic-gate #define EM_REF_INVSIZE 14 80*7c478bd9Sstevel@tonic-gate #define EM_TYPE_UNKNOWN 15 81*7c478bd9Sstevel@tonic-gate #define EM_TS_OVERFLOW 16 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * Error mesage texts 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate static char *err_msg[] = { 87*7c478bd9Sstevel@tonic-gate /* program usage */ 88*7c478bd9Sstevel@tonic-gate "Usage: %s [-v] [-c <picl_class>]\n", /* 0 */ 89*7c478bd9Sstevel@tonic-gate /* picl call failed messages */ 90*7c478bd9Sstevel@tonic-gate "picl_initialize failed: %s\n", /* 1 */ 91*7c478bd9Sstevel@tonic-gate "picl_get_root failed: %s\n", /* 2 */ 92*7c478bd9Sstevel@tonic-gate "picl_get_propval failed: %s\n", /* 3 */ 93*7c478bd9Sstevel@tonic-gate "picl_get_next_by_col failed: %s\n", /* 4 */ 94*7c478bd9Sstevel@tonic-gate "picl_get_next_by_row failed: %s\n", /* 5 */ 95*7c478bd9Sstevel@tonic-gate "picl_get_propinfo failed: %s\n", /* 6 */ 96*7c478bd9Sstevel@tonic-gate "picl_get_propval_by_name failed: %s\n", /* 7 */ 97*7c478bd9Sstevel@tonic-gate "picl_get_prop_by_name failed: %s\n", /* 8 */ 98*7c478bd9Sstevel@tonic-gate /* invalid data error messages */ 99*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid int size %d\n", /* 9 */ 100*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid unsigned int size %d\n", /* 10 */ 101*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid float size %d\n", /* 11 */ 102*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid timestamp\n", /* 12 */ 103*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid table handle size %d\n", /* 13 */ 104*7c478bd9Sstevel@tonic-gate "picl_get_propval: invalid reference size %d\n", /* 14 */ 105*7c478bd9Sstevel@tonic-gate "picl_get_propval: unknown type\n", /* 15 */ 106*7c478bd9Sstevel@tonic-gate "picl_get_propval: timestamp value too large\n" /* 16 */ 107*7c478bd9Sstevel@tonic-gate }; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 110*7c478bd9Sstevel@tonic-gate static void 111*7c478bd9Sstevel@tonic-gate print_errmsg(char *message, ...) 112*7c478bd9Sstevel@tonic-gate { 113*7c478bd9Sstevel@tonic-gate va_list ap; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate va_start(ap, message); 116*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", prog); 117*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, message, ap); 118*7c478bd9Sstevel@tonic-gate va_end(ap); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* 122*7c478bd9Sstevel@tonic-gate * Print prtpicl usage 123*7c478bd9Sstevel@tonic-gate */ 124*7c478bd9Sstevel@tonic-gate static void 125*7c478bd9Sstevel@tonic-gate usage(void) 126*7c478bd9Sstevel@tonic-gate { 127*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_USAGE]), prog); 128*7c478bd9Sstevel@tonic-gate exit(1); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate /* 132*7c478bd9Sstevel@tonic-gate * print a bytearray value and format it to fit in 80 columns 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate static void 135*7c478bd9Sstevel@tonic-gate print_bytearray(int lvl, uint8_t *vbuf, size_t nbytes) 136*7c478bd9Sstevel@tonic-gate { 137*7c478bd9Sstevel@tonic-gate int cnum; 138*7c478bd9Sstevel@tonic-gate int columns; 139*7c478bd9Sstevel@tonic-gate char *s; 140*7c478bd9Sstevel@tonic-gate struct winsize winsize; 141*7c478bd9Sstevel@tonic-gate size_t i; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* 144*7c478bd9Sstevel@tonic-gate * The COLUMNS_PER_BYTE is set to 4 to match the printf 145*7c478bd9Sstevel@tonic-gate * format used below, i.e. " %02x ", to print a byte 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate #define COLUMNS_PER_BYTE 4 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * Kind of a hack to determine the width of the output... 151*7c478bd9Sstevel@tonic-gate */ 152*7c478bd9Sstevel@tonic-gate columns = NCOLS; 153*7c478bd9Sstevel@tonic-gate if ((s = getenv("COLUMNS")) != NULL && (cnum = atoi(s)) > 0) 154*7c478bd9Sstevel@tonic-gate columns = cnum; 155*7c478bd9Sstevel@tonic-gate else if (isatty(fileno(stdout)) && 156*7c478bd9Sstevel@tonic-gate ioctl(fileno(stdout), TIOCGWINSZ, &winsize) == 0 && 157*7c478bd9Sstevel@tonic-gate winsize.ws_col != 0) 158*7c478bd9Sstevel@tonic-gate columns = winsize.ws_col; 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate cnum = PROPINFO_LEFT_MARGIN(lvl); 162*7c478bd9Sstevel@tonic-gate if ((nbytes * COLUMNS_PER_BYTE + cnum) > columns) { 163*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 164*7c478bd9Sstevel@tonic-gate cnum = 0; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate for (i = 0; i < nbytes; ++i) { 167*7c478bd9Sstevel@tonic-gate if (cnum > columns - COLUMNS_PER_BYTE) { 168*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 169*7c478bd9Sstevel@tonic-gate cnum = 0; 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate (void) printf(" %02x ", vbuf[i]); 172*7c478bd9Sstevel@tonic-gate cnum += COLUMNS_PER_BYTE; 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * Print a property's value 178*7c478bd9Sstevel@tonic-gate * If the property is read protected, return success. 179*7c478bd9Sstevel@tonic-gate * If an invalid/stale handle error is encountered, return the error. For 180*7c478bd9Sstevel@tonic-gate * other errors, print a message and return success. 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate static int 183*7c478bd9Sstevel@tonic-gate print_propval(int lvl, picl_prophdl_t proph, const picl_propinfo_t *propinfo) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate int err; 186*7c478bd9Sstevel@tonic-gate void *vbuf; 187*7c478bd9Sstevel@tonic-gate char *str; 188*7c478bd9Sstevel@tonic-gate uint64_t val64; 189*7c478bd9Sstevel@tonic-gate time_t tmp; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* 192*7c478bd9Sstevel@tonic-gate * If property is read protected, print a message and continue 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate if (!(propinfo->accessmode & PICL_READ)) { 195*7c478bd9Sstevel@tonic-gate (void) printf("<%s>", gettext("WRITE-ONLY")); 196*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate vbuf = alloca(propinfo->size); 200*7c478bd9Sstevel@tonic-gate if (propinfo->type == PICL_PTYPE_VOID) 201*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, vbuf, propinfo->size); 204*7c478bd9Sstevel@tonic-gate /* 205*7c478bd9Sstevel@tonic-gate * If the error is not a stale/invalid handle or noresponse, continue 206*7c478bd9Sstevel@tonic-gate * by ignoring the error/skipping the property. 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate if ((err == PICL_INVALIDHANDLE) || (err == PICL_STALEHANDLE) || 209*7c478bd9Sstevel@tonic-gate (err == PICL_NORESPONSE)) 210*7c478bd9Sstevel@tonic-gate return (err); 211*7c478bd9Sstevel@tonic-gate else if (err != PICL_SUCCESS) { 212*7c478bd9Sstevel@tonic-gate (void) printf("<%s: %s>", gettext("ERROR"), picl_strerror(err)); 213*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate assert(vbuf != NULL); 217*7c478bd9Sstevel@tonic-gate assert(propinfo->size > 0); 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate switch (propinfo->type) { 220*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_CHARSTRING: 221*7c478bd9Sstevel@tonic-gate (void) printf(" %s ", (char *)vbuf); 222*7c478bd9Sstevel@tonic-gate break; 223*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_INT: 224*7c478bd9Sstevel@tonic-gate switch (propinfo->size) { 225*7c478bd9Sstevel@tonic-gate case sizeof (int8_t): 226*7c478bd9Sstevel@tonic-gate /* avoid using PRId8 until lint recognizes hh */ 227*7c478bd9Sstevel@tonic-gate (void) printf(" %d ", *(int8_t *)vbuf); 228*7c478bd9Sstevel@tonic-gate break; 229*7c478bd9Sstevel@tonic-gate case sizeof (int16_t): 230*7c478bd9Sstevel@tonic-gate (void) printf(" %" PRId16 " ", *(int16_t *)vbuf); 231*7c478bd9Sstevel@tonic-gate break; 232*7c478bd9Sstevel@tonic-gate case sizeof (int32_t): 233*7c478bd9Sstevel@tonic-gate (void) printf(" %" PRId32 " ", *(int32_t *)vbuf); 234*7c478bd9Sstevel@tonic-gate break; 235*7c478bd9Sstevel@tonic-gate case sizeof (int64_t): 236*7c478bd9Sstevel@tonic-gate (void) printf(" %" PRId64 " ", *(int64_t *)vbuf); 237*7c478bd9Sstevel@tonic-gate break; 238*7c478bd9Sstevel@tonic-gate default: 239*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_INT_INVSIZE]), 240*7c478bd9Sstevel@tonic-gate propinfo->size); 241*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate break; 244*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_UNSIGNED_INT: 245*7c478bd9Sstevel@tonic-gate switch (propinfo->size) { 246*7c478bd9Sstevel@tonic-gate case sizeof (uint8_t): 247*7c478bd9Sstevel@tonic-gate /* avoid using PRIx8 until lint recognizes hh */ 248*7c478bd9Sstevel@tonic-gate (void) printf(" %#x ", *(uint8_t *)vbuf); 249*7c478bd9Sstevel@tonic-gate break; 250*7c478bd9Sstevel@tonic-gate case sizeof (uint16_t): 251*7c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx16 " ", *(uint16_t *)vbuf); 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate case sizeof (uint32_t): 254*7c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx32 " ", *(uint32_t *)vbuf); 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case sizeof (uint64_t): 257*7c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx64 " ", *(uint64_t *)vbuf); 258*7c478bd9Sstevel@tonic-gate break; 259*7c478bd9Sstevel@tonic-gate default: 260*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_UINT_INVSIZE]), 261*7c478bd9Sstevel@tonic-gate propinfo->size); 262*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate break; 265*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_FLOAT: 266*7c478bd9Sstevel@tonic-gate switch (propinfo->size) { 267*7c478bd9Sstevel@tonic-gate case sizeof (float): 268*7c478bd9Sstevel@tonic-gate (void) printf(" %f ", *(float *)vbuf); 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate case sizeof (double): 271*7c478bd9Sstevel@tonic-gate (void) printf(" %f ", *(double *)vbuf); 272*7c478bd9Sstevel@tonic-gate break; 273*7c478bd9Sstevel@tonic-gate default: 274*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_FLOAT_INVSIZE]), 275*7c478bd9Sstevel@tonic-gate propinfo->size); 276*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_TIMESTAMP: 280*7c478bd9Sstevel@tonic-gate val64 = *(uint64_t *)vbuf; 281*7c478bd9Sstevel@tonic-gate tmp = (time_t)val64; 282*7c478bd9Sstevel@tonic-gate if ((uint64_t)tmp != val64) { 283*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TS_OVERFLOW])); 284*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate str = ctime(&tmp); 287*7c478bd9Sstevel@tonic-gate if (str == NULL) { 288*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TS_INVALID])); 289*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate str[strlen(str) - 1] = '\0'; 292*7c478bd9Sstevel@tonic-gate (void) printf(" %s ", str); 293*7c478bd9Sstevel@tonic-gate break; 294*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_TABLE: 295*7c478bd9Sstevel@tonic-gate if (propinfo->size != sizeof (picl_prophdl_t)) { 296*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TABLE_INVSIZE]), 297*7c478bd9Sstevel@tonic-gate propinfo->size); 298*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate (void) printf("(%" PRIxPICLTBL "TBL) ", 301*7c478bd9Sstevel@tonic-gate *(picl_prophdl_t *)vbuf); 302*7c478bd9Sstevel@tonic-gate break; 303*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_REFERENCE: 304*7c478bd9Sstevel@tonic-gate if (propinfo->size != sizeof (picl_nodehdl_t)) { 305*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_REF_INVSIZE]), 306*7c478bd9Sstevel@tonic-gate propinfo->size); 307*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate (void) printf(" (%" PRIxPICLHDL "H) ", *(picl_nodehdl_t *)vbuf); 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_BYTEARRAY: 312*7c478bd9Sstevel@tonic-gate print_bytearray(lvl, vbuf, propinfo->size); 313*7c478bd9Sstevel@tonic-gate break; 314*7c478bd9Sstevel@tonic-gate default: 315*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TYPE_UNKNOWN])); 316*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate /* 322*7c478bd9Sstevel@tonic-gate * print table property value 323*7c478bd9Sstevel@tonic-gate */ 324*7c478bd9Sstevel@tonic-gate static int 325*7c478bd9Sstevel@tonic-gate print_table_prop(int lvl, picl_prophdl_t tblh) 326*7c478bd9Sstevel@tonic-gate { 327*7c478bd9Sstevel@tonic-gate picl_prophdl_t rowproph; 328*7c478bd9Sstevel@tonic-gate picl_prophdl_t colproph; 329*7c478bd9Sstevel@tonic-gate int err; 330*7c478bd9Sstevel@tonic-gate picl_propinfo_t propinfo; 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate for (err = picl_get_next_by_col(tblh, &rowproph); err != PICL_ENDOFLIST; 333*7c478bd9Sstevel@tonic-gate err = picl_get_next_by_col(rowproph, &rowproph)) { 334*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 335*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETNXTBYCOL]), 336*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 337*7c478bd9Sstevel@tonic-gate return (err); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate (void) printf("%*s %s", PROPINFO_LEFT_MARGIN(lvl), " ", 341*7c478bd9Sstevel@tonic-gate COL_DELIM); 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate for (colproph = rowproph; err != PICL_ENDOFLIST; 344*7c478bd9Sstevel@tonic-gate err = picl_get_next_by_row(colproph, &colproph)) { 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 347*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETNXTBYROW]), 348*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 349*7c478bd9Sstevel@tonic-gate return (err); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate err = picl_get_propinfo(colproph, &propinfo); 353*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 354*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]), 355*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 356*7c478bd9Sstevel@tonic-gate return (err); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate err = print_propval(lvl, colproph, &propinfo); 360*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 361*7c478bd9Sstevel@tonic-gate return (err); 362*7c478bd9Sstevel@tonic-gate (void) printf(COL_DELIM); 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * Print the properties (name = value) of a node. If an error occurs 371*7c478bd9Sstevel@tonic-gate * when printing the property value, stop. print_propval() suppresses 372*7c478bd9Sstevel@tonic-gate * errors during getting property value except for stale/invalid handle 373*7c478bd9Sstevel@tonic-gate * and no response errors. 374*7c478bd9Sstevel@tonic-gate */ 375*7c478bd9Sstevel@tonic-gate static int 376*7c478bd9Sstevel@tonic-gate print_proplist(int lvl, picl_nodehdl_t nodeh) 377*7c478bd9Sstevel@tonic-gate { 378*7c478bd9Sstevel@tonic-gate int err; 379*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 380*7c478bd9Sstevel@tonic-gate picl_propinfo_t propinfo; 381*7c478bd9Sstevel@tonic-gate picl_prophdl_t tblh; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate for (err = picl_get_first_prop(nodeh, &proph); err == PICL_SUCCESS; 384*7c478bd9Sstevel@tonic-gate err = picl_get_next_prop(proph, &proph)) { 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate err = picl_get_propinfo(proph, &propinfo); 387*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 388*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]), 389*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 390*7c478bd9Sstevel@tonic-gate return (err); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate if (propinfo.type == PICL_PTYPE_VOID) 394*7c478bd9Sstevel@tonic-gate (void) printf("%*s:%s\n", PROPINFO_LEFT_MARGIN(lvl), 395*7c478bd9Sstevel@tonic-gate " ", propinfo.name); 396*7c478bd9Sstevel@tonic-gate else { 397*7c478bd9Sstevel@tonic-gate (void) printf("%*s:%s\t", PROPINFO_LEFT_MARGIN(lvl), 398*7c478bd9Sstevel@tonic-gate " ", propinfo.name); 399*7c478bd9Sstevel@tonic-gate err = print_propval(lvl, proph, &propinfo); 400*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 401*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 402*7c478bd9Sstevel@tonic-gate return (err); 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* 406*7c478bd9Sstevel@tonic-gate * Expand the table property 407*7c478bd9Sstevel@tonic-gate */ 408*7c478bd9Sstevel@tonic-gate if (propinfo.type == PICL_PTYPE_TABLE) { 409*7c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, &tblh, propinfo.size); 410*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 411*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVAL]), 412*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 413*7c478bd9Sstevel@tonic-gate return (err); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate err = print_table_prop(lvl, tblh); 416*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 417*7c478bd9Sstevel@tonic-gate return (err); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate /* 424*7c478bd9Sstevel@tonic-gate * Recursively print the PICL tree 425*7c478bd9Sstevel@tonic-gate * When piclclass is specified, print only the nodes of that class. 426*7c478bd9Sstevel@tonic-gate */ 427*7c478bd9Sstevel@tonic-gate static int 428*7c478bd9Sstevel@tonic-gate print_tree_by_class(int lvl, picl_nodehdl_t nodeh, char *piclclass) 429*7c478bd9Sstevel@tonic-gate { 430*7c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh; 431*7c478bd9Sstevel@tonic-gate char *nameval; 432*7c478bd9Sstevel@tonic-gate char classval[PICL_PROPNAMELEN_MAX]; 433*7c478bd9Sstevel@tonic-gate int err; 434*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 435*7c478bd9Sstevel@tonic-gate picl_propinfo_t pinfo; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate /* 438*7c478bd9Sstevel@tonic-gate * First get the class name of the node to compare with piclclass 439*7c478bd9Sstevel@tonic-gate */ 440*7c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, classval, 441*7c478bd9Sstevel@tonic-gate sizeof (classval)); 442*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 443*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVALBYNAME]), 444*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 445*7c478bd9Sstevel@tonic-gate return (err); 446*7c478bd9Sstevel@tonic-gate } 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate #define MATCHING_CLASSVAL(x, y) ((x == NULL) || (strcasecmp(x, y) == 0)) 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate if (MATCHING_CLASSVAL(piclclass, classval)) { 451*7c478bd9Sstevel@tonic-gate err = picl_get_prop_by_name(nodeh, PICL_PROP_NAME, &proph); 452*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 453*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPROPBYNAME]), 454*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 455*7c478bd9Sstevel@tonic-gate return (err); 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate err = picl_get_propinfo(proph, &pinfo); 459*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 460*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]), 461*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 462*7c478bd9Sstevel@tonic-gate return (err); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate nameval = alloca(pinfo.size); 466*7c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, nameval, pinfo.size); 467*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 468*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVAL]), 469*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 470*7c478bd9Sstevel@tonic-gate return (err); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate (void) printf("%*s %s (%s, %" PRIxPICLHDL ")\n", 474*7c478bd9Sstevel@tonic-gate NODEINFO_LEFT_MARGIN(lvl), " ", nameval, classval, nodeh); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate if (verbose_mode) { 477*7c478bd9Sstevel@tonic-gate err = print_proplist(lvl, nodeh); 478*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 479*7c478bd9Sstevel@tonic-gate return (err); 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate ++lvl; 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate for (err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, &chdh, 485*7c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t)); err != PICL_PROPNOTFOUND; 486*7c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh, 487*7c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t))) { 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 490*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVALBYNAME]), 491*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 492*7c478bd9Sstevel@tonic-gate return (err); 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate err = print_tree_by_class(lvl, chdh, piclclass); 496*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 497*7c478bd9Sstevel@tonic-gate return (err); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate /* 504*7c478bd9Sstevel@tonic-gate * This program prints the PICL tree. 505*7c478bd9Sstevel@tonic-gate * If an invalid handle or stale handle is encountered while printing 506*7c478bd9Sstevel@tonic-gate * the tree, it starts over from the root node. 507*7c478bd9Sstevel@tonic-gate */ 508*7c478bd9Sstevel@tonic-gate int 509*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 510*7c478bd9Sstevel@tonic-gate { 511*7c478bd9Sstevel@tonic-gate int err; 512*7c478bd9Sstevel@tonic-gate picl_nodehdl_t rooth; 513*7c478bd9Sstevel@tonic-gate int c; 514*7c478bd9Sstevel@tonic-gate int done; 515*7c478bd9Sstevel@tonic-gate char piclclass[PICL_CLASSNAMELEN_MAX]; 516*7c478bd9Sstevel@tonic-gate int cflg; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 519*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate if ((prog = strrchr(argv[0], '/')) == NULL) 522*7c478bd9Sstevel@tonic-gate prog = argv[0]; 523*7c478bd9Sstevel@tonic-gate else 524*7c478bd9Sstevel@tonic-gate prog++; 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate cflg = 0; 527*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "vc:")) != EOF) { 528*7c478bd9Sstevel@tonic-gate switch (c) { 529*7c478bd9Sstevel@tonic-gate case 'v': 530*7c478bd9Sstevel@tonic-gate verbose_mode = 1; 531*7c478bd9Sstevel@tonic-gate break; 532*7c478bd9Sstevel@tonic-gate case 'c': 533*7c478bd9Sstevel@tonic-gate cflg = 1; 534*7c478bd9Sstevel@tonic-gate (void) strlcpy(piclclass, optarg, 535*7c478bd9Sstevel@tonic-gate PICL_CLASSNAMELEN_MAX); 536*7c478bd9Sstevel@tonic-gate break; 537*7c478bd9Sstevel@tonic-gate case '?': 538*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 539*7c478bd9Sstevel@tonic-gate default: 540*7c478bd9Sstevel@tonic-gate usage(); 541*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate if (optind != argc) 545*7c478bd9Sstevel@tonic-gate usage(); 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate err = picl_initialize(); 548*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 549*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_INIT]), picl_strerror(err)); 550*7c478bd9Sstevel@tonic-gate exit(1); 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate do { 555*7c478bd9Sstevel@tonic-gate done = 1; 556*7c478bd9Sstevel@tonic-gate err = picl_get_root(&rooth); 557*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 558*7c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETROOT]), 559*7c478bd9Sstevel@tonic-gate picl_strerror(err)); 560*7c478bd9Sstevel@tonic-gate exit(1); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate err = print_tree_by_class(ROOT_LEVEL, rooth, 564*7c478bd9Sstevel@tonic-gate (cflg ? piclclass : NULL)); 565*7c478bd9Sstevel@tonic-gate if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE)) 566*7c478bd9Sstevel@tonic-gate done = 0; 567*7c478bd9Sstevel@tonic-gate } while (!done); 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate (void) picl_shutdown(); 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate return (0); 572*7c478bd9Sstevel@tonic-gate } 573