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