17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*da6837b3SJustin Frank * Common Development and Distribution License (the "License").
6*da6837b3SJustin Frank * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*da6837b3SJustin Frank * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <stdarg.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <alloca.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <assert.h>
357c478bd9Sstevel@tonic-gate #include <inttypes.h>
367c478bd9Sstevel@tonic-gate #include <sys/termios.h>
377c478bd9Sstevel@tonic-gate #include <picl.h>
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate * Constant definitions and macros
417c478bd9Sstevel@tonic-gate */
427c478bd9Sstevel@tonic-gate #define COL_DELIM "|"
437c478bd9Sstevel@tonic-gate #define ROOT_LEVEL 0
447c478bd9Sstevel@tonic-gate #define LEVEL_INDENT 4
457c478bd9Sstevel@tonic-gate #define PROP_INDENT 2
467c478bd9Sstevel@tonic-gate #define NCOLS 80
477c478bd9Sstevel@tonic-gate #define NODEINFO_LEFT_MARGIN(x) (x * LEVEL_INDENT)
487c478bd9Sstevel@tonic-gate #define PROPINFO_LEFT_MARGIN(x) (x * LEVEL_INDENT + PROP_INDENT)
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate #define PRIxPICLTBL PRIx64
517c478bd9Sstevel@tonic-gate #define PRIxPICLHDL PRIx64
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate * Program variables
557c478bd9Sstevel@tonic-gate */
567c478bd9Sstevel@tonic-gate static char *prog;
577c478bd9Sstevel@tonic-gate static int verbose_mode = 0;
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate * Error codes
617c478bd9Sstevel@tonic-gate */
627c478bd9Sstevel@tonic-gate #define EM_USAGE 0
637c478bd9Sstevel@tonic-gate #define EM_INIT 1
647c478bd9Sstevel@tonic-gate #define EM_GETROOT 2
657c478bd9Sstevel@tonic-gate #define EM_GETPVAL 3
667c478bd9Sstevel@tonic-gate #define EM_GETNXTBYCOL 4
677c478bd9Sstevel@tonic-gate #define EM_GETNXTBYROW 5
687c478bd9Sstevel@tonic-gate #define EM_GETPINFO 6
697c478bd9Sstevel@tonic-gate #define EM_GETPVALBYNAME 7
707c478bd9Sstevel@tonic-gate #define EM_GETPROPBYNAME 8
717c478bd9Sstevel@tonic-gate #define EM_INT_INVSIZE 9
727c478bd9Sstevel@tonic-gate #define EM_UINT_INVSIZE 10
737c478bd9Sstevel@tonic-gate #define EM_FLOAT_INVSIZE 11
747c478bd9Sstevel@tonic-gate #define EM_TS_INVALID 12
757c478bd9Sstevel@tonic-gate #define EM_TABLE_INVSIZE 13
767c478bd9Sstevel@tonic-gate #define EM_REF_INVSIZE 14
777c478bd9Sstevel@tonic-gate #define EM_TYPE_UNKNOWN 15
787c478bd9Sstevel@tonic-gate #define EM_TS_OVERFLOW 16
79*da6837b3SJustin Frank #define EM_TS_INVSIZE 17
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate /*
827c478bd9Sstevel@tonic-gate * Error mesage texts
837c478bd9Sstevel@tonic-gate */
847c478bd9Sstevel@tonic-gate static char *err_msg[] = {
857c478bd9Sstevel@tonic-gate /* program usage */
867c478bd9Sstevel@tonic-gate "Usage: %s [-v] [-c <picl_class>]\n", /* 0 */
877c478bd9Sstevel@tonic-gate /* picl call failed messages */
887c478bd9Sstevel@tonic-gate "picl_initialize failed: %s\n", /* 1 */
897c478bd9Sstevel@tonic-gate "picl_get_root failed: %s\n", /* 2 */
907c478bd9Sstevel@tonic-gate "picl_get_propval failed: %s\n", /* 3 */
917c478bd9Sstevel@tonic-gate "picl_get_next_by_col failed: %s\n", /* 4 */
927c478bd9Sstevel@tonic-gate "picl_get_next_by_row failed: %s\n", /* 5 */
937c478bd9Sstevel@tonic-gate "picl_get_propinfo failed: %s\n", /* 6 */
947c478bd9Sstevel@tonic-gate "picl_get_propval_by_name failed: %s\n", /* 7 */
957c478bd9Sstevel@tonic-gate "picl_get_prop_by_name failed: %s\n", /* 8 */
967c478bd9Sstevel@tonic-gate /* invalid data error messages */
977c478bd9Sstevel@tonic-gate "picl_get_propval: invalid int size %d\n", /* 9 */
987c478bd9Sstevel@tonic-gate "picl_get_propval: invalid unsigned int size %d\n", /* 10 */
997c478bd9Sstevel@tonic-gate "picl_get_propval: invalid float size %d\n", /* 11 */
1007c478bd9Sstevel@tonic-gate "picl_get_propval: invalid timestamp\n", /* 12 */
1017c478bd9Sstevel@tonic-gate "picl_get_propval: invalid table handle size %d\n", /* 13 */
1027c478bd9Sstevel@tonic-gate "picl_get_propval: invalid reference size %d\n", /* 14 */
1037c478bd9Sstevel@tonic-gate "picl_get_propval: unknown type\n", /* 15 */
104*da6837b3SJustin Frank "picl_get_propval: timestamp value too large\n", /* 16 */
105*da6837b3SJustin Frank "picl_get_propval: invalid timestamp size\n" /* 17 */
1067c478bd9Sstevel@tonic-gate };
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
1097c478bd9Sstevel@tonic-gate static void
print_errmsg(char * message,...)1107c478bd9Sstevel@tonic-gate print_errmsg(char *message, ...)
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate va_list ap;
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate va_start(ap, message);
1157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", prog);
1167c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, message, ap);
1177c478bd9Sstevel@tonic-gate va_end(ap);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate * Print prtpicl usage
1227c478bd9Sstevel@tonic-gate */
1237c478bd9Sstevel@tonic-gate static void
usage(void)1247c478bd9Sstevel@tonic-gate usage(void)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_USAGE]), prog);
1277c478bd9Sstevel@tonic-gate exit(1);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate /*
1317c478bd9Sstevel@tonic-gate * print a bytearray value and format it to fit in 80 columns
1327c478bd9Sstevel@tonic-gate */
1337c478bd9Sstevel@tonic-gate static void
print_bytearray(int lvl,uint8_t * vbuf,size_t nbytes)1347c478bd9Sstevel@tonic-gate print_bytearray(int lvl, uint8_t *vbuf, size_t nbytes)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate int cnum;
1377c478bd9Sstevel@tonic-gate int columns;
1387c478bd9Sstevel@tonic-gate char *s;
1397c478bd9Sstevel@tonic-gate struct winsize winsize;
1407c478bd9Sstevel@tonic-gate size_t i;
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate * The COLUMNS_PER_BYTE is set to 4 to match the printf
1447c478bd9Sstevel@tonic-gate * format used below, i.e. " %02x ", to print a byte
1457c478bd9Sstevel@tonic-gate */
1467c478bd9Sstevel@tonic-gate #define COLUMNS_PER_BYTE 4
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate * Kind of a hack to determine the width of the output...
1507c478bd9Sstevel@tonic-gate */
1517c478bd9Sstevel@tonic-gate columns = NCOLS;
1527c478bd9Sstevel@tonic-gate if ((s = getenv("COLUMNS")) != NULL && (cnum = atoi(s)) > 0)
1537c478bd9Sstevel@tonic-gate columns = cnum;
1547c478bd9Sstevel@tonic-gate else if (isatty(fileno(stdout)) &&
1557c478bd9Sstevel@tonic-gate ioctl(fileno(stdout), TIOCGWINSZ, &winsize) == 0 &&
1567c478bd9Sstevel@tonic-gate winsize.ws_col != 0)
1577c478bd9Sstevel@tonic-gate columns = winsize.ws_col;
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate cnum = PROPINFO_LEFT_MARGIN(lvl);
1617c478bd9Sstevel@tonic-gate if ((nbytes * COLUMNS_PER_BYTE + cnum) > columns) {
1627c478bd9Sstevel@tonic-gate (void) printf("\n");
1637c478bd9Sstevel@tonic-gate cnum = 0;
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate for (i = 0; i < nbytes; ++i) {
1667c478bd9Sstevel@tonic-gate if (cnum > columns - COLUMNS_PER_BYTE) {
1677c478bd9Sstevel@tonic-gate (void) printf("\n");
1687c478bd9Sstevel@tonic-gate cnum = 0;
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate (void) printf(" %02x ", vbuf[i]);
1717c478bd9Sstevel@tonic-gate cnum += COLUMNS_PER_BYTE;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate * Print a property's value
1777c478bd9Sstevel@tonic-gate * If the property is read protected, return success.
1787c478bd9Sstevel@tonic-gate * If an invalid/stale handle error is encountered, return the error. For
1797c478bd9Sstevel@tonic-gate * other errors, print a message and return success.
1807c478bd9Sstevel@tonic-gate */
1817c478bd9Sstevel@tonic-gate static int
print_propval(int lvl,picl_prophdl_t proph,const picl_propinfo_t * propinfo)1827c478bd9Sstevel@tonic-gate print_propval(int lvl, picl_prophdl_t proph, const picl_propinfo_t *propinfo)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate int err;
1857c478bd9Sstevel@tonic-gate void *vbuf;
1867c478bd9Sstevel@tonic-gate char *str;
1877c478bd9Sstevel@tonic-gate uint64_t val64;
1887c478bd9Sstevel@tonic-gate time_t tmp;
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate * If property is read protected, print a message and continue
1927c478bd9Sstevel@tonic-gate */
1937c478bd9Sstevel@tonic-gate if (!(propinfo->accessmode & PICL_READ)) {
1947c478bd9Sstevel@tonic-gate (void) printf("<%s>", gettext("WRITE-ONLY"));
1957c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate vbuf = alloca(propinfo->size);
1997c478bd9Sstevel@tonic-gate if (propinfo->type == PICL_PTYPE_VOID)
2007c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, vbuf, propinfo->size);
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate * If the error is not a stale/invalid handle or noresponse, continue
2057c478bd9Sstevel@tonic-gate * by ignoring the error/skipping the property.
2067c478bd9Sstevel@tonic-gate */
2077c478bd9Sstevel@tonic-gate if ((err == PICL_INVALIDHANDLE) || (err == PICL_STALEHANDLE) ||
2087c478bd9Sstevel@tonic-gate (err == PICL_NORESPONSE))
2097c478bd9Sstevel@tonic-gate return (err);
2107c478bd9Sstevel@tonic-gate else if (err != PICL_SUCCESS) {
2117c478bd9Sstevel@tonic-gate (void) printf("<%s: %s>", gettext("ERROR"), picl_strerror(err));
2127c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate switch (propinfo->type) {
2167c478bd9Sstevel@tonic-gate case PICL_PTYPE_CHARSTRING:
217*da6837b3SJustin Frank if (propinfo->size > 0)
2187c478bd9Sstevel@tonic-gate (void) printf(" %s ", (char *)vbuf);
2197c478bd9Sstevel@tonic-gate break;
2207c478bd9Sstevel@tonic-gate case PICL_PTYPE_INT:
2217c478bd9Sstevel@tonic-gate switch (propinfo->size) {
2227c478bd9Sstevel@tonic-gate case sizeof (int8_t):
2237c478bd9Sstevel@tonic-gate /* avoid using PRId8 until lint recognizes hh */
2247c478bd9Sstevel@tonic-gate (void) printf(" %d ", *(int8_t *)vbuf);
2257c478bd9Sstevel@tonic-gate break;
2267c478bd9Sstevel@tonic-gate case sizeof (int16_t):
2277c478bd9Sstevel@tonic-gate (void) printf(" %" PRId16 " ", *(int16_t *)vbuf);
2287c478bd9Sstevel@tonic-gate break;
2297c478bd9Sstevel@tonic-gate case sizeof (int32_t):
2307c478bd9Sstevel@tonic-gate (void) printf(" %" PRId32 " ", *(int32_t *)vbuf);
2317c478bd9Sstevel@tonic-gate break;
2327c478bd9Sstevel@tonic-gate case sizeof (int64_t):
2337c478bd9Sstevel@tonic-gate (void) printf(" %" PRId64 " ", *(int64_t *)vbuf);
2347c478bd9Sstevel@tonic-gate break;
2357c478bd9Sstevel@tonic-gate default:
2367c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_INT_INVSIZE]),
2377c478bd9Sstevel@tonic-gate propinfo->size);
2387c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate break;
2417c478bd9Sstevel@tonic-gate case PICL_PTYPE_UNSIGNED_INT:
2427c478bd9Sstevel@tonic-gate switch (propinfo->size) {
2437c478bd9Sstevel@tonic-gate case sizeof (uint8_t):
2447c478bd9Sstevel@tonic-gate /* avoid using PRIx8 until lint recognizes hh */
2457c478bd9Sstevel@tonic-gate (void) printf(" %#x ", *(uint8_t *)vbuf);
2467c478bd9Sstevel@tonic-gate break;
2477c478bd9Sstevel@tonic-gate case sizeof (uint16_t):
2487c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx16 " ", *(uint16_t *)vbuf);
2497c478bd9Sstevel@tonic-gate break;
2507c478bd9Sstevel@tonic-gate case sizeof (uint32_t):
2517c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx32 " ", *(uint32_t *)vbuf);
2527c478bd9Sstevel@tonic-gate break;
2537c478bd9Sstevel@tonic-gate case sizeof (uint64_t):
2547c478bd9Sstevel@tonic-gate (void) printf(" %#" PRIx64 " ", *(uint64_t *)vbuf);
2557c478bd9Sstevel@tonic-gate break;
2567c478bd9Sstevel@tonic-gate default:
2577c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_UINT_INVSIZE]),
2587c478bd9Sstevel@tonic-gate propinfo->size);
2597c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate break;
2627c478bd9Sstevel@tonic-gate case PICL_PTYPE_FLOAT:
2637c478bd9Sstevel@tonic-gate switch (propinfo->size) {
2647c478bd9Sstevel@tonic-gate case sizeof (float):
2657c478bd9Sstevel@tonic-gate (void) printf(" %f ", *(float *)vbuf);
2667c478bd9Sstevel@tonic-gate break;
2677c478bd9Sstevel@tonic-gate case sizeof (double):
2687c478bd9Sstevel@tonic-gate (void) printf(" %f ", *(double *)vbuf);
2697c478bd9Sstevel@tonic-gate break;
2707c478bd9Sstevel@tonic-gate default:
2717c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_FLOAT_INVSIZE]),
2727c478bd9Sstevel@tonic-gate propinfo->size);
2737c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate break;
2767c478bd9Sstevel@tonic-gate case PICL_PTYPE_TIMESTAMP:
277*da6837b3SJustin Frank if (propinfo->size != sizeof (val64)) {
278*da6837b3SJustin Frank print_errmsg(gettext(err_msg[EM_TS_INVSIZE]));
279*da6837b3SJustin Frank return (PICL_FAILURE);
280*da6837b3SJustin Frank }
2817c478bd9Sstevel@tonic-gate val64 = *(uint64_t *)vbuf;
2827c478bd9Sstevel@tonic-gate tmp = (time_t)val64;
2837c478bd9Sstevel@tonic-gate if ((uint64_t)tmp != val64) {
2847c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TS_OVERFLOW]));
2857c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate str = ctime(&tmp);
2887c478bd9Sstevel@tonic-gate if (str == NULL) {
2897c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TS_INVALID]));
2907c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate str[strlen(str) - 1] = '\0';
2937c478bd9Sstevel@tonic-gate (void) printf(" %s ", str);
2947c478bd9Sstevel@tonic-gate break;
2957c478bd9Sstevel@tonic-gate case PICL_PTYPE_TABLE:
2967c478bd9Sstevel@tonic-gate if (propinfo->size != sizeof (picl_prophdl_t)) {
2977c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TABLE_INVSIZE]),
2987c478bd9Sstevel@tonic-gate propinfo->size);
2997c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate (void) printf("(%" PRIxPICLTBL "TBL) ",
3027c478bd9Sstevel@tonic-gate *(picl_prophdl_t *)vbuf);
3037c478bd9Sstevel@tonic-gate break;
3047c478bd9Sstevel@tonic-gate case PICL_PTYPE_REFERENCE:
3057c478bd9Sstevel@tonic-gate if (propinfo->size != sizeof (picl_nodehdl_t)) {
3067c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_REF_INVSIZE]),
3077c478bd9Sstevel@tonic-gate propinfo->size);
3087c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate (void) printf(" (%" PRIxPICLHDL "H) ", *(picl_nodehdl_t *)vbuf);
3117c478bd9Sstevel@tonic-gate break;
3127c478bd9Sstevel@tonic-gate case PICL_PTYPE_BYTEARRAY:
313*da6837b3SJustin Frank if (propinfo->size > 0)
3147c478bd9Sstevel@tonic-gate print_bytearray(lvl, vbuf, propinfo->size);
3157c478bd9Sstevel@tonic-gate break;
3167c478bd9Sstevel@tonic-gate default:
3177c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_TYPE_UNKNOWN]));
3187c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate /*
3247c478bd9Sstevel@tonic-gate * print table property value
3257c478bd9Sstevel@tonic-gate */
3267c478bd9Sstevel@tonic-gate static int
print_table_prop(int lvl,picl_prophdl_t tblh)3277c478bd9Sstevel@tonic-gate print_table_prop(int lvl, picl_prophdl_t tblh)
3287c478bd9Sstevel@tonic-gate {
3297c478bd9Sstevel@tonic-gate picl_prophdl_t rowproph;
3307c478bd9Sstevel@tonic-gate picl_prophdl_t colproph;
3317c478bd9Sstevel@tonic-gate int err;
3327c478bd9Sstevel@tonic-gate picl_propinfo_t propinfo;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate for (err = picl_get_next_by_col(tblh, &rowproph); err != PICL_ENDOFLIST;
3357c478bd9Sstevel@tonic-gate err = picl_get_next_by_col(rowproph, &rowproph)) {
3367c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
3377c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETNXTBYCOL]),
3387c478bd9Sstevel@tonic-gate picl_strerror(err));
3397c478bd9Sstevel@tonic-gate return (err);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate (void) printf("%*s %s", PROPINFO_LEFT_MARGIN(lvl), " ",
3437c478bd9Sstevel@tonic-gate COL_DELIM);
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate for (colproph = rowproph; err != PICL_ENDOFLIST;
3467c478bd9Sstevel@tonic-gate err = picl_get_next_by_row(colproph, &colproph)) {
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
3497c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETNXTBYROW]),
3507c478bd9Sstevel@tonic-gate picl_strerror(err));
3517c478bd9Sstevel@tonic-gate return (err);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate err = picl_get_propinfo(colproph, &propinfo);
3557c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
3567c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]),
3577c478bd9Sstevel@tonic-gate picl_strerror(err));
3587c478bd9Sstevel@tonic-gate return (err);
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate err = print_propval(lvl, colproph, &propinfo);
3627c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
3637c478bd9Sstevel@tonic-gate return (err);
3647c478bd9Sstevel@tonic-gate (void) printf(COL_DELIM);
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate (void) printf("\n");
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate /*
3727c478bd9Sstevel@tonic-gate * Print the properties (name = value) of a node. If an error occurs
3737c478bd9Sstevel@tonic-gate * when printing the property value, stop. print_propval() suppresses
3747c478bd9Sstevel@tonic-gate * errors during getting property value except for stale/invalid handle
3757c478bd9Sstevel@tonic-gate * and no response errors.
3767c478bd9Sstevel@tonic-gate */
3777c478bd9Sstevel@tonic-gate static int
print_proplist(int lvl,picl_nodehdl_t nodeh)3787c478bd9Sstevel@tonic-gate print_proplist(int lvl, picl_nodehdl_t nodeh)
3797c478bd9Sstevel@tonic-gate {
3807c478bd9Sstevel@tonic-gate int err;
3817c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
3827c478bd9Sstevel@tonic-gate picl_propinfo_t propinfo;
3837c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate for (err = picl_get_first_prop(nodeh, &proph); err == PICL_SUCCESS;
3867c478bd9Sstevel@tonic-gate err = picl_get_next_prop(proph, &proph)) {
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate err = picl_get_propinfo(proph, &propinfo);
3897c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
3907c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]),
3917c478bd9Sstevel@tonic-gate picl_strerror(err));
3927c478bd9Sstevel@tonic-gate return (err);
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate if (propinfo.type == PICL_PTYPE_VOID)
3967c478bd9Sstevel@tonic-gate (void) printf("%*s:%s\n", PROPINFO_LEFT_MARGIN(lvl),
3977c478bd9Sstevel@tonic-gate " ", propinfo.name);
3987c478bd9Sstevel@tonic-gate else {
3997c478bd9Sstevel@tonic-gate (void) printf("%*s:%s\t", PROPINFO_LEFT_MARGIN(lvl),
4007c478bd9Sstevel@tonic-gate " ", propinfo.name);
4017c478bd9Sstevel@tonic-gate err = print_propval(lvl, proph, &propinfo);
4027c478bd9Sstevel@tonic-gate (void) printf("\n");
4037c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
4047c478bd9Sstevel@tonic-gate return (err);
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate
4077c478bd9Sstevel@tonic-gate /*
4087c478bd9Sstevel@tonic-gate * Expand the table property
4097c478bd9Sstevel@tonic-gate */
4107c478bd9Sstevel@tonic-gate if (propinfo.type == PICL_PTYPE_TABLE) {
4117c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, &tblh, propinfo.size);
4127c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4137c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVAL]),
4147c478bd9Sstevel@tonic-gate picl_strerror(err));
4157c478bd9Sstevel@tonic-gate return (err);
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate err = print_table_prop(lvl, tblh);
4187c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
4197c478bd9Sstevel@tonic-gate return (err);
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate /*
4267c478bd9Sstevel@tonic-gate * Recursively print the PICL tree
4277c478bd9Sstevel@tonic-gate * When piclclass is specified, print only the nodes of that class.
4287c478bd9Sstevel@tonic-gate */
4297c478bd9Sstevel@tonic-gate static int
print_tree_by_class(int lvl,picl_nodehdl_t nodeh,char * piclclass)4307c478bd9Sstevel@tonic-gate print_tree_by_class(int lvl, picl_nodehdl_t nodeh, char *piclclass)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
4337c478bd9Sstevel@tonic-gate char *nameval;
4347c478bd9Sstevel@tonic-gate char classval[PICL_PROPNAMELEN_MAX];
4357c478bd9Sstevel@tonic-gate int err;
4367c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
4377c478bd9Sstevel@tonic-gate picl_propinfo_t pinfo;
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate /*
4407c478bd9Sstevel@tonic-gate * First get the class name of the node to compare with piclclass
4417c478bd9Sstevel@tonic-gate */
4427c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, classval,
4437c478bd9Sstevel@tonic-gate sizeof (classval));
4447c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4457c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVALBYNAME]),
4467c478bd9Sstevel@tonic-gate picl_strerror(err));
4477c478bd9Sstevel@tonic-gate return (err);
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate
4507c478bd9Sstevel@tonic-gate #define MATCHING_CLASSVAL(x, y) ((x == NULL) || (strcasecmp(x, y) == 0))
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate if (MATCHING_CLASSVAL(piclclass, classval)) {
4537c478bd9Sstevel@tonic-gate err = picl_get_prop_by_name(nodeh, PICL_PROP_NAME, &proph);
4547c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4557c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPROPBYNAME]),
4567c478bd9Sstevel@tonic-gate picl_strerror(err));
4577c478bd9Sstevel@tonic-gate return (err);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate err = picl_get_propinfo(proph, &pinfo);
4617c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4627c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPINFO]),
4637c478bd9Sstevel@tonic-gate picl_strerror(err));
4647c478bd9Sstevel@tonic-gate return (err);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate nameval = alloca(pinfo.size);
4687c478bd9Sstevel@tonic-gate err = picl_get_propval(proph, nameval, pinfo.size);
4697c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4707c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVAL]),
4717c478bd9Sstevel@tonic-gate picl_strerror(err));
4727c478bd9Sstevel@tonic-gate return (err);
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate (void) printf("%*s %s (%s, %" PRIxPICLHDL ")\n",
4767c478bd9Sstevel@tonic-gate NODEINFO_LEFT_MARGIN(lvl), " ", nameval, classval, nodeh);
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate if (verbose_mode) {
4797c478bd9Sstevel@tonic-gate err = print_proplist(lvl, nodeh);
4807c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
4817c478bd9Sstevel@tonic-gate return (err);
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate ++lvl;
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate for (err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, &chdh,
4877c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t)); err != PICL_PROPNOTFOUND;
4887c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
4897c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t))) {
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
4927c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETPVALBYNAME]),
4937c478bd9Sstevel@tonic-gate picl_strerror(err));
4947c478bd9Sstevel@tonic-gate return (err);
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate err = print_tree_by_class(lvl, chdh, piclclass);
4987c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
4997c478bd9Sstevel@tonic-gate return (err);
5007c478bd9Sstevel@tonic-gate }
5017c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate /*
5067c478bd9Sstevel@tonic-gate * This program prints the PICL tree.
5077c478bd9Sstevel@tonic-gate * If an invalid handle or stale handle is encountered while printing
5087c478bd9Sstevel@tonic-gate * the tree, it starts over from the root node.
5097c478bd9Sstevel@tonic-gate */
5107c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)5117c478bd9Sstevel@tonic-gate main(int argc, char **argv)
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate int err;
5147c478bd9Sstevel@tonic-gate picl_nodehdl_t rooth;
5157c478bd9Sstevel@tonic-gate int c;
5167c478bd9Sstevel@tonic-gate int done;
5177c478bd9Sstevel@tonic-gate char piclclass[PICL_CLASSNAMELEN_MAX];
5187c478bd9Sstevel@tonic-gate int cflg;
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
5217c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate if ((prog = strrchr(argv[0], '/')) == NULL)
5247c478bd9Sstevel@tonic-gate prog = argv[0];
5257c478bd9Sstevel@tonic-gate else
5267c478bd9Sstevel@tonic-gate prog++;
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate cflg = 0;
5297c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "vc:")) != EOF) {
5307c478bd9Sstevel@tonic-gate switch (c) {
5317c478bd9Sstevel@tonic-gate case 'v':
5327c478bd9Sstevel@tonic-gate verbose_mode = 1;
5337c478bd9Sstevel@tonic-gate break;
5347c478bd9Sstevel@tonic-gate case 'c':
5357c478bd9Sstevel@tonic-gate cflg = 1;
5367c478bd9Sstevel@tonic-gate (void) strlcpy(piclclass, optarg,
5377c478bd9Sstevel@tonic-gate PICL_CLASSNAMELEN_MAX);
5387c478bd9Sstevel@tonic-gate break;
5397c478bd9Sstevel@tonic-gate case '?':
5407c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
5417c478bd9Sstevel@tonic-gate default:
5427c478bd9Sstevel@tonic-gate usage();
5437c478bd9Sstevel@tonic-gate /*NOTREACHED*/
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate }
5467c478bd9Sstevel@tonic-gate if (optind != argc)
5477c478bd9Sstevel@tonic-gate usage();
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate err = picl_initialize();
5507c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
5517c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_INIT]), picl_strerror(err));
5527c478bd9Sstevel@tonic-gate exit(1);
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate
5557c478bd9Sstevel@tonic-gate
5567c478bd9Sstevel@tonic-gate do {
5577c478bd9Sstevel@tonic-gate done = 1;
5587c478bd9Sstevel@tonic-gate err = picl_get_root(&rooth);
5597c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
5607c478bd9Sstevel@tonic-gate print_errmsg(gettext(err_msg[EM_GETROOT]),
5617c478bd9Sstevel@tonic-gate picl_strerror(err));
5627c478bd9Sstevel@tonic-gate exit(1);
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate err = print_tree_by_class(ROOT_LEVEL, rooth,
5667c478bd9Sstevel@tonic-gate (cflg ? piclclass : NULL));
5677c478bd9Sstevel@tonic-gate if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE))
5687c478bd9Sstevel@tonic-gate done = 0;
5697c478bd9Sstevel@tonic-gate } while (!done);
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate (void) picl_shutdown();
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate return (0);
5747c478bd9Sstevel@tonic-gate }
575