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