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 506e46062Sjbeloro * Common Development and Distribution License (the "License"). 606e46062Sjbeloro * 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 */ 2106e46062Sjbeloro 227c478bd9Sstevel@tonic-gate /* 23*821a83dbSps154918 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <limits.h> 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <string.h> 337c478bd9Sstevel@tonic-gate #include <libintl.h> 347c478bd9Sstevel@tonic-gate #include <libfru.h> 357c478bd9Sstevel@tonic-gate #include <errno.h> 367c478bd9Sstevel@tonic-gate #include <math.h> 377c478bd9Sstevel@tonic-gate #include <alloca.h> 387c478bd9Sstevel@tonic-gate #include <assert.h> 397c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define NUM_OF_SEGMENT 1 427c478bd9Sstevel@tonic-gate #define SEGMENT_NAME_SIZE 2 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #define FD_SEGMENT_SIZE 2949 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate static char *command, *customer_data = NULL, *frupath = NULL, **svcargv; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /* DataElement supported in the customer operation */ 497c478bd9Sstevel@tonic-gate static char *cust_data_list[] = {"Customer_DataR"}; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* DataElement supported in the service operation */ 527c478bd9Sstevel@tonic-gate static char *serv_data_list[] = {"InstallationR", "ECO_CurrentR"}; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* currently supported segment name */ 557c478bd9Sstevel@tonic-gate static char *segment_name[] = {"FD"}; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static int found_frupath = 0, list_only = 0, recursive = 0, 587c478bd9Sstevel@tonic-gate service_mode = 0, svcargc, update = 0; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static void 627c478bd9Sstevel@tonic-gate usage(void) 637c478bd9Sstevel@tonic-gate { 647c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 657c478bd9Sstevel@tonic-gate gettext("Usage: %s [ -l ] | [ [ -r ] frupath [ text ] ]\n"), 667c478bd9Sstevel@tonic-gate command); 677c478bd9Sstevel@tonic-gate } 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static int 707c478bd9Sstevel@tonic-gate validate_fieldnames(int argc, char *argv[]) 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate static int num = sizeof (serv_data_list)/sizeof (*serv_data_list); 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate char *fieldname; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate int i, j, match, status; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate fru_elemdef_t definition; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i += 2) { 827c478bd9Sstevel@tonic-gate if (argv[i][0] == '/') { 837c478bd9Sstevel@tonic-gate fieldname = &argv[i][1]; 847c478bd9Sstevel@tonic-gate } else { 857c478bd9Sstevel@tonic-gate fieldname = &argv[i][0]; 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate match = 0; 897c478bd9Sstevel@tonic-gate for (j = 0; j < num; j++) { 907c478bd9Sstevel@tonic-gate if (strncmp(fieldname, serv_data_list[j], 917c478bd9Sstevel@tonic-gate strlen(serv_data_list[j])) == 0) { 927c478bd9Sstevel@tonic-gate match = 1; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate if (!match) { 967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 977c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a supported field\n"), 987c478bd9Sstevel@tonic-gate argv[i]); 997c478bd9Sstevel@tonic-gate return (1); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate if ((status = fru_get_definition(argv[i], &definition)) 1037c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 1047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("\"%s\": %s\n"), 1057c478bd9Sstevel@tonic-gate argv[i], 1067c478bd9Sstevel@tonic-gate fru_strerror(status)); 1077c478bd9Sstevel@tonic-gate return (1); 1087c478bd9Sstevel@tonic-gate } else if ((definition.data_type == FDTYPE_Record) || 1097c478bd9Sstevel@tonic-gate (definition.data_type == FDTYPE_UNDEFINED)) { 1107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1117c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a field\n"), argv[i]); 1127c478bd9Sstevel@tonic-gate return (1); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate return (0); 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate static int 1207c478bd9Sstevel@tonic-gate pathmatch(const char *path) 1217c478bd9Sstevel@tonic-gate { 1227c478bd9Sstevel@tonic-gate char *match; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate if ((frupath != NULL) && 1257c478bd9Sstevel@tonic-gate ((match = strstr(path, frupath)) != NULL) && 1267c478bd9Sstevel@tonic-gate ((match + strlen(frupath)) == (path + strlen(path))) && 1277c478bd9Sstevel@tonic-gate ((match == path) || (*(match - 1) == '/'))) { 1287c478bd9Sstevel@tonic-gate found_frupath = 1; 1297c478bd9Sstevel@tonic-gate return (1); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate return (0); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate static void 1357c478bd9Sstevel@tonic-gate displayBinary(unsigned char *data, size_t length, fru_elemdef_t *def) 1367c478bd9Sstevel@tonic-gate { 1377c478bd9Sstevel@tonic-gate int i = 0; 1387c478bd9Sstevel@tonic-gate uint64_t lldata; 1397c478bd9Sstevel@tonic-gate uint64_t mask; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate if (def->disp_type == FDISP_Hex) { 1427c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 1437c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate return; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate (void) memcpy(&lldata, data, sizeof (lldata)); 1497c478bd9Sstevel@tonic-gate switch (def->disp_type) { 1507c478bd9Sstevel@tonic-gate case FDISP_Binary: 1517c478bd9Sstevel@tonic-gate { 15234e5f34eSkmohan mask = 0x8000000000000000ULL; 1537c478bd9Sstevel@tonic-gate for (i = 0; i < (sizeof (uint64_t) *8); i++) { 1547c478bd9Sstevel@tonic-gate if (lldata & (mask >> i)) { 1557c478bd9Sstevel@tonic-gate (void) printf("1"); 1567c478bd9Sstevel@tonic-gate } else { 1577c478bd9Sstevel@tonic-gate (void) printf("0"); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate return; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate case FDISP_Octal: 1637c478bd9Sstevel@tonic-gate { 1647c478bd9Sstevel@tonic-gate (void) printf("%llo", lldata); 1657c478bd9Sstevel@tonic-gate return; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate case FDISP_Decimal: 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate (void) printf("%lld", lldata); 1707c478bd9Sstevel@tonic-gate return; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate case FDISP_Time: 1737c478bd9Sstevel@tonic-gate { 1747c478bd9Sstevel@tonic-gate char buffer[PATH_MAX]; 1757c478bd9Sstevel@tonic-gate time_t time; 1767c478bd9Sstevel@tonic-gate time = (time_t)lldata; 1777c478bd9Sstevel@tonic-gate (void) strftime(buffer, PATH_MAX, "%C", 1787c478bd9Sstevel@tonic-gate localtime(&time)); 1797c478bd9Sstevel@tonic-gate (void) printf("%s", buffer); 1807c478bd9Sstevel@tonic-gate return; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate static void 1867c478bd9Sstevel@tonic-gate displayBAasBinary(unsigned char *data, size_t length) 1877c478bd9Sstevel@tonic-gate { 1887c478bd9Sstevel@tonic-gate int i; 1897c478bd9Sstevel@tonic-gate unsigned char mask; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 1927c478bd9Sstevel@tonic-gate /* 1937c478bd9Sstevel@tonic-gate * make a mask for the high order bit and adjust down through 1947c478bd9Sstevel@tonic-gate * all the bits. 1957c478bd9Sstevel@tonic-gate */ 1967c478bd9Sstevel@tonic-gate for (mask = 0x80; mask > 0; mask /= 2) { 1977c478bd9Sstevel@tonic-gate if ((data[i] & mask) != 0) /* bit must be on */ 1987c478bd9Sstevel@tonic-gate (void) printf("1"); 1997c478bd9Sstevel@tonic-gate else /* bit is off... */ 2007c478bd9Sstevel@tonic-gate (void) printf("0"); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate (void) printf("\n"); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate static void 2077c478bd9Sstevel@tonic-gate display_data(unsigned char *data, size_t length, fru_elemdef_t *def) 2087c478bd9Sstevel@tonic-gate { 2097c478bd9Sstevel@tonic-gate int i = 0; 2107c478bd9Sstevel@tonic-gate uint64_t lldata; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate if (data == 0x00) { 2137c478bd9Sstevel@tonic-gate (void) printf("\n"); 2147c478bd9Sstevel@tonic-gate return; 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate switch (def->data_type) { 2187c478bd9Sstevel@tonic-gate case FDTYPE_Binary: 2197c478bd9Sstevel@tonic-gate { 2207c478bd9Sstevel@tonic-gate displayBinary(data, length, def); 2217c478bd9Sstevel@tonic-gate return; 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate case FDTYPE_ByteArray: 2257c478bd9Sstevel@tonic-gate { 2267c478bd9Sstevel@tonic-gate switch (def->disp_type) { 2277c478bd9Sstevel@tonic-gate case FDISP_Binary: 2287c478bd9Sstevel@tonic-gate displayBAasBinary(data, length); 2297c478bd9Sstevel@tonic-gate return; 2307c478bd9Sstevel@tonic-gate case FDISP_Hex: 2317c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 2327c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate return; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate case FDTYPE_Unicode: 2397c478bd9Sstevel@tonic-gate assert(gettext("Unicode not yet supported") == 0); 2407c478bd9Sstevel@tonic-gate break; 2417c478bd9Sstevel@tonic-gate case FDTYPE_ASCII: 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate char *disp_str = (char *)alloca(length+1); 2447c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) 2457c478bd9Sstevel@tonic-gate disp_str[i] = data[i]; 2467c478bd9Sstevel@tonic-gate disp_str[i] = '\0'; 2477c478bd9Sstevel@tonic-gate (void) printf("%s", disp_str); 2487c478bd9Sstevel@tonic-gate return; 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate case FDTYPE_Enumeration: 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate lldata = strtoull((const char *)data, NULL, 0); 2547c478bd9Sstevel@tonic-gate for (i = 0; i < def->enum_count; i++) { 2557c478bd9Sstevel@tonic-gate if (def->enum_table[i].value == lldata) { 2567c478bd9Sstevel@tonic-gate /* strdup such that map_... can realloc if necessary. */ 2577c478bd9Sstevel@tonic-gate char *tmp = strdup(def->enum_table[i].text); 2587c478bd9Sstevel@tonic-gate (void) printf("%s", tmp); 2597c478bd9Sstevel@tonic-gate free(tmp); 2607c478bd9Sstevel@tonic-gate return; 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate (void) printf(gettext("Unrecognized Value: 0x")); 2647c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (uint64_t); i++) 2657c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 2667c478bd9Sstevel@tonic-gate break; 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate default: 2697c478bd9Sstevel@tonic-gate break; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate static void 2747c478bd9Sstevel@tonic-gate print_node_data(fru_nodehdl_t cont_hdl) 2757c478bd9Sstevel@tonic-gate { 2767c478bd9Sstevel@tonic-gate int iter_cnt = 0; 2777c478bd9Sstevel@tonic-gate int iter; 2787c478bd9Sstevel@tonic-gate int numseg; 2797c478bd9Sstevel@tonic-gate int list_cnt; 2807c478bd9Sstevel@tonic-gate unsigned char *data; 2817c478bd9Sstevel@tonic-gate size_t dataLen; 2827c478bd9Sstevel@tonic-gate int total_cnt; 2837c478bd9Sstevel@tonic-gate char *found_path = NULL; 2847c478bd9Sstevel@tonic-gate fru_elemdef_t def, def1; 2857c478bd9Sstevel@tonic-gate int instance = 0; 2867c478bd9Sstevel@tonic-gate char **ptr; 2877c478bd9Sstevel@tonic-gate char **tmp_ptr; 2887c478bd9Sstevel@tonic-gate int count = 0; 2897c478bd9Sstevel@tonic-gate char elem_name[PATH_MAX]; 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate if (service_mode) { 2927c478bd9Sstevel@tonic-gate total_cnt = sizeof (serv_data_list)/sizeof (*serv_data_list); 2937c478bd9Sstevel@tonic-gate ptr = serv_data_list; 2947c478bd9Sstevel@tonic-gate } else { 2957c478bd9Sstevel@tonic-gate total_cnt = sizeof (cust_data_list)/sizeof (*cust_data_list); 2967c478bd9Sstevel@tonic-gate ptr = cust_data_list; 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate tmp_ptr = ptr; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate for (numseg = 0; numseg < NUM_OF_SEGMENT; numseg++) { 3017c478bd9Sstevel@tonic-gate ptr = tmp_ptr; 3027c478bd9Sstevel@tonic-gate for (list_cnt = 0; list_cnt < total_cnt; list_cnt++) { 3037c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) != FRU_SUCCESS) { 3047c478bd9Sstevel@tonic-gate continue; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate if ((fru_get_num_iterations(cont_hdl, 3077c478bd9Sstevel@tonic-gate &segment_name[numseg], 0, *ptr, 3087c478bd9Sstevel@tonic-gate &iter_cnt, NULL)) != FRU_SUCCESS) { 3097c478bd9Sstevel@tonic-gate iter_cnt = 0; 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate iter = 0; 3127c478bd9Sstevel@tonic-gate do { 3137c478bd9Sstevel@tonic-gate for (count = 0; count < def.enum_count; 3147c478bd9Sstevel@tonic-gate count++) { 3157c478bd9Sstevel@tonic-gate if (def.iteration_type != 3167c478bd9Sstevel@tonic-gate FRU_NOT_ITERATED) { 3177c478bd9Sstevel@tonic-gate (void) snprintf(elem_name, 3187c478bd9Sstevel@tonic-gate sizeof (elem_name), 3197c478bd9Sstevel@tonic-gate "/%s[%d]/%s", *ptr, iter, def.enum_table[count].text); 3207c478bd9Sstevel@tonic-gate } else { 3217c478bd9Sstevel@tonic-gate (void) snprintf(elem_name, 3227c478bd9Sstevel@tonic-gate sizeof (elem_name), 3237c478bd9Sstevel@tonic-gate "/%s/%s", *ptr, def.enum_table[count].text); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate if ((fru_read_field(cont_hdl, 3277c478bd9Sstevel@tonic-gate &segment_name[numseg], instance, elem_name, (void**)&data, 3287c478bd9Sstevel@tonic-gate &dataLen, &found_path)) != FRU_SUCCESS) { 3297c478bd9Sstevel@tonic-gate break; 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate if ((fru_get_definition( 3337c478bd9Sstevel@tonic-gate def.enum_table[count].text, &def1)) != FRU_SUCCESS) { 3347c478bd9Sstevel@tonic-gate break; 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate (void) printf(" %s: ",\ 3377c478bd9Sstevel@tonic-gate elem_name); 3387c478bd9Sstevel@tonic-gate display_data(data, dataLen, &def1); 3397c478bd9Sstevel@tonic-gate (void) printf("\n"); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate iter ++; 3427c478bd9Sstevel@tonic-gate } while (iter < iter_cnt); 3437c478bd9Sstevel@tonic-gate ptr++; 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate static char * 3497c478bd9Sstevel@tonic-gate convertBinaryToDecimal(char *ptr) 3507c478bd9Sstevel@tonic-gate { 3517c478bd9Sstevel@tonic-gate int cnt = 0; 3527c478bd9Sstevel@tonic-gate char *data; 3537c478bd9Sstevel@tonic-gate int str_len; 3547c478bd9Sstevel@tonic-gate char *ret = NULL; 3557c478bd9Sstevel@tonic-gate uint64_t result = 0; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate str_len = strlen(ptr); 3587c478bd9Sstevel@tonic-gate data = ptr; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate while (str_len >= 1) { 3617c478bd9Sstevel@tonic-gate str_len -= 1; 3627c478bd9Sstevel@tonic-gate if (data[str_len] == '0') { 3637c478bd9Sstevel@tonic-gate result += (0 * pow(2, cnt)); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate if (data[str_len] == '1') { 3667c478bd9Sstevel@tonic-gate result += (1 * pow(2, cnt)); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate cnt++; 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate ret = (char *)lltostr(result, "\n"); 3717c478bd9Sstevel@tonic-gate return (ret); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * called update_field() to update the field with specific field value. 3767c478bd9Sstevel@tonic-gate * nodehdl represents the fru, segment represents the segment name in the fru. 3777c478bd9Sstevel@tonic-gate * field_name represents the field to be updated with the value field_value. 3787c478bd9Sstevel@tonic-gate */ 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate static int 3817c478bd9Sstevel@tonic-gate convert_update(fru_nodehdl_t nodehdl, char *segment, char *field_name, 3827c478bd9Sstevel@tonic-gate char *field_value) 3837c478bd9Sstevel@tonic-gate { 3847c478bd9Sstevel@tonic-gate uint64_t num = 0; 3857c478bd9Sstevel@tonic-gate fru_elemdef_t def; 3867c478bd9Sstevel@tonic-gate fru_errno_t err; 3877c478bd9Sstevel@tonic-gate void *data = NULL; 3887c478bd9Sstevel@tonic-gate size_t dataLen = 0; 3897c478bd9Sstevel@tonic-gate int i; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate if ((err = fru_get_definition(field_name, &def)) != FRU_SUCCESS) { 3927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3937c478bd9Sstevel@tonic-gate gettext("Failed to get definition %s: %s\n"), 3947c478bd9Sstevel@tonic-gate field_name, fru_strerror(err)); 3957c478bd9Sstevel@tonic-gate return (1); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate if (field_value == NULL) { 3997c478bd9Sstevel@tonic-gate return (1); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate switch (def.data_type) { 4037c478bd9Sstevel@tonic-gate case FDTYPE_Binary: 4047c478bd9Sstevel@tonic-gate if (def.disp_type != FDISP_Time) { 4057c478bd9Sstevel@tonic-gate if (field_value[0] == 'b') { 4067c478bd9Sstevel@tonic-gate field_value = 4077c478bd9Sstevel@tonic-gate convertBinaryToDecimal((field_value+1)); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate num = strtoll(field_value, (char **)NULL, 0); 4107c478bd9Sstevel@tonic-gate if ((num == 0) && (errno == 0)) { 4117c478bd9Sstevel@tonic-gate return (1); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate data = (void*)# 4147c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate break; 4177c478bd9Sstevel@tonic-gate case FDTYPE_ByteArray: 4187c478bd9Sstevel@tonic-gate return (1); 4197c478bd9Sstevel@tonic-gate case FDTYPE_Unicode: 4207c478bd9Sstevel@tonic-gate return (1); 4217c478bd9Sstevel@tonic-gate case FDTYPE_ASCII: 4227c478bd9Sstevel@tonic-gate data = (void *) field_value; 4237c478bd9Sstevel@tonic-gate dataLen = strlen(field_value); 4247c478bd9Sstevel@tonic-gate if (dataLen < def.data_length) { 4257c478bd9Sstevel@tonic-gate dataLen++; 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate break; 4287c478bd9Sstevel@tonic-gate case FDTYPE_Enumeration: 4297c478bd9Sstevel@tonic-gate for (i = 0; i < def.enum_count; i++) { 4307c478bd9Sstevel@tonic-gate if (strcmp(def.enum_table[i].text, 4317c478bd9Sstevel@tonic-gate field_value) == 0) { 43234e5f34eSkmohan data = (void *)(uintptr_t) 43334e5f34eSkmohan def.enum_table[i].value; 4347c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 4357c478bd9Sstevel@tonic-gate break; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate return (1); 4397c478bd9Sstevel@tonic-gate case FDTYPE_Record: 4407c478bd9Sstevel@tonic-gate if (def.iteration_count == 0) { 4417c478bd9Sstevel@tonic-gate return (1); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate data = NULL; 4447c478bd9Sstevel@tonic-gate dataLen = 0; 4457c478bd9Sstevel@tonic-gate break; 4467c478bd9Sstevel@tonic-gate case FDTYPE_UNDEFINED: 4477c478bd9Sstevel@tonic-gate return (1); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, data, 4517c478bd9Sstevel@tonic-gate dataLen)) != FRU_SUCCESS) { 4527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 4537c478bd9Sstevel@tonic-gate fru_strerror(err)); 4547c478bd9Sstevel@tonic-gate return (1); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate return (0); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate /* 4597c478bd9Sstevel@tonic-gate * called by update_field() when a new data element is created. 4607c478bd9Sstevel@tonic-gate * it updates the UNIX_Timestamp32 field with the current system time. 4617c478bd9Sstevel@tonic-gate */ 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate static int 4647c478bd9Sstevel@tonic-gate update_unixtimestamp(fru_nodehdl_t nodehdl, char *segment, char **ptr) 4657c478bd9Sstevel@tonic-gate { 4667c478bd9Sstevel@tonic-gate char *field_name; 4677c478bd9Sstevel@tonic-gate time_t clock; 4687c478bd9Sstevel@tonic-gate struct tm *sp_tm; 4697c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 4707c478bd9Sstevel@tonic-gate uint64_t time_data; 4717c478bd9Sstevel@tonic-gate size_t len; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate len = strlen(*ptr) + strlen("UNIX_Timestamp32") + 3; 4747c478bd9Sstevel@tonic-gate field_name = alloca(len); 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate (void) snprintf(field_name, len, "/%s/UNIX_Timestamp32", *ptr); 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate clock = time(NULL); 4797c478bd9Sstevel@tonic-gate sp_tm = localtime(&clock); 4807c478bd9Sstevel@tonic-gate time_data = (uint64_t)mktime(sp_tm); 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, 4837c478bd9Sstevel@tonic-gate (void *)&time_data, sizeof (time_data))) != FRU_SUCCESS) { 4847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 4857c478bd9Sstevel@tonic-gate fru_strerror(err)); 4867c478bd9Sstevel@tonic-gate return (1); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate return (0); 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* 4927c478bd9Sstevel@tonic-gate * create segment on the specified fru represented by nodehdl. 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate static int 4967c478bd9Sstevel@tonic-gate create_segment(fru_nodehdl_t nodehdl) 4977c478bd9Sstevel@tonic-gate { 4987c478bd9Sstevel@tonic-gate fru_segdesc_t seg_desc; 4997c478bd9Sstevel@tonic-gate fru_segdef_t def; 5007c478bd9Sstevel@tonic-gate int cnt; 501*821a83dbSps154918 int status; 5027c478bd9Sstevel@tonic-gate 50306e46062Sjbeloro (void) memset(&seg_desc, 0, sizeof (seg_desc)); 5047c478bd9Sstevel@tonic-gate seg_desc.field.field_perm = 0x6; 5057c478bd9Sstevel@tonic-gate seg_desc.field.operations_perm = 0x6; 5067c478bd9Sstevel@tonic-gate seg_desc.field.engineering_perm = 0x6; 5077c478bd9Sstevel@tonic-gate seg_desc.field.repair_perm = 0x6; 5087c478bd9Sstevel@tonic-gate 50906e46062Sjbeloro (void) memset(&def, 0, sizeof (def)); 5107c478bd9Sstevel@tonic-gate def.address = 0; 5117c478bd9Sstevel@tonic-gate def.desc.raw_data = seg_desc.raw_data; 5127c478bd9Sstevel@tonic-gate def.hw_desc.all_bits = 0; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 5157c478bd9Sstevel@tonic-gate (void) strncpy(def.name, segment_name[cnt], SEGMENT_NAME_SIZE); 5167c478bd9Sstevel@tonic-gate if (cnt == 0) { 5177c478bd9Sstevel@tonic-gate def.size = FD_SEGMENT_SIZE; 5187c478bd9Sstevel@tonic-gate } 519*821a83dbSps154918 if ((status = fru_create_segment(nodehdl, &def)) 520*821a83dbSps154918 != FRU_SUCCESS) { 5217c478bd9Sstevel@tonic-gate continue; 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate return (cnt); 5247c478bd9Sstevel@tonic-gate } 525*821a83dbSps154918 if (status != FRU_SUCCESS) 526*821a83dbSps154918 (void) fprintf(stderr, gettext("fru_create_segment(): %s\n"), 527*821a83dbSps154918 fru_strerror(status)); 5287c478bd9Sstevel@tonic-gate return (1); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate /* 5327c478bd9Sstevel@tonic-gate * called from update_field() when service flag is ON. currently 5337c478bd9Sstevel@tonic-gate * supported iterated record is InstallationR and fields supported for 5347c478bd9Sstevel@tonic-gate * update are Geo_North, Geo_East, Geo_Alt, Geo_Location. 5357c478bd9Sstevel@tonic-gate */ 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate static int 5387c478bd9Sstevel@tonic-gate updateiter_record(fru_nodehdl_t nodehdl, int cnt, char **ptr, 5397c478bd9Sstevel@tonic-gate char *field_name, char *field_value) 5407c478bd9Sstevel@tonic-gate { 5417c478bd9Sstevel@tonic-gate int iter_cnt = 0; 5427c478bd9Sstevel@tonic-gate char rec_name[512]; 5437c478bd9Sstevel@tonic-gate void *data = NULL; 5447c478bd9Sstevel@tonic-gate char *tmpptr = NULL; 5457c478bd9Sstevel@tonic-gate size_t dataLen = 0; 5467c478bd9Sstevel@tonic-gate char **elem_ptr; 5477c478bd9Sstevel@tonic-gate int found = 0; 5487c478bd9Sstevel@tonic-gate int index; 5497c478bd9Sstevel@tonic-gate int total_cnt; 550*821a83dbSps154918 fru_errno_t err; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate static char *elem_list[] = {"/Geo_North", "/Geo_East",\ 5537c478bd9Sstevel@tonic-gate "/Geo_Alt", "/Geo_Location"}; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate elem_ptr = elem_list; 5567c478bd9Sstevel@tonic-gate total_cnt = sizeof (elem_list)/sizeof (*elem_list); 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate for (index = 0; index < total_cnt; index++) { 5597c478bd9Sstevel@tonic-gate tmpptr = strrchr(field_name, '/'); 5607c478bd9Sstevel@tonic-gate if (tmpptr == NULL) { 5617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5627c478bd9Sstevel@tonic-gate gettext("Error: Data Element not known\n")); 5637c478bd9Sstevel@tonic-gate return (1); 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate if ((strncmp(*elem_ptr, tmpptr, strlen(*elem_ptr)) != 0)) { 5667c478bd9Sstevel@tonic-gate elem_ptr++; 5677c478bd9Sstevel@tonic-gate continue; 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate found = 1; 5707c478bd9Sstevel@tonic-gate break; 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate if (found == 0) { 5747c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5757c478bd9Sstevel@tonic-gate gettext("Error: Update not allowed for field: %s\n"), 5767c478bd9Sstevel@tonic-gate field_name); 5777c478bd9Sstevel@tonic-gate return (1); 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate if ((fru_get_num_iterations(nodehdl, &segment_name[cnt], 0, 5817c478bd9Sstevel@tonic-gate *ptr, &iter_cnt, NULL)) != FRU_SUCCESS) { 5827c478bd9Sstevel@tonic-gate return (1); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate /* add a new Iterated Record if complete path is not given */ 5867c478bd9Sstevel@tonic-gate if (iter_cnt == 0) { 5877c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[+]", *ptr); 588*821a83dbSps154918 if ((err = fru_update_field(nodehdl, segment_name[cnt], 0, 5897c478bd9Sstevel@tonic-gate rec_name, data, dataLen)) != FRU_SUCCESS) { 590*821a83dbSps154918 (void) fprintf(stderr, 591*821a83dbSps154918 gettext("fru_update_field(): %s\n"), 592*821a83dbSps154918 fru_strerror(err)); 5937c478bd9Sstevel@tonic-gate return (1); 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate iter_cnt = 1; 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]%s", 6007c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1, strrchr(field_name, '/')); 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], rec_name, 6037c478bd9Sstevel@tonic-gate field_value)) != 0) { 6047c478bd9Sstevel@tonic-gate return (1); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate /* update success now update the unix timestamp */ 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]", 6107c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1); 6117c478bd9Sstevel@tonic-gate tmpptr = rec_name; 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 6147c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 6157c478bd9Sstevel@tonic-gate &tmpptr)) != 0) { 6167c478bd9Sstevel@tonic-gate return (1); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate return (0); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate static int 6237c478bd9Sstevel@tonic-gate update_field(fru_nodehdl_t nodehdl, char *field_name, char *field_value) 6247c478bd9Sstevel@tonic-gate { 6257c478bd9Sstevel@tonic-gate fru_elemdef_t def; 6267c478bd9Sstevel@tonic-gate unsigned char *data; 6277c478bd9Sstevel@tonic-gate size_t dataLen; 6287c478bd9Sstevel@tonic-gate char *found_path = NULL; 6297c478bd9Sstevel@tonic-gate int cnt; 6307c478bd9Sstevel@tonic-gate char **ptr; 6317c478bd9Sstevel@tonic-gate fru_strlist_t elem; 6327c478bd9Sstevel@tonic-gate int elem_cnt; 6337c478bd9Sstevel@tonic-gate int add_flag = 1; 6347c478bd9Sstevel@tonic-gate int total_cnt; 635*821a83dbSps154918 int status; 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate if (service_mode) { 6387c478bd9Sstevel@tonic-gate ptr = serv_data_list; 6397c478bd9Sstevel@tonic-gate total_cnt = sizeof (serv_data_list)/sizeof (*serv_data_list); 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < total_cnt; cnt++) { 6427c478bd9Sstevel@tonic-gate if ((strncmp(*ptr, &field_name[1], strlen(*ptr)) \ 6437c478bd9Sstevel@tonic-gate != 0) && (strncmp(*ptr, &field_name[0], 6447c478bd9Sstevel@tonic-gate strlen(*ptr)) != 0)) { 6457c478bd9Sstevel@tonic-gate ptr++; 6467c478bd9Sstevel@tonic-gate add_flag = 0; 6477c478bd9Sstevel@tonic-gate continue; 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate add_flag = 1; 6507c478bd9Sstevel@tonic-gate break; 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate } else { 6537c478bd9Sstevel@tonic-gate ptr = cust_data_list; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate /* look for the field in either of the segment if found update it */ 6577c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 6587c478bd9Sstevel@tonic-gate if ((fru_read_field(nodehdl, &segment_name[cnt], 0, field_name, 6597c478bd9Sstevel@tonic-gate (void **) &data, &dataLen, &found_path)) != FRU_SUCCESS) { 6607c478bd9Sstevel@tonic-gate continue; 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 6637c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 6647c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 6657c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 6667c478bd9Sstevel@tonic-gate return (1); 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate return (0); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], 6737c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 6747c478bd9Sstevel@tonic-gate return (1); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with update time */ 6787c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 6797c478bd9Sstevel@tonic-gate ptr)) != 0) { 6807c478bd9Sstevel@tonic-gate return (1); 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate return (0); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate elem.num = 0; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate /* field not found add the the record in one of the segment */ 6887c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 6897c478bd9Sstevel@tonic-gate fru_list_elems_in(nodehdl, segment_name[cnt], &elem); 6907c478bd9Sstevel@tonic-gate for (elem_cnt = 0; elem_cnt < elem.num; elem_cnt++) { 6917c478bd9Sstevel@tonic-gate if ((strcmp(*ptr, elem.strs[elem_cnt])) == 0) { 6927c478bd9Sstevel@tonic-gate add_flag = 0; 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate if (add_flag) { 6977c478bd9Sstevel@tonic-gate if ((fru_add_element(nodehdl, segment_name[cnt], 6987c478bd9Sstevel@tonic-gate *ptr)) != FRU_SUCCESS) { 6997c478bd9Sstevel@tonic-gate continue; 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 7047c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 7057c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 7067c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 7077c478bd9Sstevel@tonic-gate return (1); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate return (0); 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 7147c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 7157c478bd9Sstevel@tonic-gate ptr)) != 0) { 7167c478bd9Sstevel@tonic-gate return (1); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate /* record added update the field with the value */ 7207c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 7217c478bd9Sstevel@tonic-gate field_value)) != 0) { 7227c478bd9Sstevel@tonic-gate return (1); 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate return (0); 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate /* segment not present, create one and add the record */ 7287c478bd9Sstevel@tonic-gate cnt = create_segment(nodehdl); 7297c478bd9Sstevel@tonic-gate if (cnt == 1) { 7307c478bd9Sstevel@tonic-gate return (1); 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate 733*821a83dbSps154918 if ((status = fru_add_element(nodehdl, segment_name[cnt], *ptr)) 7347c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 735*821a83dbSps154918 (void) fprintf(stderr, gettext("fru_add_element(): %s\n"), 736*821a83dbSps154918 fru_strerror(status)); 7377c478bd9Sstevel@tonic-gate return (1); 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 7417c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 7427c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 7437c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 7447c478bd9Sstevel@tonic-gate return (1); 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate return (0); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 7517c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 7527c478bd9Sstevel@tonic-gate ptr)) != 0) { 7537c478bd9Sstevel@tonic-gate return (1); 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 7577c478bd9Sstevel@tonic-gate field_value)) != 0) { 7587c478bd9Sstevel@tonic-gate return (1); 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate return (0); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate static void 7647c478bd9Sstevel@tonic-gate update_node_data(fru_nodehdl_t node) 7657c478bd9Sstevel@tonic-gate { 7667c478bd9Sstevel@tonic-gate int i; 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate if (service_mode) { 7697c478bd9Sstevel@tonic-gate for (i = 0; i < svcargc; i += 2) 7707c478bd9Sstevel@tonic-gate (void) update_field(node, svcargv[i], svcargv[i + 1]); 7717c478bd9Sstevel@tonic-gate } else { 7727c478bd9Sstevel@tonic-gate (void) update_field(node, "/Customer_DataR/Cust_Data", 7737c478bd9Sstevel@tonic-gate customer_data); 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate static void 7787c478bd9Sstevel@tonic-gate walk_tree(fru_nodehdl_t node, const char *prior_path, int process_tree) 7797c478bd9Sstevel@tonic-gate { 7807c478bd9Sstevel@tonic-gate char *name, path[PATH_MAX]; 7817c478bd9Sstevel@tonic-gate int process_self = process_tree, status; 7827c478bd9Sstevel@tonic-gate fru_nodehdl_t next_node; 7837c478bd9Sstevel@tonic-gate fru_node_t type; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate if ((status = fru_get_node_type(node, &type)) != FRU_SUCCESS) { 7867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7877c478bd9Sstevel@tonic-gate gettext("Error getting FRU tree node type: %s\n"), 7887c478bd9Sstevel@tonic-gate fru_strerror(status)); 7897c478bd9Sstevel@tonic-gate exit(1); 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate if ((status = fru_get_name_from_hdl(node, &name)) != FRU_SUCCESS) { 7937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7947c478bd9Sstevel@tonic-gate gettext("Error getting name of FRU tree node: %s\n"), 7957c478bd9Sstevel@tonic-gate fru_strerror(status)); 7967c478bd9Sstevel@tonic-gate exit(1); 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate /* 8017c478bd9Sstevel@tonic-gate * Build the current path 8027c478bd9Sstevel@tonic-gate */ 8037c478bd9Sstevel@tonic-gate if (snprintf(path, sizeof (path), "%s/%s", prior_path, name) 8047c478bd9Sstevel@tonic-gate >= sizeof (path)) { 8057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8067c478bd9Sstevel@tonic-gate gettext("FRU tree path would overflow buffer\n")); 8077c478bd9Sstevel@tonic-gate exit(1); 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate free(name); 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate /* 8137c478bd9Sstevel@tonic-gate * Process the node 8147c478bd9Sstevel@tonic-gate */ 8157c478bd9Sstevel@tonic-gate if (list_only) { 8167c478bd9Sstevel@tonic-gate (void) printf("%s%s\n", path, ((type == FRU_NODE_FRU) ? 8177c478bd9Sstevel@tonic-gate " (fru)" : ((type == FRU_NODE_CONTAINER) ? 8187c478bd9Sstevel@tonic-gate " (container)" : ""))); 8197c478bd9Sstevel@tonic-gate } else if ((process_tree || (process_self = pathmatch(path))) && 8207c478bd9Sstevel@tonic-gate (type == FRU_NODE_CONTAINER)) { 8217c478bd9Sstevel@tonic-gate (void) printf("%s\n", path); 8227c478bd9Sstevel@tonic-gate if (update) update_node_data(node); 8237c478bd9Sstevel@tonic-gate print_node_data(node); 8247c478bd9Sstevel@tonic-gate if (!recursive) exit(0); 8257c478bd9Sstevel@tonic-gate } else if (process_self && !recursive) { 8267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8277c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a container\n"), path); 8287c478bd9Sstevel@tonic-gate exit(1); 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate /* 8337c478bd9Sstevel@tonic-gate * Recurse 8347c478bd9Sstevel@tonic-gate */ 8357c478bd9Sstevel@tonic-gate if (fru_get_child(node, &next_node) == FRU_SUCCESS) 8367c478bd9Sstevel@tonic-gate walk_tree(next_node, path, process_self); 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate if (fru_get_peer(node, &next_node) == FRU_SUCCESS) 8397c478bd9Sstevel@tonic-gate walk_tree(next_node, prior_path, process_tree); 8407c478bd9Sstevel@tonic-gate } 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate static int 8437c478bd9Sstevel@tonic-gate has_system_controller() 8447c478bd9Sstevel@tonic-gate { 8457c478bd9Sstevel@tonic-gate char platform[PATH_MAX]; 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate int size; 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate if (((size = sysinfo(SI_PLATFORM, platform, sizeof (platform))) 8507c478bd9Sstevel@tonic-gate < 0) || (size > sizeof (platform))) 8517c478bd9Sstevel@tonic-gate return (-1); 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate if ((strcmp("SUNW,Sun-Fire", platform) == 0) || 8547c478bd9Sstevel@tonic-gate (strcmp("SUNW,Sun-Fire-15000", platform) == 0)) { 8557c478bd9Sstevel@tonic-gate return (1); 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate return (0); 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate int 8627c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 8637c478bd9Sstevel@tonic-gate { 8647c478bd9Sstevel@tonic-gate int process_tree = 0, option, status; 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate fru_nodehdl_t root; 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate command = argv[0]; 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate opterr = 0; /* "getopt" should not print to "stderr" */ 8727c478bd9Sstevel@tonic-gate while ((option = getopt(argc, argv, "lrs")) != EOF) { 8737c478bd9Sstevel@tonic-gate switch (option) { 8747c478bd9Sstevel@tonic-gate case 'l': 8757c478bd9Sstevel@tonic-gate list_only = 1; 8767c478bd9Sstevel@tonic-gate break; 8777c478bd9Sstevel@tonic-gate case 'r': 8787c478bd9Sstevel@tonic-gate recursive = 1; 8797c478bd9Sstevel@tonic-gate break; 8807c478bd9Sstevel@tonic-gate case 's': 8817c478bd9Sstevel@tonic-gate service_mode = 1; 8827c478bd9Sstevel@tonic-gate break; 8837c478bd9Sstevel@tonic-gate default: 8847c478bd9Sstevel@tonic-gate usage(); 8857c478bd9Sstevel@tonic-gate return (1); 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate } 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate argc -= optind; 8907c478bd9Sstevel@tonic-gate argv += optind; 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate if (argc == 0) { 8937c478bd9Sstevel@tonic-gate process_tree = 1; 8947c478bd9Sstevel@tonic-gate recursive = 1; 8957c478bd9Sstevel@tonic-gate } else { 8967c478bd9Sstevel@tonic-gate if (list_only) { 8977c478bd9Sstevel@tonic-gate usage(); 8987c478bd9Sstevel@tonic-gate return (1); 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate frupath = argv[0]; 9027c478bd9Sstevel@tonic-gate if (*frupath == 0) { 9037c478bd9Sstevel@tonic-gate usage(); 9047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9057c478bd9Sstevel@tonic-gate gettext("\"frupath\" should not be empty\n")); 9067c478bd9Sstevel@tonic-gate return (1); 9077c478bd9Sstevel@tonic-gate } 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate argc--; 9107c478bd9Sstevel@tonic-gate argv++; 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate if (argc > 0) { 9137c478bd9Sstevel@tonic-gate update = 1; 9147c478bd9Sstevel@tonic-gate if (service_mode) { 9157c478bd9Sstevel@tonic-gate if ((argc % 2) != 0) { 9167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9177c478bd9Sstevel@tonic-gate gettext("Must specify " 9187c478bd9Sstevel@tonic-gate "field-value pairs " 9197c478bd9Sstevel@tonic-gate "for update\n")); 9207c478bd9Sstevel@tonic-gate return (1); 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate if (validate_fieldnames(argc, argv) != 0) { 9247c478bd9Sstevel@tonic-gate return (1); 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate svcargc = argc; 9287c478bd9Sstevel@tonic-gate svcargv = argv; 9297c478bd9Sstevel@tonic-gate } else if (argc == 1) 9307c478bd9Sstevel@tonic-gate customer_data = argv[0]; 9317c478bd9Sstevel@tonic-gate else { 9327c478bd9Sstevel@tonic-gate usage(); 9337c478bd9Sstevel@tonic-gate return (1); 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate } 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate if ((status = fru_open_data_source("picl", NULL)) != FRU_SUCCESS) { 9397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9407c478bd9Sstevel@tonic-gate gettext("Unable to access FRU data source: %s\n"), 9417c478bd9Sstevel@tonic-gate fru_strerror(status)); 9427c478bd9Sstevel@tonic-gate return (1); 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate if ((status = fru_get_root(&root)) == FRU_NODENOTFOUND) { 9467c478bd9Sstevel@tonic-gate if (has_system_controller() == 1) { 9477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9487c478bd9Sstevel@tonic-gate gettext("Access FRUs from the " 9497c478bd9Sstevel@tonic-gate "System Controller\n")); 9507c478bd9Sstevel@tonic-gate } else { 9517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9527c478bd9Sstevel@tonic-gate gettext("This system does not provide " 9537c478bd9Sstevel@tonic-gate "FRU ID data\n")); 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate return (1); 9577c478bd9Sstevel@tonic-gate } else if (status != FRU_SUCCESS) { 9587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9597c478bd9Sstevel@tonic-gate gettext("Unable to access FRU ID data " 9607c478bd9Sstevel@tonic-gate "due to data source error\n")); 9617c478bd9Sstevel@tonic-gate return (1); 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate walk_tree(root, "", process_tree); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate if ((frupath != NULL) && (!found_frupath)) { 9677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9687c478bd9Sstevel@tonic-gate gettext("\"%s\" not found\n"), 9697c478bd9Sstevel@tonic-gate frupath); 9707c478bd9Sstevel@tonic-gate return (1); 9717c478bd9Sstevel@tonic-gate } 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate return (0); 9747c478bd9Sstevel@tonic-gate } 975