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*043728a3Sdt207653 * Copyright 2008 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, 327af3025fdSdt207653 &segment_name[numseg], instance, 328af3025fdSdt207653 elem_name, (void**)&data, &dataLen, 329af3025fdSdt207653 &found_path)) != FRU_SUCCESS) { 3307c478bd9Sstevel@tonic-gate break; 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate if ((fru_get_definition( 3347c478bd9Sstevel@tonic-gate def.enum_table[count].text, &def1)) != FRU_SUCCESS) { 3357c478bd9Sstevel@tonic-gate break; 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate (void) printf(" %s: ",\ 3387c478bd9Sstevel@tonic-gate elem_name); 3397c478bd9Sstevel@tonic-gate display_data(data, dataLen, &def1); 3407c478bd9Sstevel@tonic-gate (void) printf("\n"); 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate iter ++; 3437c478bd9Sstevel@tonic-gate } while (iter < iter_cnt); 3447c478bd9Sstevel@tonic-gate ptr++; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate static char * 3507c478bd9Sstevel@tonic-gate convertBinaryToDecimal(char *ptr) 3517c478bd9Sstevel@tonic-gate { 3527c478bd9Sstevel@tonic-gate int cnt = 0; 3537c478bd9Sstevel@tonic-gate char *data; 3547c478bd9Sstevel@tonic-gate int str_len; 3557c478bd9Sstevel@tonic-gate char *ret = NULL; 3567c478bd9Sstevel@tonic-gate uint64_t result = 0; 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate str_len = strlen(ptr); 3597c478bd9Sstevel@tonic-gate data = ptr; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate while (str_len >= 1) { 3627c478bd9Sstevel@tonic-gate str_len -= 1; 3637c478bd9Sstevel@tonic-gate if (data[str_len] == '0') { 3647c478bd9Sstevel@tonic-gate result += (0 * pow(2, cnt)); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate if (data[str_len] == '1') { 3677c478bd9Sstevel@tonic-gate result += (1 * pow(2, cnt)); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate cnt++; 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate ret = (char *)lltostr(result, "\n"); 3727c478bd9Sstevel@tonic-gate return (ret); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* 3767c478bd9Sstevel@tonic-gate * called update_field() to update the field with specific field value. 3777c478bd9Sstevel@tonic-gate * nodehdl represents the fru, segment represents the segment name in the fru. 3787c478bd9Sstevel@tonic-gate * field_name represents the field to be updated with the value field_value. 3797c478bd9Sstevel@tonic-gate */ 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate static int 3827c478bd9Sstevel@tonic-gate convert_update(fru_nodehdl_t nodehdl, char *segment, char *field_name, 3837c478bd9Sstevel@tonic-gate char *field_value) 3847c478bd9Sstevel@tonic-gate { 3857c478bd9Sstevel@tonic-gate uint64_t num = 0; 3867c478bd9Sstevel@tonic-gate fru_elemdef_t def; 3877c478bd9Sstevel@tonic-gate fru_errno_t err; 3887c478bd9Sstevel@tonic-gate void *data = NULL; 3897c478bd9Sstevel@tonic-gate size_t dataLen = 0; 3907c478bd9Sstevel@tonic-gate int i; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate if ((err = fru_get_definition(field_name, &def)) != FRU_SUCCESS) { 3937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3947c478bd9Sstevel@tonic-gate gettext("Failed to get definition %s: %s\n"), 3957c478bd9Sstevel@tonic-gate field_name, fru_strerror(err)); 3967c478bd9Sstevel@tonic-gate return (1); 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate if (field_value == NULL) { 4007c478bd9Sstevel@tonic-gate return (1); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate switch (def.data_type) { 4047c478bd9Sstevel@tonic-gate case FDTYPE_Binary: 4057c478bd9Sstevel@tonic-gate if (def.disp_type != FDISP_Time) { 4067c478bd9Sstevel@tonic-gate if (field_value[0] == 'b') { 4077c478bd9Sstevel@tonic-gate field_value = 408af3025fdSdt207653 convertBinaryToDecimal((field_value 409af3025fdSdt207653 +1)); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate num = strtoll(field_value, (char **)NULL, 0); 4127c478bd9Sstevel@tonic-gate if ((num == 0) && (errno == 0)) { 4137c478bd9Sstevel@tonic-gate return (1); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate data = (void*)# 4167c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate break; 4197c478bd9Sstevel@tonic-gate case FDTYPE_ByteArray: 4207c478bd9Sstevel@tonic-gate return (1); 4217c478bd9Sstevel@tonic-gate case FDTYPE_Unicode: 4227c478bd9Sstevel@tonic-gate return (1); 4237c478bd9Sstevel@tonic-gate case FDTYPE_ASCII: 4247c478bd9Sstevel@tonic-gate data = (void *) field_value; 4257c478bd9Sstevel@tonic-gate dataLen = strlen(field_value); 4267c478bd9Sstevel@tonic-gate if (dataLen < def.data_length) { 4277c478bd9Sstevel@tonic-gate dataLen++; 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate break; 4307c478bd9Sstevel@tonic-gate case FDTYPE_Enumeration: 4317c478bd9Sstevel@tonic-gate for (i = 0; i < def.enum_count; i++) { 4327c478bd9Sstevel@tonic-gate if (strcmp(def.enum_table[i].text, 4337c478bd9Sstevel@tonic-gate field_value) == 0) { 43434e5f34eSkmohan data = (void *)(uintptr_t) 43534e5f34eSkmohan def.enum_table[i].value; 4367c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 4377c478bd9Sstevel@tonic-gate break; 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate return (1); 4417c478bd9Sstevel@tonic-gate case FDTYPE_Record: 4427c478bd9Sstevel@tonic-gate if (def.iteration_count == 0) { 4437c478bd9Sstevel@tonic-gate return (1); 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate data = NULL; 4467c478bd9Sstevel@tonic-gate dataLen = 0; 4477c478bd9Sstevel@tonic-gate break; 4487c478bd9Sstevel@tonic-gate case FDTYPE_UNDEFINED: 4497c478bd9Sstevel@tonic-gate return (1); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, data, 4537c478bd9Sstevel@tonic-gate dataLen)) != FRU_SUCCESS) { 4547c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 4557c478bd9Sstevel@tonic-gate fru_strerror(err)); 4567c478bd9Sstevel@tonic-gate return (1); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate return (0); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate /* 4617c478bd9Sstevel@tonic-gate * called by update_field() when a new data element is created. 4627c478bd9Sstevel@tonic-gate * it updates the UNIX_Timestamp32 field with the current system time. 4637c478bd9Sstevel@tonic-gate */ 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate static int 4667c478bd9Sstevel@tonic-gate update_unixtimestamp(fru_nodehdl_t nodehdl, char *segment, char **ptr) 4677c478bd9Sstevel@tonic-gate { 4687c478bd9Sstevel@tonic-gate char *field_name; 4697c478bd9Sstevel@tonic-gate time_t clock; 4707c478bd9Sstevel@tonic-gate struct tm *sp_tm; 4717c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 4727c478bd9Sstevel@tonic-gate uint64_t time_data; 4737c478bd9Sstevel@tonic-gate size_t len; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate len = strlen(*ptr) + strlen("UNIX_Timestamp32") + 3; 4767c478bd9Sstevel@tonic-gate field_name = alloca(len); 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate (void) snprintf(field_name, len, "/%s/UNIX_Timestamp32", *ptr); 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate clock = time(NULL); 4817c478bd9Sstevel@tonic-gate sp_tm = localtime(&clock); 4827c478bd9Sstevel@tonic-gate time_data = (uint64_t)mktime(sp_tm); 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, 4857c478bd9Sstevel@tonic-gate (void *)&time_data, sizeof (time_data))) != FRU_SUCCESS) { 4867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 4877c478bd9Sstevel@tonic-gate fru_strerror(err)); 4887c478bd9Sstevel@tonic-gate return (1); 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate return (0); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * create segment on the specified fru represented by nodehdl. 4957c478bd9Sstevel@tonic-gate */ 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate static int 4987c478bd9Sstevel@tonic-gate create_segment(fru_nodehdl_t nodehdl) 4997c478bd9Sstevel@tonic-gate { 5007c478bd9Sstevel@tonic-gate fru_segdesc_t seg_desc; 5017c478bd9Sstevel@tonic-gate fru_segdef_t def; 5027c478bd9Sstevel@tonic-gate int cnt; 503821a83dbSps154918 int status; 5047c478bd9Sstevel@tonic-gate 50506e46062Sjbeloro (void) memset(&seg_desc, 0, sizeof (seg_desc)); 5067c478bd9Sstevel@tonic-gate seg_desc.field.field_perm = 0x6; 5077c478bd9Sstevel@tonic-gate seg_desc.field.operations_perm = 0x6; 5087c478bd9Sstevel@tonic-gate seg_desc.field.engineering_perm = 0x6; 5097c478bd9Sstevel@tonic-gate seg_desc.field.repair_perm = 0x6; 5107c478bd9Sstevel@tonic-gate 51106e46062Sjbeloro (void) memset(&def, 0, sizeof (def)); 5127c478bd9Sstevel@tonic-gate def.address = 0; 5137c478bd9Sstevel@tonic-gate def.desc.raw_data = seg_desc.raw_data; 5147c478bd9Sstevel@tonic-gate def.hw_desc.all_bits = 0; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 5177c478bd9Sstevel@tonic-gate (void) strncpy(def.name, segment_name[cnt], SEGMENT_NAME_SIZE); 5187c478bd9Sstevel@tonic-gate if (cnt == 0) { 5197c478bd9Sstevel@tonic-gate def.size = FD_SEGMENT_SIZE; 5207c478bd9Sstevel@tonic-gate } 521821a83dbSps154918 if ((status = fru_create_segment(nodehdl, &def)) 522821a83dbSps154918 != FRU_SUCCESS) { 5237c478bd9Sstevel@tonic-gate continue; 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate return (cnt); 5267c478bd9Sstevel@tonic-gate } 527821a83dbSps154918 if (status != FRU_SUCCESS) 528821a83dbSps154918 (void) fprintf(stderr, gettext("fru_create_segment(): %s\n"), 529821a83dbSps154918 fru_strerror(status)); 5307c478bd9Sstevel@tonic-gate return (1); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /* 5347c478bd9Sstevel@tonic-gate * called from update_field() when service flag is ON. currently 5357c478bd9Sstevel@tonic-gate * supported iterated record is InstallationR and fields supported for 5367c478bd9Sstevel@tonic-gate * update are Geo_North, Geo_East, Geo_Alt, Geo_Location. 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate static int 5407c478bd9Sstevel@tonic-gate updateiter_record(fru_nodehdl_t nodehdl, int cnt, char **ptr, 5417c478bd9Sstevel@tonic-gate char *field_name, char *field_value) 5427c478bd9Sstevel@tonic-gate { 5437c478bd9Sstevel@tonic-gate int iter_cnt = 0; 5447c478bd9Sstevel@tonic-gate char rec_name[512]; 5457c478bd9Sstevel@tonic-gate void *data = NULL; 5467c478bd9Sstevel@tonic-gate char *tmpptr = NULL; 5477c478bd9Sstevel@tonic-gate size_t dataLen = 0; 5487c478bd9Sstevel@tonic-gate char **elem_ptr; 5497c478bd9Sstevel@tonic-gate int found = 0; 5507c478bd9Sstevel@tonic-gate int index; 5517c478bd9Sstevel@tonic-gate int total_cnt; 552821a83dbSps154918 fru_errno_t err; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate static char *elem_list[] = {"/Geo_North", "/Geo_East",\ 5557c478bd9Sstevel@tonic-gate "/Geo_Alt", "/Geo_Location"}; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate elem_ptr = elem_list; 5587c478bd9Sstevel@tonic-gate total_cnt = sizeof (elem_list)/sizeof (*elem_list); 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate for (index = 0; index < total_cnt; index++) { 5617c478bd9Sstevel@tonic-gate tmpptr = strrchr(field_name, '/'); 5627c478bd9Sstevel@tonic-gate if (tmpptr == NULL) { 5637c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5647c478bd9Sstevel@tonic-gate gettext("Error: Data Element not known\n")); 5657c478bd9Sstevel@tonic-gate return (1); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate if ((strncmp(*elem_ptr, tmpptr, strlen(*elem_ptr)) != 0)) { 5687c478bd9Sstevel@tonic-gate elem_ptr++; 5697c478bd9Sstevel@tonic-gate continue; 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate found = 1; 5727c478bd9Sstevel@tonic-gate break; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate if (found == 0) { 5767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5777c478bd9Sstevel@tonic-gate gettext("Error: Update not allowed for field: %s\n"), 5787c478bd9Sstevel@tonic-gate field_name); 5797c478bd9Sstevel@tonic-gate return (1); 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate if ((fru_get_num_iterations(nodehdl, &segment_name[cnt], 0, 5837c478bd9Sstevel@tonic-gate *ptr, &iter_cnt, NULL)) != FRU_SUCCESS) { 5847c478bd9Sstevel@tonic-gate return (1); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /* add a new Iterated Record if complete path is not given */ 5887c478bd9Sstevel@tonic-gate if (iter_cnt == 0) { 5897c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[+]", *ptr); 590821a83dbSps154918 if ((err = fru_update_field(nodehdl, segment_name[cnt], 0, 5917c478bd9Sstevel@tonic-gate rec_name, data, dataLen)) != FRU_SUCCESS) { 592821a83dbSps154918 (void) fprintf(stderr, 593821a83dbSps154918 gettext("fru_update_field(): %s\n"), 594821a83dbSps154918 fru_strerror(err)); 5957c478bd9Sstevel@tonic-gate return (1); 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate iter_cnt = 1; 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]%s", 6027c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1, strrchr(field_name, '/')); 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], rec_name, 6057c478bd9Sstevel@tonic-gate field_value)) != 0) { 6067c478bd9Sstevel@tonic-gate return (1); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate /* update success now update the unix timestamp */ 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]", 6127c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1); 6137c478bd9Sstevel@tonic-gate tmpptr = rec_name; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 6167c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 6177c478bd9Sstevel@tonic-gate &tmpptr)) != 0) { 6187c478bd9Sstevel@tonic-gate return (1); 6197c478bd9Sstevel@tonic-gate } 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate return (0); 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate static int 6257c478bd9Sstevel@tonic-gate update_field(fru_nodehdl_t nodehdl, char *field_name, char *field_value) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate fru_elemdef_t def; 6287c478bd9Sstevel@tonic-gate unsigned char *data; 6297c478bd9Sstevel@tonic-gate size_t dataLen; 6307c478bd9Sstevel@tonic-gate char *found_path = NULL; 6317c478bd9Sstevel@tonic-gate int cnt; 6327c478bd9Sstevel@tonic-gate char **ptr; 6337c478bd9Sstevel@tonic-gate fru_strlist_t elem; 6347c478bd9Sstevel@tonic-gate int elem_cnt; 6357c478bd9Sstevel@tonic-gate int add_flag = 1; 6367c478bd9Sstevel@tonic-gate int total_cnt; 637821a83dbSps154918 int status; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate if (service_mode) { 6407c478bd9Sstevel@tonic-gate ptr = serv_data_list; 6417c478bd9Sstevel@tonic-gate total_cnt = sizeof (serv_data_list)/sizeof (*serv_data_list); 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < total_cnt; cnt++) { 6447c478bd9Sstevel@tonic-gate if ((strncmp(*ptr, &field_name[1], strlen(*ptr)) \ 6457c478bd9Sstevel@tonic-gate != 0) && (strncmp(*ptr, &field_name[0], 6467c478bd9Sstevel@tonic-gate strlen(*ptr)) != 0)) { 6477c478bd9Sstevel@tonic-gate ptr++; 6487c478bd9Sstevel@tonic-gate add_flag = 0; 6497c478bd9Sstevel@tonic-gate continue; 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate add_flag = 1; 6527c478bd9Sstevel@tonic-gate break; 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate } else { 6557c478bd9Sstevel@tonic-gate ptr = cust_data_list; 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* look for the field in either of the segment if found update it */ 6597c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 6607c478bd9Sstevel@tonic-gate if ((fru_read_field(nodehdl, &segment_name[cnt], 0, field_name, 6617c478bd9Sstevel@tonic-gate (void **) &data, &dataLen, &found_path)) != FRU_SUCCESS) { 6627c478bd9Sstevel@tonic-gate continue; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 6657c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 6667c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 6677c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 6687c478bd9Sstevel@tonic-gate return (1); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate return (0); 6717c478bd9Sstevel@tonic-gate } 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], 6757c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 6767c478bd9Sstevel@tonic-gate return (1); 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with update time */ 6807c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 6817c478bd9Sstevel@tonic-gate ptr)) != 0) { 6827c478bd9Sstevel@tonic-gate return (1); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate return (0); 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate elem.num = 0; 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate /* field not found add the the record in one of the segment */ 6907c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 6917c478bd9Sstevel@tonic-gate fru_list_elems_in(nodehdl, segment_name[cnt], &elem); 6927c478bd9Sstevel@tonic-gate for (elem_cnt = 0; elem_cnt < elem.num; elem_cnt++) { 6937c478bd9Sstevel@tonic-gate if ((strcmp(*ptr, elem.strs[elem_cnt])) == 0) { 6947c478bd9Sstevel@tonic-gate add_flag = 0; 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate if (add_flag) { 6997c478bd9Sstevel@tonic-gate if ((fru_add_element(nodehdl, segment_name[cnt], 7007c478bd9Sstevel@tonic-gate *ptr)) != FRU_SUCCESS) { 7017c478bd9Sstevel@tonic-gate continue; 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 7067c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 7077c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 7087c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 7097c478bd9Sstevel@tonic-gate return (1); 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate return (0); 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 7167c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 7177c478bd9Sstevel@tonic-gate ptr)) != 0) { 7187c478bd9Sstevel@tonic-gate return (1); 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate /* record added update the field with the value */ 7227c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 7237c478bd9Sstevel@tonic-gate field_value)) != 0) { 7247c478bd9Sstevel@tonic-gate return (1); 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate return (0); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate /* segment not present, create one and add the record */ 7307c478bd9Sstevel@tonic-gate cnt = create_segment(nodehdl); 7317c478bd9Sstevel@tonic-gate if (cnt == 1) { 7327c478bd9Sstevel@tonic-gate return (1); 7337c478bd9Sstevel@tonic-gate } 7347c478bd9Sstevel@tonic-gate 735821a83dbSps154918 if ((status = fru_add_element(nodehdl, segment_name[cnt], *ptr)) 7367c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 737821a83dbSps154918 (void) fprintf(stderr, gettext("fru_add_element(): %s\n"), 738821a83dbSps154918 fru_strerror(status)); 7397c478bd9Sstevel@tonic-gate return (1); 7407c478bd9Sstevel@tonic-gate } 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 7437c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 7447c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 7457c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 7467c478bd9Sstevel@tonic-gate return (1); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate return (0); 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 7537c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 7547c478bd9Sstevel@tonic-gate ptr)) != 0) { 7557c478bd9Sstevel@tonic-gate return (1); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 7597c478bd9Sstevel@tonic-gate field_value)) != 0) { 7607c478bd9Sstevel@tonic-gate return (1); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate return (0); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657513a25aSdt207653 static int 7667c478bd9Sstevel@tonic-gate update_node_data(fru_nodehdl_t node) 7677c478bd9Sstevel@tonic-gate { 7687c478bd9Sstevel@tonic-gate int i; 769af3025fdSdt207653 int status = 0; 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate if (service_mode) { 7727c478bd9Sstevel@tonic-gate for (i = 0; i < svcargc; i += 2) 7737513a25aSdt207653 if (update_field(node, svcargv[i], svcargv[i + 1])) { 7747513a25aSdt207653 status = 1; 7757513a25aSdt207653 } 7767c478bd9Sstevel@tonic-gate } else { 7777513a25aSdt207653 status = update_field(node, "/Customer_DataR/Cust_Data", 7787c478bd9Sstevel@tonic-gate customer_data); 7797c478bd9Sstevel@tonic-gate } 7807513a25aSdt207653 return (status); 7817c478bd9Sstevel@tonic-gate } 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate static void 7847c478bd9Sstevel@tonic-gate walk_tree(fru_nodehdl_t node, const char *prior_path, int process_tree) 7857c478bd9Sstevel@tonic-gate { 7867c478bd9Sstevel@tonic-gate char *name, path[PATH_MAX]; 7877513a25aSdt207653 int process_self = process_tree, status, update_status = 0; 7887c478bd9Sstevel@tonic-gate fru_nodehdl_t next_node; 7897c478bd9Sstevel@tonic-gate fru_node_t type; 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate if ((status = fru_get_node_type(node, &type)) != FRU_SUCCESS) { 7927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7937c478bd9Sstevel@tonic-gate gettext("Error getting FRU tree node type: %s\n"), 7947c478bd9Sstevel@tonic-gate fru_strerror(status)); 7957c478bd9Sstevel@tonic-gate exit(1); 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate if ((status = fru_get_name_from_hdl(node, &name)) != FRU_SUCCESS) { 7997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8007c478bd9Sstevel@tonic-gate gettext("Error getting name of FRU tree node: %s\n"), 8017c478bd9Sstevel@tonic-gate fru_strerror(status)); 8027c478bd9Sstevel@tonic-gate exit(1); 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate /* 8077c478bd9Sstevel@tonic-gate * Build the current path 8087c478bd9Sstevel@tonic-gate */ 8097c478bd9Sstevel@tonic-gate if (snprintf(path, sizeof (path), "%s/%s", prior_path, name) 8107c478bd9Sstevel@tonic-gate >= sizeof (path)) { 8117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8127c478bd9Sstevel@tonic-gate gettext("FRU tree path would overflow buffer\n")); 8137c478bd9Sstevel@tonic-gate exit(1); 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate free(name); 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* 8197c478bd9Sstevel@tonic-gate * Process the node 8207c478bd9Sstevel@tonic-gate */ 8217c478bd9Sstevel@tonic-gate if (list_only) { 8227c478bd9Sstevel@tonic-gate (void) printf("%s%s\n", path, ((type == FRU_NODE_FRU) ? 8237c478bd9Sstevel@tonic-gate " (fru)" : ((type == FRU_NODE_CONTAINER) ? 8247c478bd9Sstevel@tonic-gate " (container)" : ""))); 8257c478bd9Sstevel@tonic-gate } else if ((process_tree || (process_self = pathmatch(path))) && 8267c478bd9Sstevel@tonic-gate (type == FRU_NODE_CONTAINER)) { 8277c478bd9Sstevel@tonic-gate (void) printf("%s\n", path); 8287513a25aSdt207653 if (update) { 8297513a25aSdt207653 status = update_node_data(node); 8307513a25aSdt207653 update_status = status; 8317513a25aSdt207653 } 8327c478bd9Sstevel@tonic-gate print_node_data(node); 8337513a25aSdt207653 if (!recursive) { 8347513a25aSdt207653 exit(status); 8357513a25aSdt207653 } 8367c478bd9Sstevel@tonic-gate } else if (process_self && !recursive) { 8377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8387c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a container\n"), path); 8397c478bd9Sstevel@tonic-gate exit(1); 8407c478bd9Sstevel@tonic-gate } 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate /* 8447c478bd9Sstevel@tonic-gate * Recurse 8457c478bd9Sstevel@tonic-gate */ 8467c478bd9Sstevel@tonic-gate if (fru_get_child(node, &next_node) == FRU_SUCCESS) 8477c478bd9Sstevel@tonic-gate walk_tree(next_node, path, process_self); 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate if (fru_get_peer(node, &next_node) == FRU_SUCCESS) 8507c478bd9Sstevel@tonic-gate walk_tree(next_node, prior_path, process_tree); 8517513a25aSdt207653 8527513a25aSdt207653 /* 8537513a25aSdt207653 * when update_node_data failed, need to exit with return value 1 8547513a25aSdt207653 */ 8557513a25aSdt207653 if (update_status) 8567513a25aSdt207653 exit(1); 8577c478bd9Sstevel@tonic-gate } 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate int 8607c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 8617c478bd9Sstevel@tonic-gate { 8627c478bd9Sstevel@tonic-gate int process_tree = 0, option, status; 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate fru_nodehdl_t root; 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate command = argv[0]; 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate opterr = 0; /* "getopt" should not print to "stderr" */ 8707c478bd9Sstevel@tonic-gate while ((option = getopt(argc, argv, "lrs")) != EOF) { 8717c478bd9Sstevel@tonic-gate switch (option) { 8727c478bd9Sstevel@tonic-gate case 'l': 8737c478bd9Sstevel@tonic-gate list_only = 1; 8747c478bd9Sstevel@tonic-gate break; 8757c478bd9Sstevel@tonic-gate case 'r': 8767c478bd9Sstevel@tonic-gate recursive = 1; 8777c478bd9Sstevel@tonic-gate break; 8787c478bd9Sstevel@tonic-gate case 's': 8797c478bd9Sstevel@tonic-gate service_mode = 1; 8807c478bd9Sstevel@tonic-gate break; 8817c478bd9Sstevel@tonic-gate default: 8827c478bd9Sstevel@tonic-gate usage(); 8837c478bd9Sstevel@tonic-gate return (1); 8847c478bd9Sstevel@tonic-gate } 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate argc -= optind; 8887c478bd9Sstevel@tonic-gate argv += optind; 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate if (argc == 0) { 8917c478bd9Sstevel@tonic-gate process_tree = 1; 8927c478bd9Sstevel@tonic-gate recursive = 1; 8937c478bd9Sstevel@tonic-gate } else { 8947c478bd9Sstevel@tonic-gate if (list_only) { 8957c478bd9Sstevel@tonic-gate usage(); 8967c478bd9Sstevel@tonic-gate return (1); 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate frupath = argv[0]; 9007c478bd9Sstevel@tonic-gate if (*frupath == 0) { 9017c478bd9Sstevel@tonic-gate usage(); 9027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9037c478bd9Sstevel@tonic-gate gettext("\"frupath\" should not be empty\n")); 9047c478bd9Sstevel@tonic-gate return (1); 9057c478bd9Sstevel@tonic-gate } 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate argc--; 9087c478bd9Sstevel@tonic-gate argv++; 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate if (argc > 0) { 9117c478bd9Sstevel@tonic-gate update = 1; 9127c478bd9Sstevel@tonic-gate if (service_mode) { 9137c478bd9Sstevel@tonic-gate if ((argc % 2) != 0) { 9147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9157c478bd9Sstevel@tonic-gate gettext("Must specify " 9167c478bd9Sstevel@tonic-gate "field-value pairs " 9177c478bd9Sstevel@tonic-gate "for update\n")); 9187c478bd9Sstevel@tonic-gate return (1); 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate if (validate_fieldnames(argc, argv) != 0) { 9227c478bd9Sstevel@tonic-gate return (1); 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate svcargc = argc; 9267c478bd9Sstevel@tonic-gate svcargv = argv; 9277c478bd9Sstevel@tonic-gate } else if (argc == 1) 9287c478bd9Sstevel@tonic-gate customer_data = argv[0]; 9297c478bd9Sstevel@tonic-gate else { 9307c478bd9Sstevel@tonic-gate usage(); 9317c478bd9Sstevel@tonic-gate return (1); 9327c478bd9Sstevel@tonic-gate } 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate if ((status = fru_open_data_source("picl", NULL)) != FRU_SUCCESS) { 9377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9387c478bd9Sstevel@tonic-gate gettext("Unable to access FRU data source: %s\n"), 9397c478bd9Sstevel@tonic-gate fru_strerror(status)); 9407c478bd9Sstevel@tonic-gate return (1); 9417c478bd9Sstevel@tonic-gate } 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate if ((status = fru_get_root(&root)) == FRU_NODENOTFOUND) { 9447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 945*043728a3Sdt207653 gettext("This system does not support PICL " 946*043728a3Sdt207653 "infrastructure to provide FRUID data\n" 947*043728a3Sdt207653 "Please use the platform SP to access the FRUID " 948*043728a3Sdt207653 "information\n")); 9497c478bd9Sstevel@tonic-gate return (1); 9507c478bd9Sstevel@tonic-gate } else if (status != FRU_SUCCESS) { 9517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9527c478bd9Sstevel@tonic-gate gettext("Unable to access FRU ID data " 9537c478bd9Sstevel@tonic-gate "due to data source error\n")); 9547c478bd9Sstevel@tonic-gate return (1); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate walk_tree(root, "", process_tree); 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate if ((frupath != NULL) && (!found_frupath)) { 9607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9617c478bd9Sstevel@tonic-gate gettext("\"%s\" not found\n"), 9627c478bd9Sstevel@tonic-gate frupath); 9637c478bd9Sstevel@tonic-gate return (1); 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate return (0); 9677c478bd9Sstevel@tonic-gate } 968