1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <limits.h> 30*7c478bd9Sstevel@tonic-gate #include <stdio.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <string.h> 33*7c478bd9Sstevel@tonic-gate #include <libintl.h> 34*7c478bd9Sstevel@tonic-gate #include <libfru.h> 35*7c478bd9Sstevel@tonic-gate #include <errno.h> 36*7c478bd9Sstevel@tonic-gate #include <math.h> 37*7c478bd9Sstevel@tonic-gate #include <alloca.h> 38*7c478bd9Sstevel@tonic-gate #include <assert.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #define NUM_OF_SEGMENT 1 42*7c478bd9Sstevel@tonic-gate #define SEGMENT_NAME_SIZE 2 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define FD_SEGMENT_SIZE 2949 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static char *command, *customer_data = NULL, *frupath = NULL, **svcargv; 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate /* DataElement supported in the customer operation */ 49*7c478bd9Sstevel@tonic-gate static char *cust_data_list[] = {"Customer_DataR"}; 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate /* DataElement supported in the service operation */ 52*7c478bd9Sstevel@tonic-gate static char *serv_data_list[] = {"InstallationR", "ECO_CurrentR"}; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* currently supported segment name */ 55*7c478bd9Sstevel@tonic-gate static char *segment_name[] = {"FD"}; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static int found_frupath = 0, list_only = 0, recursive = 0, 58*7c478bd9Sstevel@tonic-gate service_mode = 0, svcargc, update = 0; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate static void 62*7c478bd9Sstevel@tonic-gate usage(void) 63*7c478bd9Sstevel@tonic-gate { 64*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 65*7c478bd9Sstevel@tonic-gate gettext("Usage: %s [ -l ] | [ [ -r ] frupath [ text ] ]\n"), 66*7c478bd9Sstevel@tonic-gate command); 67*7c478bd9Sstevel@tonic-gate } 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static int 70*7c478bd9Sstevel@tonic-gate validate_fieldnames(int argc, char *argv[]) 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate static int num = sizeof (serv_data_list)/sizeof (*serv_data_list); 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate char *fieldname; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate int i, j, match, status; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate fru_elemdef_t definition; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i += 2) { 82*7c478bd9Sstevel@tonic-gate if (argv[i][0] == '/') { 83*7c478bd9Sstevel@tonic-gate fieldname = &argv[i][1]; 84*7c478bd9Sstevel@tonic-gate } else { 85*7c478bd9Sstevel@tonic-gate fieldname = &argv[i][0]; 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate match = 0; 89*7c478bd9Sstevel@tonic-gate for (j = 0; j < num; j++) { 90*7c478bd9Sstevel@tonic-gate if (strncmp(fieldname, serv_data_list[j], 91*7c478bd9Sstevel@tonic-gate strlen(serv_data_list[j])) == 0) { 92*7c478bd9Sstevel@tonic-gate match = 1; 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate if (!match) { 96*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 97*7c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a supported field\n"), 98*7c478bd9Sstevel@tonic-gate argv[i]); 99*7c478bd9Sstevel@tonic-gate return (1); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate if ((status = fru_get_definition(argv[i], &definition)) 103*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 104*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("\"%s\": %s\n"), 105*7c478bd9Sstevel@tonic-gate argv[i], 106*7c478bd9Sstevel@tonic-gate fru_strerror(status)); 107*7c478bd9Sstevel@tonic-gate return (1); 108*7c478bd9Sstevel@tonic-gate } else if ((definition.data_type == FDTYPE_Record) || 109*7c478bd9Sstevel@tonic-gate (definition.data_type == FDTYPE_UNDEFINED)) { 110*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 111*7c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a field\n"), argv[i]); 112*7c478bd9Sstevel@tonic-gate return (1); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate return (0); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate static int 120*7c478bd9Sstevel@tonic-gate pathmatch(const char *path) 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate char *match; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate if ((frupath != NULL) && 125*7c478bd9Sstevel@tonic-gate ((match = strstr(path, frupath)) != NULL) && 126*7c478bd9Sstevel@tonic-gate ((match + strlen(frupath)) == (path + strlen(path))) && 127*7c478bd9Sstevel@tonic-gate ((match == path) || (*(match - 1) == '/'))) { 128*7c478bd9Sstevel@tonic-gate found_frupath = 1; 129*7c478bd9Sstevel@tonic-gate return (1); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate return (0); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate static void 136*7c478bd9Sstevel@tonic-gate displayBinary(unsigned char *data, size_t length, fru_elemdef_t *def) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate int i = 0; 139*7c478bd9Sstevel@tonic-gate uint64_t lldata; 140*7c478bd9Sstevel@tonic-gate uint64_t mask; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (def->disp_type == FDISP_Hex) { 143*7c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 144*7c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate return; 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate (void) memcpy(&lldata, data, sizeof (lldata)); 150*7c478bd9Sstevel@tonic-gate switch (def->disp_type) { 151*7c478bd9Sstevel@tonic-gate case FDISP_Binary: 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate mask = 0x8000000000000000; 154*7c478bd9Sstevel@tonic-gate for (i = 0; i < (sizeof (uint64_t) *8); i++) { 155*7c478bd9Sstevel@tonic-gate if (lldata & (mask >> i)) { 156*7c478bd9Sstevel@tonic-gate (void) printf("1"); 157*7c478bd9Sstevel@tonic-gate } else { 158*7c478bd9Sstevel@tonic-gate (void) printf("0"); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate return; 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate case FDISP_Octal: 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate (void) printf("%llo", lldata); 166*7c478bd9Sstevel@tonic-gate return; 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate case FDISP_Decimal: 169*7c478bd9Sstevel@tonic-gate { 170*7c478bd9Sstevel@tonic-gate (void) printf("%lld", lldata); 171*7c478bd9Sstevel@tonic-gate return; 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate case FDISP_Time: 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate char buffer[PATH_MAX]; 176*7c478bd9Sstevel@tonic-gate time_t time; 177*7c478bd9Sstevel@tonic-gate time = (time_t)lldata; 178*7c478bd9Sstevel@tonic-gate (void) strftime(buffer, PATH_MAX, "%C", 179*7c478bd9Sstevel@tonic-gate localtime(&time)); 180*7c478bd9Sstevel@tonic-gate (void) printf("%s", buffer); 181*7c478bd9Sstevel@tonic-gate return; 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate static void 187*7c478bd9Sstevel@tonic-gate displayBAasBinary(unsigned char *data, size_t length) 188*7c478bd9Sstevel@tonic-gate { 189*7c478bd9Sstevel@tonic-gate int i; 190*7c478bd9Sstevel@tonic-gate unsigned char mask; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * make a mask for the high order bit and adjust down through 195*7c478bd9Sstevel@tonic-gate * all the bits. 196*7c478bd9Sstevel@tonic-gate */ 197*7c478bd9Sstevel@tonic-gate for (mask = 0x80; mask > 0; mask /= 2) { 198*7c478bd9Sstevel@tonic-gate if ((data[i] & mask) != 0) /* bit must be on */ 199*7c478bd9Sstevel@tonic-gate (void) printf("1"); 200*7c478bd9Sstevel@tonic-gate else /* bit is off... */ 201*7c478bd9Sstevel@tonic-gate (void) printf("0"); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate static void 208*7c478bd9Sstevel@tonic-gate display_data(unsigned char *data, size_t length, fru_elemdef_t *def) 209*7c478bd9Sstevel@tonic-gate { 210*7c478bd9Sstevel@tonic-gate int i = 0; 211*7c478bd9Sstevel@tonic-gate uint64_t lldata; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate if (data == 0x00) { 214*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 215*7c478bd9Sstevel@tonic-gate return; 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate switch (def->data_type) { 219*7c478bd9Sstevel@tonic-gate case FDTYPE_Binary: 220*7c478bd9Sstevel@tonic-gate { 221*7c478bd9Sstevel@tonic-gate displayBinary(data, length, def); 222*7c478bd9Sstevel@tonic-gate return; 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate case FDTYPE_ByteArray: 226*7c478bd9Sstevel@tonic-gate { 227*7c478bd9Sstevel@tonic-gate switch (def->disp_type) { 228*7c478bd9Sstevel@tonic-gate case FDISP_Binary: 229*7c478bd9Sstevel@tonic-gate displayBAasBinary(data, length); 230*7c478bd9Sstevel@tonic-gate return; 231*7c478bd9Sstevel@tonic-gate case FDISP_Hex: 232*7c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) { 233*7c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate return; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate return; 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate case FDTYPE_Unicode: 240*7c478bd9Sstevel@tonic-gate assert(gettext("Unicode not yet supported") == 0); 241*7c478bd9Sstevel@tonic-gate break; 242*7c478bd9Sstevel@tonic-gate case FDTYPE_ASCII: 243*7c478bd9Sstevel@tonic-gate { 244*7c478bd9Sstevel@tonic-gate char *disp_str = (char *)alloca(length+1); 245*7c478bd9Sstevel@tonic-gate for (i = 0; i < length; i++) 246*7c478bd9Sstevel@tonic-gate disp_str[i] = data[i]; 247*7c478bd9Sstevel@tonic-gate disp_str[i] = '\0'; 248*7c478bd9Sstevel@tonic-gate (void) printf("%s", disp_str); 249*7c478bd9Sstevel@tonic-gate return; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate case FDTYPE_Enumeration: 253*7c478bd9Sstevel@tonic-gate { 254*7c478bd9Sstevel@tonic-gate lldata = strtoull((const char *)data, NULL, 0); 255*7c478bd9Sstevel@tonic-gate for (i = 0; i < def->enum_count; i++) { 256*7c478bd9Sstevel@tonic-gate if (def->enum_table[i].value == lldata) { 257*7c478bd9Sstevel@tonic-gate /* strdup such that map_... can realloc if necessary. */ 258*7c478bd9Sstevel@tonic-gate char *tmp = strdup(def->enum_table[i].text); 259*7c478bd9Sstevel@tonic-gate (void) printf("%s", tmp); 260*7c478bd9Sstevel@tonic-gate free(tmp); 261*7c478bd9Sstevel@tonic-gate return; 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate (void) printf(gettext("Unrecognized Value: 0x")); 265*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (uint64_t); i++) 266*7c478bd9Sstevel@tonic-gate (void) printf("%02X", data[i]); 267*7c478bd9Sstevel@tonic-gate break; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate default: 270*7c478bd9Sstevel@tonic-gate break; 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate static void 275*7c478bd9Sstevel@tonic-gate print_node_data(fru_nodehdl_t cont_hdl) 276*7c478bd9Sstevel@tonic-gate { 277*7c478bd9Sstevel@tonic-gate int iter_cnt = 0; 278*7c478bd9Sstevel@tonic-gate int iter; 279*7c478bd9Sstevel@tonic-gate int numseg; 280*7c478bd9Sstevel@tonic-gate int list_cnt; 281*7c478bd9Sstevel@tonic-gate unsigned char *data; 282*7c478bd9Sstevel@tonic-gate size_t dataLen; 283*7c478bd9Sstevel@tonic-gate int total_cnt; 284*7c478bd9Sstevel@tonic-gate char *found_path = NULL; 285*7c478bd9Sstevel@tonic-gate fru_elemdef_t def, def1; 286*7c478bd9Sstevel@tonic-gate int instance = 0; 287*7c478bd9Sstevel@tonic-gate char **ptr; 288*7c478bd9Sstevel@tonic-gate char **tmp_ptr; 289*7c478bd9Sstevel@tonic-gate int count = 0; 290*7c478bd9Sstevel@tonic-gate char elem_name[PATH_MAX]; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate if (service_mode) { 293*7c478bd9Sstevel@tonic-gate total_cnt = sizeof (serv_data_list)/sizeof (*serv_data_list); 294*7c478bd9Sstevel@tonic-gate ptr = serv_data_list; 295*7c478bd9Sstevel@tonic-gate } else { 296*7c478bd9Sstevel@tonic-gate total_cnt = sizeof (cust_data_list)/sizeof (*cust_data_list); 297*7c478bd9Sstevel@tonic-gate ptr = cust_data_list; 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate tmp_ptr = ptr; 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate for (numseg = 0; numseg < NUM_OF_SEGMENT; numseg++) { 302*7c478bd9Sstevel@tonic-gate ptr = tmp_ptr; 303*7c478bd9Sstevel@tonic-gate for (list_cnt = 0; list_cnt < total_cnt; list_cnt++) { 304*7c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) != FRU_SUCCESS) { 305*7c478bd9Sstevel@tonic-gate continue; 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate if ((fru_get_num_iterations(cont_hdl, 308*7c478bd9Sstevel@tonic-gate &segment_name[numseg], 0, *ptr, 309*7c478bd9Sstevel@tonic-gate &iter_cnt, NULL)) != FRU_SUCCESS) { 310*7c478bd9Sstevel@tonic-gate iter_cnt = 0; 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate iter = 0; 313*7c478bd9Sstevel@tonic-gate do { 314*7c478bd9Sstevel@tonic-gate for (count = 0; count < def.enum_count; 315*7c478bd9Sstevel@tonic-gate count++) { 316*7c478bd9Sstevel@tonic-gate if (def.iteration_type != 317*7c478bd9Sstevel@tonic-gate FRU_NOT_ITERATED) { 318*7c478bd9Sstevel@tonic-gate (void) snprintf(elem_name, 319*7c478bd9Sstevel@tonic-gate sizeof (elem_name), 320*7c478bd9Sstevel@tonic-gate "/%s[%d]/%s", *ptr, iter, def.enum_table[count].text); 321*7c478bd9Sstevel@tonic-gate } else { 322*7c478bd9Sstevel@tonic-gate (void) snprintf(elem_name, 323*7c478bd9Sstevel@tonic-gate sizeof (elem_name), 324*7c478bd9Sstevel@tonic-gate "/%s/%s", *ptr, def.enum_table[count].text); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate if ((fru_read_field(cont_hdl, 328*7c478bd9Sstevel@tonic-gate &segment_name[numseg], instance, elem_name, (void**)&data, 329*7c478bd9Sstevel@tonic-gate &dataLen, &found_path)) != FRU_SUCCESS) { 330*7c478bd9Sstevel@tonic-gate break; 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate if ((fru_get_definition( 334*7c478bd9Sstevel@tonic-gate def.enum_table[count].text, &def1)) != FRU_SUCCESS) { 335*7c478bd9Sstevel@tonic-gate break; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate (void) printf(" %s: ",\ 338*7c478bd9Sstevel@tonic-gate elem_name); 339*7c478bd9Sstevel@tonic-gate display_data(data, dataLen, &def1); 340*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate iter ++; 343*7c478bd9Sstevel@tonic-gate } while (iter < iter_cnt); 344*7c478bd9Sstevel@tonic-gate ptr++; 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate static char * 350*7c478bd9Sstevel@tonic-gate convertBinaryToDecimal(char *ptr) 351*7c478bd9Sstevel@tonic-gate { 352*7c478bd9Sstevel@tonic-gate int cnt = 0; 353*7c478bd9Sstevel@tonic-gate char *data; 354*7c478bd9Sstevel@tonic-gate int str_len; 355*7c478bd9Sstevel@tonic-gate char *ret = NULL; 356*7c478bd9Sstevel@tonic-gate uint64_t result = 0; 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate str_len = strlen(ptr); 359*7c478bd9Sstevel@tonic-gate data = ptr; 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate while (str_len >= 1) { 362*7c478bd9Sstevel@tonic-gate str_len -= 1; 363*7c478bd9Sstevel@tonic-gate if (data[str_len] == '0') { 364*7c478bd9Sstevel@tonic-gate result += (0 * pow(2, cnt)); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate if (data[str_len] == '1') { 367*7c478bd9Sstevel@tonic-gate result += (1 * pow(2, cnt)); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate cnt++; 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate ret = (char *)lltostr(result, "\n"); 372*7c478bd9Sstevel@tonic-gate return (ret); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate /* 376*7c478bd9Sstevel@tonic-gate * called update_field() to update the field with specific field value. 377*7c478bd9Sstevel@tonic-gate * nodehdl represents the fru, segment represents the segment name in the fru. 378*7c478bd9Sstevel@tonic-gate * field_name represents the field to be updated with the value field_value. 379*7c478bd9Sstevel@tonic-gate */ 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate static int 382*7c478bd9Sstevel@tonic-gate convert_update(fru_nodehdl_t nodehdl, char *segment, char *field_name, 383*7c478bd9Sstevel@tonic-gate char *field_value) 384*7c478bd9Sstevel@tonic-gate { 385*7c478bd9Sstevel@tonic-gate uint64_t num = 0; 386*7c478bd9Sstevel@tonic-gate fru_elemdef_t def; 387*7c478bd9Sstevel@tonic-gate fru_errno_t err; 388*7c478bd9Sstevel@tonic-gate void *data = NULL; 389*7c478bd9Sstevel@tonic-gate size_t dataLen = 0; 390*7c478bd9Sstevel@tonic-gate int i; 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate if ((err = fru_get_definition(field_name, &def)) != FRU_SUCCESS) { 393*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 394*7c478bd9Sstevel@tonic-gate gettext("Failed to get definition %s: %s\n"), 395*7c478bd9Sstevel@tonic-gate field_name, fru_strerror(err)); 396*7c478bd9Sstevel@tonic-gate return (1); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate if (field_value == NULL) { 400*7c478bd9Sstevel@tonic-gate return (1); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate switch (def.data_type) { 404*7c478bd9Sstevel@tonic-gate case FDTYPE_Binary: 405*7c478bd9Sstevel@tonic-gate if (def.disp_type != FDISP_Time) { 406*7c478bd9Sstevel@tonic-gate if (field_value[0] == 'b') { 407*7c478bd9Sstevel@tonic-gate field_value = 408*7c478bd9Sstevel@tonic-gate convertBinaryToDecimal((field_value+1)); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate num = strtoll(field_value, (char **)NULL, 0); 411*7c478bd9Sstevel@tonic-gate if ((num == 0) && (errno == 0)) { 412*7c478bd9Sstevel@tonic-gate return (1); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate data = (void*)# 415*7c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate break; 418*7c478bd9Sstevel@tonic-gate case FDTYPE_ByteArray: 419*7c478bd9Sstevel@tonic-gate return (1); 420*7c478bd9Sstevel@tonic-gate case FDTYPE_Unicode: 421*7c478bd9Sstevel@tonic-gate return (1); 422*7c478bd9Sstevel@tonic-gate case FDTYPE_ASCII: 423*7c478bd9Sstevel@tonic-gate data = (void *) field_value; 424*7c478bd9Sstevel@tonic-gate dataLen = strlen(field_value); 425*7c478bd9Sstevel@tonic-gate if (dataLen < def.data_length) { 426*7c478bd9Sstevel@tonic-gate dataLen++; 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate break; 429*7c478bd9Sstevel@tonic-gate case FDTYPE_Enumeration: 430*7c478bd9Sstevel@tonic-gate for (i = 0; i < def.enum_count; i++) { 431*7c478bd9Sstevel@tonic-gate if (strcmp(def.enum_table[i].text, 432*7c478bd9Sstevel@tonic-gate field_value) == 0) { 433*7c478bd9Sstevel@tonic-gate data = (void *)def.enum_table[i].value; 434*7c478bd9Sstevel@tonic-gate dataLen = sizeof (uint64_t); 435*7c478bd9Sstevel@tonic-gate break; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate return (1); 439*7c478bd9Sstevel@tonic-gate case FDTYPE_Record: 440*7c478bd9Sstevel@tonic-gate if (def.iteration_count == 0) { 441*7c478bd9Sstevel@tonic-gate return (1); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate data = NULL; 444*7c478bd9Sstevel@tonic-gate dataLen = 0; 445*7c478bd9Sstevel@tonic-gate break; 446*7c478bd9Sstevel@tonic-gate case FDTYPE_UNDEFINED: 447*7c478bd9Sstevel@tonic-gate return (1); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, data, 451*7c478bd9Sstevel@tonic-gate dataLen)) != FRU_SUCCESS) { 452*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 453*7c478bd9Sstevel@tonic-gate fru_strerror(err)); 454*7c478bd9Sstevel@tonic-gate return (1); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate return (0); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate /* 459*7c478bd9Sstevel@tonic-gate * called by update_field() when a new data element is created. 460*7c478bd9Sstevel@tonic-gate * it updates the UNIX_Timestamp32 field with the current system time. 461*7c478bd9Sstevel@tonic-gate */ 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate static int 464*7c478bd9Sstevel@tonic-gate update_unixtimestamp(fru_nodehdl_t nodehdl, char *segment, char **ptr) 465*7c478bd9Sstevel@tonic-gate { 466*7c478bd9Sstevel@tonic-gate char *field_name; 467*7c478bd9Sstevel@tonic-gate time_t clock; 468*7c478bd9Sstevel@tonic-gate struct tm *sp_tm; 469*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 470*7c478bd9Sstevel@tonic-gate uint64_t time_data; 471*7c478bd9Sstevel@tonic-gate size_t len; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate len = strlen(*ptr) + strlen("UNIX_Timestamp32") + 3; 474*7c478bd9Sstevel@tonic-gate field_name = alloca(len); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate (void) snprintf(field_name, len, "/%s/UNIX_Timestamp32", *ptr); 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate clock = time(NULL); 479*7c478bd9Sstevel@tonic-gate sp_tm = localtime(&clock); 480*7c478bd9Sstevel@tonic-gate time_data = (uint64_t)mktime(sp_tm); 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate if ((err = fru_update_field(nodehdl, segment, 0, field_name, 483*7c478bd9Sstevel@tonic-gate (void *)&time_data, sizeof (time_data))) != FRU_SUCCESS) { 484*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fru_update_field(): %s\n"), 485*7c478bd9Sstevel@tonic-gate fru_strerror(err)); 486*7c478bd9Sstevel@tonic-gate return (1); 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate return (0); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate /* 492*7c478bd9Sstevel@tonic-gate * create segment on the specified fru represented by nodehdl. 493*7c478bd9Sstevel@tonic-gate */ 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate static int 496*7c478bd9Sstevel@tonic-gate create_segment(fru_nodehdl_t nodehdl) 497*7c478bd9Sstevel@tonic-gate { 498*7c478bd9Sstevel@tonic-gate fru_segdesc_t seg_desc; 499*7c478bd9Sstevel@tonic-gate fru_segdef_t def; 500*7c478bd9Sstevel@tonic-gate int cnt; 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate seg_desc.field.field_perm = 0x6; 503*7c478bd9Sstevel@tonic-gate seg_desc.field.operations_perm = 0x6; 504*7c478bd9Sstevel@tonic-gate seg_desc.field.engineering_perm = 0x6; 505*7c478bd9Sstevel@tonic-gate seg_desc.field.repair_perm = 0x6; 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate def.address = 0; 508*7c478bd9Sstevel@tonic-gate def.desc.raw_data = seg_desc.raw_data; 509*7c478bd9Sstevel@tonic-gate def.hw_desc.all_bits = 0; 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 512*7c478bd9Sstevel@tonic-gate (void) strncpy(def.name, segment_name[cnt], SEGMENT_NAME_SIZE); 513*7c478bd9Sstevel@tonic-gate if (cnt == 0) { 514*7c478bd9Sstevel@tonic-gate def.size = FD_SEGMENT_SIZE; 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate if ((fru_create_segment(nodehdl, &def)) != FRU_SUCCESS) { 517*7c478bd9Sstevel@tonic-gate continue; 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate return (cnt); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate return (1); 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate /* 525*7c478bd9Sstevel@tonic-gate * called from update_field() when service flag is ON. currently 526*7c478bd9Sstevel@tonic-gate * supported iterated record is InstallationR and fields supported for 527*7c478bd9Sstevel@tonic-gate * update are Geo_North, Geo_East, Geo_Alt, Geo_Location. 528*7c478bd9Sstevel@tonic-gate */ 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate static int 531*7c478bd9Sstevel@tonic-gate updateiter_record(fru_nodehdl_t nodehdl, int cnt, char **ptr, 532*7c478bd9Sstevel@tonic-gate char *field_name, char *field_value) 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate int iter_cnt = 0; 535*7c478bd9Sstevel@tonic-gate char rec_name[512]; 536*7c478bd9Sstevel@tonic-gate void *data = NULL; 537*7c478bd9Sstevel@tonic-gate char *tmpptr = NULL; 538*7c478bd9Sstevel@tonic-gate size_t dataLen = 0; 539*7c478bd9Sstevel@tonic-gate char **elem_ptr; 540*7c478bd9Sstevel@tonic-gate int found = 0; 541*7c478bd9Sstevel@tonic-gate int index; 542*7c478bd9Sstevel@tonic-gate int total_cnt; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate static char *elem_list[] = {"/Geo_North", "/Geo_East",\ 545*7c478bd9Sstevel@tonic-gate "/Geo_Alt", "/Geo_Location"}; 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate elem_ptr = elem_list; 548*7c478bd9Sstevel@tonic-gate total_cnt = sizeof (elem_list)/sizeof (*elem_list); 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate for (index = 0; index < total_cnt; index++) { 551*7c478bd9Sstevel@tonic-gate tmpptr = strrchr(field_name, '/'); 552*7c478bd9Sstevel@tonic-gate if (tmpptr == NULL) { 553*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 554*7c478bd9Sstevel@tonic-gate gettext("Error: Data Element not known\n")); 555*7c478bd9Sstevel@tonic-gate return (1); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate if ((strncmp(*elem_ptr, tmpptr, strlen(*elem_ptr)) != 0)) { 558*7c478bd9Sstevel@tonic-gate elem_ptr++; 559*7c478bd9Sstevel@tonic-gate continue; 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate found = 1; 562*7c478bd9Sstevel@tonic-gate break; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate if (found == 0) { 566*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 567*7c478bd9Sstevel@tonic-gate gettext("Error: Update not allowed for field: %s\n"), 568*7c478bd9Sstevel@tonic-gate field_name); 569*7c478bd9Sstevel@tonic-gate return (1); 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate if ((fru_get_num_iterations(nodehdl, &segment_name[cnt], 0, 573*7c478bd9Sstevel@tonic-gate *ptr, &iter_cnt, NULL)) != FRU_SUCCESS) { 574*7c478bd9Sstevel@tonic-gate return (1); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate /* add a new Iterated Record if complete path is not given */ 578*7c478bd9Sstevel@tonic-gate if (iter_cnt == 0) { 579*7c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[+]", *ptr); 580*7c478bd9Sstevel@tonic-gate if ((fru_update_field(nodehdl, segment_name[cnt], 0, 581*7c478bd9Sstevel@tonic-gate rec_name, data, dataLen)) != FRU_SUCCESS) { 582*7c478bd9Sstevel@tonic-gate return (1); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate iter_cnt = 1; 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]%s", 589*7c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1, strrchr(field_name, '/')); 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], rec_name, 592*7c478bd9Sstevel@tonic-gate field_value)) != 0) { 593*7c478bd9Sstevel@tonic-gate return (1); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate /* update success now update the unix timestamp */ 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate (void) snprintf(rec_name, sizeof (rec_name), "/%s[%d]", 599*7c478bd9Sstevel@tonic-gate *ptr, iter_cnt-1); 600*7c478bd9Sstevel@tonic-gate tmpptr = rec_name; 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 603*7c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 604*7c478bd9Sstevel@tonic-gate &tmpptr)) != 0) { 605*7c478bd9Sstevel@tonic-gate return (1); 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate return (0); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate static int 612*7c478bd9Sstevel@tonic-gate update_field(fru_nodehdl_t nodehdl, char *field_name, char *field_value) 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate fru_elemdef_t def; 615*7c478bd9Sstevel@tonic-gate unsigned char *data; 616*7c478bd9Sstevel@tonic-gate size_t dataLen; 617*7c478bd9Sstevel@tonic-gate char *found_path = NULL; 618*7c478bd9Sstevel@tonic-gate int cnt; 619*7c478bd9Sstevel@tonic-gate char **ptr; 620*7c478bd9Sstevel@tonic-gate fru_strlist_t elem; 621*7c478bd9Sstevel@tonic-gate int elem_cnt; 622*7c478bd9Sstevel@tonic-gate int add_flag = 1; 623*7c478bd9Sstevel@tonic-gate int total_cnt; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate if (service_mode) { 626*7c478bd9Sstevel@tonic-gate ptr = serv_data_list; 627*7c478bd9Sstevel@tonic-gate total_cnt = sizeof (serv_data_list)/sizeof (*serv_data_list); 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < total_cnt; cnt++) { 630*7c478bd9Sstevel@tonic-gate if ((strncmp(*ptr, &field_name[1], strlen(*ptr)) \ 631*7c478bd9Sstevel@tonic-gate != 0) && (strncmp(*ptr, &field_name[0], 632*7c478bd9Sstevel@tonic-gate strlen(*ptr)) != 0)) { 633*7c478bd9Sstevel@tonic-gate ptr++; 634*7c478bd9Sstevel@tonic-gate add_flag = 0; 635*7c478bd9Sstevel@tonic-gate continue; 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate add_flag = 1; 638*7c478bd9Sstevel@tonic-gate break; 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate } else { 641*7c478bd9Sstevel@tonic-gate ptr = cust_data_list; 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate /* look for the field in either of the segment if found update it */ 645*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 646*7c478bd9Sstevel@tonic-gate if ((fru_read_field(nodehdl, &segment_name[cnt], 0, field_name, 647*7c478bd9Sstevel@tonic-gate (void **) &data, &dataLen, &found_path)) != FRU_SUCCESS) { 648*7c478bd9Sstevel@tonic-gate continue; 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 651*7c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 652*7c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 653*7c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 654*7c478bd9Sstevel@tonic-gate return (1); 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate return (0); 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], 661*7c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 662*7c478bd9Sstevel@tonic-gate return (1); 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with update time */ 666*7c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 667*7c478bd9Sstevel@tonic-gate ptr)) != 0) { 668*7c478bd9Sstevel@tonic-gate return (1); 669*7c478bd9Sstevel@tonic-gate } 670*7c478bd9Sstevel@tonic-gate return (0); 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate elem.num = 0; 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate /* field not found add the the record in one of the segment */ 676*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < NUM_OF_SEGMENT; cnt++) { 677*7c478bd9Sstevel@tonic-gate fru_list_elems_in(nodehdl, segment_name[cnt], &elem); 678*7c478bd9Sstevel@tonic-gate for (elem_cnt = 0; elem_cnt < elem.num; elem_cnt++) { 679*7c478bd9Sstevel@tonic-gate if ((strcmp(*ptr, elem.strs[elem_cnt])) == 0) { 680*7c478bd9Sstevel@tonic-gate add_flag = 0; 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate if (add_flag) { 685*7c478bd9Sstevel@tonic-gate if ((fru_add_element(nodehdl, segment_name[cnt], 686*7c478bd9Sstevel@tonic-gate *ptr)) != FRU_SUCCESS) { 687*7c478bd9Sstevel@tonic-gate continue; 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 692*7c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 693*7c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 694*7c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 695*7c478bd9Sstevel@tonic-gate return (1); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate return (0); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 702*7c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 703*7c478bd9Sstevel@tonic-gate ptr)) != 0) { 704*7c478bd9Sstevel@tonic-gate return (1); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* record added update the field with the value */ 708*7c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 709*7c478bd9Sstevel@tonic-gate field_value)) != 0) { 710*7c478bd9Sstevel@tonic-gate return (1); 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate return (0); 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate /* segment not present, create one and add the record */ 716*7c478bd9Sstevel@tonic-gate cnt = create_segment(nodehdl); 717*7c478bd9Sstevel@tonic-gate if (cnt == 1) { 718*7c478bd9Sstevel@tonic-gate return (1); 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate if ((fru_add_element(nodehdl, segment_name[cnt], *ptr)) 722*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 723*7c478bd9Sstevel@tonic-gate return (1); 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate if ((fru_get_definition(*ptr, &def)) == FRU_SUCCESS) { 727*7c478bd9Sstevel@tonic-gate if (def.iteration_count != 0) { 728*7c478bd9Sstevel@tonic-gate if ((updateiter_record(nodehdl, cnt, ptr, 729*7c478bd9Sstevel@tonic-gate field_name, field_value)) != 0) { 730*7c478bd9Sstevel@tonic-gate return (1); 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate return (0); 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate /* update UNIX_Timestamp32 with creation time */ 737*7c478bd9Sstevel@tonic-gate if ((update_unixtimestamp(nodehdl, segment_name[cnt], 738*7c478bd9Sstevel@tonic-gate ptr)) != 0) { 739*7c478bd9Sstevel@tonic-gate return (1); 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate if ((convert_update(nodehdl, segment_name[cnt], field_name, 743*7c478bd9Sstevel@tonic-gate field_value)) != 0) { 744*7c478bd9Sstevel@tonic-gate return (1); 745*7c478bd9Sstevel@tonic-gate } 746*7c478bd9Sstevel@tonic-gate return (0); 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate static void 750*7c478bd9Sstevel@tonic-gate update_node_data(fru_nodehdl_t node) 751*7c478bd9Sstevel@tonic-gate { 752*7c478bd9Sstevel@tonic-gate int i; 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate if (service_mode) { 755*7c478bd9Sstevel@tonic-gate for (i = 0; i < svcargc; i += 2) 756*7c478bd9Sstevel@tonic-gate (void) update_field(node, svcargv[i], svcargv[i + 1]); 757*7c478bd9Sstevel@tonic-gate } else { 758*7c478bd9Sstevel@tonic-gate (void) update_field(node, "/Customer_DataR/Cust_Data", 759*7c478bd9Sstevel@tonic-gate customer_data); 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate static void 764*7c478bd9Sstevel@tonic-gate walk_tree(fru_nodehdl_t node, const char *prior_path, int process_tree) 765*7c478bd9Sstevel@tonic-gate { 766*7c478bd9Sstevel@tonic-gate char *name, path[PATH_MAX]; 767*7c478bd9Sstevel@tonic-gate int process_self = process_tree, status; 768*7c478bd9Sstevel@tonic-gate fru_nodehdl_t next_node; 769*7c478bd9Sstevel@tonic-gate fru_node_t type; 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate if ((status = fru_get_node_type(node, &type)) != FRU_SUCCESS) { 772*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 773*7c478bd9Sstevel@tonic-gate gettext("Error getting FRU tree node type: %s\n"), 774*7c478bd9Sstevel@tonic-gate fru_strerror(status)); 775*7c478bd9Sstevel@tonic-gate exit(1); 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate if ((status = fru_get_name_from_hdl(node, &name)) != FRU_SUCCESS) { 779*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 780*7c478bd9Sstevel@tonic-gate gettext("Error getting name of FRU tree node: %s\n"), 781*7c478bd9Sstevel@tonic-gate fru_strerror(status)); 782*7c478bd9Sstevel@tonic-gate exit(1); 783*7c478bd9Sstevel@tonic-gate } 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate /* 787*7c478bd9Sstevel@tonic-gate * Build the current path 788*7c478bd9Sstevel@tonic-gate */ 789*7c478bd9Sstevel@tonic-gate if (snprintf(path, sizeof (path), "%s/%s", prior_path, name) 790*7c478bd9Sstevel@tonic-gate >= sizeof (path)) { 791*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 792*7c478bd9Sstevel@tonic-gate gettext("FRU tree path would overflow buffer\n")); 793*7c478bd9Sstevel@tonic-gate exit(1); 794*7c478bd9Sstevel@tonic-gate } 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate free(name); 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * Process the node 800*7c478bd9Sstevel@tonic-gate */ 801*7c478bd9Sstevel@tonic-gate if (list_only) { 802*7c478bd9Sstevel@tonic-gate (void) printf("%s%s\n", path, ((type == FRU_NODE_FRU) ? 803*7c478bd9Sstevel@tonic-gate " (fru)" : ((type == FRU_NODE_CONTAINER) ? 804*7c478bd9Sstevel@tonic-gate " (container)" : ""))); 805*7c478bd9Sstevel@tonic-gate } else if ((process_tree || (process_self = pathmatch(path))) && 806*7c478bd9Sstevel@tonic-gate (type == FRU_NODE_CONTAINER)) { 807*7c478bd9Sstevel@tonic-gate (void) printf("%s\n", path); 808*7c478bd9Sstevel@tonic-gate if (update) update_node_data(node); 809*7c478bd9Sstevel@tonic-gate print_node_data(node); 810*7c478bd9Sstevel@tonic-gate if (!recursive) exit(0); 811*7c478bd9Sstevel@tonic-gate } else if (process_self && !recursive) { 812*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 813*7c478bd9Sstevel@tonic-gate gettext("\"%s\" is not a container\n"), path); 814*7c478bd9Sstevel@tonic-gate exit(1); 815*7c478bd9Sstevel@tonic-gate } 816*7c478bd9Sstevel@tonic-gate 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate /* 819*7c478bd9Sstevel@tonic-gate * Recurse 820*7c478bd9Sstevel@tonic-gate */ 821*7c478bd9Sstevel@tonic-gate if (fru_get_child(node, &next_node) == FRU_SUCCESS) 822*7c478bd9Sstevel@tonic-gate walk_tree(next_node, path, process_self); 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate if (fru_get_peer(node, &next_node) == FRU_SUCCESS) 825*7c478bd9Sstevel@tonic-gate walk_tree(next_node, prior_path, process_tree); 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate static int 829*7c478bd9Sstevel@tonic-gate has_system_controller() 830*7c478bd9Sstevel@tonic-gate { 831*7c478bd9Sstevel@tonic-gate char platform[PATH_MAX]; 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate int size; 834*7c478bd9Sstevel@tonic-gate 835*7c478bd9Sstevel@tonic-gate if (((size = sysinfo(SI_PLATFORM, platform, sizeof (platform))) 836*7c478bd9Sstevel@tonic-gate < 0) || (size > sizeof (platform))) 837*7c478bd9Sstevel@tonic-gate return (-1); 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate if ((strcmp("SUNW,Sun-Fire", platform) == 0) || 840*7c478bd9Sstevel@tonic-gate (strcmp("SUNW,Sun-Fire-15000", platform) == 0)) { 841*7c478bd9Sstevel@tonic-gate return (1); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate return (0); 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate int 848*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 849*7c478bd9Sstevel@tonic-gate { 850*7c478bd9Sstevel@tonic-gate int process_tree = 0, option, status; 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate fru_nodehdl_t root; 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate command = argv[0]; 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate opterr = 0; /* "getopt" should not print to "stderr" */ 858*7c478bd9Sstevel@tonic-gate while ((option = getopt(argc, argv, "lrs")) != EOF) { 859*7c478bd9Sstevel@tonic-gate switch (option) { 860*7c478bd9Sstevel@tonic-gate case 'l': 861*7c478bd9Sstevel@tonic-gate list_only = 1; 862*7c478bd9Sstevel@tonic-gate break; 863*7c478bd9Sstevel@tonic-gate case 'r': 864*7c478bd9Sstevel@tonic-gate recursive = 1; 865*7c478bd9Sstevel@tonic-gate break; 866*7c478bd9Sstevel@tonic-gate case 's': 867*7c478bd9Sstevel@tonic-gate service_mode = 1; 868*7c478bd9Sstevel@tonic-gate break; 869*7c478bd9Sstevel@tonic-gate default: 870*7c478bd9Sstevel@tonic-gate usage(); 871*7c478bd9Sstevel@tonic-gate return (1); 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate argc -= optind; 876*7c478bd9Sstevel@tonic-gate argv += optind; 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate if (argc == 0) { 879*7c478bd9Sstevel@tonic-gate process_tree = 1; 880*7c478bd9Sstevel@tonic-gate recursive = 1; 881*7c478bd9Sstevel@tonic-gate } else { 882*7c478bd9Sstevel@tonic-gate if (list_only) { 883*7c478bd9Sstevel@tonic-gate usage(); 884*7c478bd9Sstevel@tonic-gate return (1); 885*7c478bd9Sstevel@tonic-gate } 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate frupath = argv[0]; 888*7c478bd9Sstevel@tonic-gate if (*frupath == 0) { 889*7c478bd9Sstevel@tonic-gate usage(); 890*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 891*7c478bd9Sstevel@tonic-gate gettext("\"frupath\" should not be empty\n")); 892*7c478bd9Sstevel@tonic-gate return (1); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate 895*7c478bd9Sstevel@tonic-gate argc--; 896*7c478bd9Sstevel@tonic-gate argv++; 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate if (argc > 0) { 899*7c478bd9Sstevel@tonic-gate update = 1; 900*7c478bd9Sstevel@tonic-gate if (service_mode) { 901*7c478bd9Sstevel@tonic-gate if ((argc % 2) != 0) { 902*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 903*7c478bd9Sstevel@tonic-gate gettext("Must specify " 904*7c478bd9Sstevel@tonic-gate "field-value pairs " 905*7c478bd9Sstevel@tonic-gate "for update\n")); 906*7c478bd9Sstevel@tonic-gate return (1); 907*7c478bd9Sstevel@tonic-gate } 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate if (validate_fieldnames(argc, argv) != 0) { 910*7c478bd9Sstevel@tonic-gate return (1); 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate svcargc = argc; 914*7c478bd9Sstevel@tonic-gate svcargv = argv; 915*7c478bd9Sstevel@tonic-gate } else if (argc == 1) 916*7c478bd9Sstevel@tonic-gate customer_data = argv[0]; 917*7c478bd9Sstevel@tonic-gate else { 918*7c478bd9Sstevel@tonic-gate usage(); 919*7c478bd9Sstevel@tonic-gate return (1); 920*7c478bd9Sstevel@tonic-gate } 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate if ((status = fru_open_data_source("picl", NULL)) != FRU_SUCCESS) { 925*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 926*7c478bd9Sstevel@tonic-gate gettext("Unable to access FRU data source: %s\n"), 927*7c478bd9Sstevel@tonic-gate fru_strerror(status)); 928*7c478bd9Sstevel@tonic-gate return (1); 929*7c478bd9Sstevel@tonic-gate } 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate if ((status = fru_get_root(&root)) == FRU_NODENOTFOUND) { 932*7c478bd9Sstevel@tonic-gate if (has_system_controller() == 1) { 933*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 934*7c478bd9Sstevel@tonic-gate gettext("Access FRUs from the " 935*7c478bd9Sstevel@tonic-gate "System Controller\n")); 936*7c478bd9Sstevel@tonic-gate } else { 937*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 938*7c478bd9Sstevel@tonic-gate gettext("This system does not provide " 939*7c478bd9Sstevel@tonic-gate "FRU ID data\n")); 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate } 942*7c478bd9Sstevel@tonic-gate return (1); 943*7c478bd9Sstevel@tonic-gate } else if (status != FRU_SUCCESS) { 944*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 945*7c478bd9Sstevel@tonic-gate gettext("Unable to access FRU ID data " 946*7c478bd9Sstevel@tonic-gate "due to data source error\n")); 947*7c478bd9Sstevel@tonic-gate return (1); 948*7c478bd9Sstevel@tonic-gate } 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate walk_tree(root, "", process_tree); 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate if ((frupath != NULL) && (!found_frupath)) { 953*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 954*7c478bd9Sstevel@tonic-gate gettext("\"%s\" not found\n"), 955*7c478bd9Sstevel@tonic-gate frupath); 956*7c478bd9Sstevel@tonic-gate return (1); 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate 959*7c478bd9Sstevel@tonic-gate return (0); 960*7c478bd9Sstevel@tonic-gate } 961