1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. 24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <sys/sysmacros.h> 29 #include <sys/param.h> 30 31 #include <smbios.h> 32 #include <alloca.h> 33 #include <limits.h> 34 #include <unistd.h> 35 #include <strings.h> 36 #include <stdlib.h> 37 #include <stdarg.h> 38 #include <stdio.h> 39 #include <fcntl.h> 40 #include <errno.h> 41 #include <ctype.h> 42 43 #define SMBIOS_SUCCESS 0 44 #define SMBIOS_ERROR 1 45 #define SMBIOS_USAGE 2 46 47 static const char *g_pname; 48 static int g_hdr; 49 50 static int opt_e; 51 static int opt_i = -1; 52 static int opt_O; 53 static int opt_s; 54 static int opt_t = -1; 55 static int opt_x; 56 57 /*PRINTFLIKE2*/ 58 static void 59 oprintf(FILE *fp, const char *format, ...) 60 { 61 va_list ap; 62 63 va_start(ap, format); 64 (void) vfprintf(fp, format, ap); 65 va_end(ap); 66 } 67 68 /*PRINTFLIKE3*/ 69 static void 70 desc_printf(const char *d, FILE *fp, const char *format, ...) 71 { 72 va_list ap; 73 74 va_start(ap, format); 75 (void) vfprintf(fp, format, ap); 76 va_end(ap); 77 78 if (d != NULL) 79 (void) fprintf(fp, " (%s)\n", d); 80 else 81 (void) fprintf(fp, "\n"); 82 } 83 84 static void 85 flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits, 86 const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t)) 87 { 88 size_t i; 89 90 oprintf(fp, " %s: 0x%x\n", s, flags); 91 92 for (i = 0; i < bits; i++) { 93 uint_t f = 1 << i; 94 const char *n; 95 96 if (!(flags & f)) 97 continue; 98 99 if ((n = flag_name(f)) != NULL) 100 desc_printf(flag_desc(f), fp, "\t%s", n); 101 else 102 desc_printf(flag_desc(f), fp, "\t0x%x", f); 103 } 104 } 105 106 static void 107 flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits, 108 const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t)) 109 { 110 size_t i; 111 112 oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags); 113 114 for (i = 0; i < bits; i++) { 115 u_longlong_t f = 1ULL << i; 116 const char *n; 117 118 if (!(flags & f)) 119 continue; 120 121 if ((n = flag_name(f)) != NULL) 122 desc_printf(flag_desc(f), fp, "\t%s", n); 123 else 124 desc_printf(flag_desc(f), fp, "\t0x%llx", f); 125 } 126 } 127 128 static void 129 id_printf(FILE *fp, const char *s, id_t id) 130 { 131 switch (id) { 132 case SMB_ID_NONE: 133 oprintf(fp, "%sNone\n", s); 134 break; 135 case SMB_ID_NOTSUP: 136 oprintf(fp, "%sNot Supported\n", s); 137 break; 138 default: 139 oprintf(fp, "%s%u\n", s, (uint_t)id); 140 } 141 } 142 143 static int 144 check_oem(smbios_hdl_t *shp) 145 { 146 int i; 147 int cnt; 148 int rv; 149 id_t oem_id; 150 smbios_struct_t s; 151 const char **oem_str; 152 153 rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s); 154 if (rv != 0) { 155 return (-1); 156 } 157 158 oem_id = s.smbstr_id; 159 160 cnt = smbios_info_strtab(shp, oem_id, 0, NULL); 161 if (cnt > 0) { 162 oem_str = alloca(sizeof (char *) * cnt); 163 (void) smbios_info_strtab(shp, oem_id, cnt, oem_str); 164 165 for (i = 0; i < cnt; i++) { 166 if (strncmp(oem_str[i], SMB_PRMS1, 167 strlen(SMB_PRMS1) + 1) == 0) { 168 return (0); 169 } 170 } 171 } 172 173 return (-1); 174 } 175 176 static void 177 print_smbios(smbios_hdl_t *shp, FILE *fp) 178 { 179 smbios_entry_t ep; 180 int i; 181 182 smbios_info_smbios(shp, &ep); 183 184 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 185 (int)sizeof (ep.smbe_eanchor), (int)sizeof (ep.smbe_eanchor), 186 ep.smbe_eanchor); 187 188 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep.smbe_ecksum); 189 oprintf(fp, "Entry Point Length: %u\n", ep.smbe_elen); 190 oprintf(fp, "Entry Point Version: %u.%u\n", 191 ep.smbe_major, ep.smbe_minor); 192 oprintf(fp, "Max Structure Size: %u\n", ep.smbe_maxssize); 193 oprintf(fp, "Entry Point Revision: 0x%x\n", ep.smbe_revision); 194 195 oprintf(fp, "Entry Point Revision Data:"); 196 for (i = 0; i < sizeof (ep.smbe_format); i++) 197 oprintf(fp, " 0x%02x", ep.smbe_format[i]); 198 oprintf(fp, "\n"); 199 200 oprintf(fp, "Intermediate Anchor Tag: %*.*s\n", 201 (int)sizeof (ep.smbe_ianchor), (int)sizeof (ep.smbe_ianchor), 202 ep.smbe_ianchor); 203 204 oprintf(fp, "Intermediate Checksum: 0x%x\n", ep.smbe_icksum); 205 oprintf(fp, "Structure Table Length: %u\n", ep.smbe_stlen); 206 oprintf(fp, "Structure Table Address: 0x%x\n", ep.smbe_staddr); 207 oprintf(fp, "Structure Table Entries: %u\n", ep.smbe_stnum); 208 oprintf(fp, "DMI BCD Revision: 0x%x\n", ep.smbe_bcdrev); 209 } 210 211 static void 212 print_common(const smbios_info_t *ip, FILE *fp) 213 { 214 if (ip->smbi_manufacturer[0] != '\0') 215 oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer); 216 if (ip->smbi_product[0] != '\0') 217 oprintf(fp, " Product: %s\n", ip->smbi_product); 218 if (ip->smbi_version[0] != '\0') 219 oprintf(fp, " Version: %s\n", ip->smbi_version); 220 if (ip->smbi_serial[0] != '\0') 221 oprintf(fp, " Serial Number: %s\n", ip->smbi_serial); 222 if (ip->smbi_asset[0] != '\0') 223 oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset); 224 if (ip->smbi_location[0] != '\0') 225 oprintf(fp, " Location Tag: %s\n", ip->smbi_location); 226 if (ip->smbi_part[0] != '\0') 227 oprintf(fp, " Part Number: %s\n", ip->smbi_part); 228 } 229 230 static void 231 print_bios(smbios_hdl_t *shp, FILE *fp) 232 { 233 smbios_bios_t b; 234 235 (void) smbios_info_bios(shp, &b); 236 237 oprintf(fp, " Vendor: %s\n", b.smbb_vendor); 238 oprintf(fp, " Version String: %s\n", b.smbb_version); 239 oprintf(fp, " Release Date: %s\n", b.smbb_reldate); 240 oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment); 241 oprintf(fp, " ROM Size: %u bytes\n", b.smbb_romsize); 242 oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize); 243 244 flag64_printf(fp, "Characteristics", 245 b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY, 246 smbios_bios_flag_name, smbios_bios_flag_desc); 247 248 if (b.smbb_nxcflags > SMB_BIOSXB_1) { 249 flag_printf(fp, "Characteristics Extension Byte 1", 250 b.smbb_xcflags[SMB_BIOSXB_1], 251 sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY, 252 smbios_bios_xb1_name, smbios_bios_xb1_desc); 253 } 254 255 if (b.smbb_nxcflags > SMB_BIOSXB_2) { 256 flag_printf(fp, "Characteristics Extension Byte 2", 257 b.smbb_xcflags[SMB_BIOSXB_2], 258 sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY, 259 smbios_bios_xb2_name, smbios_bios_xb2_desc); 260 } 261 262 if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) { 263 oprintf(fp, " Version Number: %u.%u\n", 264 b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor); 265 } 266 267 if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN) { 268 oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n", 269 b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor); 270 } 271 } 272 273 static void 274 print_system(smbios_hdl_t *shp, FILE *fp) 275 { 276 smbios_system_t s; 277 uint_t i; 278 279 (void) smbios_info_system(shp, &s); 280 281 oprintf(fp, " UUID: "); 282 for (i = 0; i < s.smbs_uuidlen; i++) { 283 oprintf(fp, "%02x", s.smbs_uuid[i]); 284 if (i == 3 || i == 5 || i == 7 || i == 9) 285 oprintf(fp, "-"); 286 } 287 oprintf(fp, "\n"); 288 289 desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup), 290 fp, " Wake-Up Event: 0x%x", s.smbs_wakeup); 291 292 oprintf(fp, " SKU Number: %s\n", s.smbs_sku); 293 oprintf(fp, " Family: %s\n", s.smbs_family); 294 } 295 296 static void 297 print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp) 298 { 299 smbios_bboard_t b; 300 int chdl_cnt; 301 302 (void) smbios_info_bboard(shp, id, &b); 303 304 oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis); 305 306 flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY, 307 smbios_bboard_flag_name, smbios_bboard_flag_desc); 308 309 desc_printf(smbios_bboard_type_desc(b.smbb_type), 310 fp, " Board Type: 0x%x", b.smbb_type); 311 312 chdl_cnt = b.smbb_contn; 313 if (chdl_cnt != 0) { 314 id_t *chdl; 315 uint16_t hdl; 316 int i, n, cnt; 317 318 chdl = alloca(chdl_cnt * sizeof (id_t)); 319 cnt = smbios_info_contains(shp, id, chdl_cnt, chdl); 320 if (cnt > SMB_CONT_MAX) 321 return; 322 n = MIN(chdl_cnt, cnt); 323 324 oprintf(fp, "\n"); 325 for (i = 0; i < n; i++) { 326 hdl = (uint16_t)chdl[i]; 327 oprintf(fp, " Contained Handle: %u\n", hdl); 328 } 329 } 330 } 331 332 static void 333 print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp) 334 { 335 smbios_chassis_t c; 336 int elem_cnt; 337 338 (void) smbios_info_chassis(shp, id, &c); 339 340 oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata); 341 oprintf(fp, " SKU number: %s\n", 342 c.smbc_sku == NULL ? "<unknown>" : c.smbc_sku); 343 oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N"); 344 345 desc_printf(smbios_chassis_type_desc(c.smbc_type), 346 fp, " Chassis Type: 0x%x", c.smbc_type); 347 348 desc_printf(smbios_chassis_state_desc(c.smbc_bustate), 349 fp, " Boot-Up State: 0x%x", c.smbc_bustate); 350 351 desc_printf(smbios_chassis_state_desc(c.smbc_psstate), 352 fp, " Power Supply State: 0x%x", c.smbc_psstate); 353 354 desc_printf(smbios_chassis_state_desc(c.smbc_thstate), 355 fp, " Thermal State: 0x%x", c.smbc_thstate); 356 357 oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight); 358 oprintf(fp, " Power Cords: %u\n", c.smbc_cords); 359 360 elem_cnt = c.smbc_elems; 361 oprintf(fp, " Element Records: %u\n", elem_cnt); 362 363 if (elem_cnt > 0) { 364 id_t *elems; 365 uint8_t type; 366 int i, n, cnt; 367 368 elems = alloca(c.smbc_elems * sizeof (id_t)); 369 cnt = smbios_info_contains(shp, id, elem_cnt, elems); 370 if (cnt > SMB_CONT_MAX) 371 return; 372 n = MIN(elem_cnt, cnt); 373 374 oprintf(fp, "\n"); 375 for (i = 0; i < n; i++) { 376 type = (uint8_t)elems[i]; 377 if (type & 0x80) { 378 /* SMBIOS structrure Type */ 379 desc_printf(smbios_type_name(type & 0x7f), fp, 380 " Contained SMBIOS structure Type: %u", 381 type & 0x80); 382 } else { 383 /* SMBIOS Base Board Type */ 384 desc_printf(smbios_bboard_type_desc(type), fp, 385 " Contained SMBIOS Base Board Type: 0x%x", 386 type); 387 } 388 } 389 } 390 } 391 392 static void 393 print_processor(smbios_hdl_t *shp, id_t id, FILE *fp) 394 { 395 smbios_processor_t p; 396 uint_t status; 397 398 (void) smbios_info_processor(shp, id, &p); 399 status = SMB_PRSTATUS_STATUS(p.smbp_status); 400 401 desc_printf(smbios_processor_family_desc(p.smbp_family), 402 fp, " Family: %u", p.smbp_family); 403 404 if (p.smbp_family2 != 0) 405 desc_printf(smbios_processor_family_desc(p.smbp_family2), 406 fp, " Family Ext: %u", p.smbp_family2); 407 408 oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid); 409 410 desc_printf(smbios_processor_type_desc(p.smbp_type), 411 fp, " Type: %u", p.smbp_type); 412 413 desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade), 414 fp, " Socket Upgrade: %u", p.smbp_upgrade); 415 416 oprintf(fp, " Socket Status: %s\n", 417 SMB_PRSTATUS_PRESENT(p.smbp_status) ? 418 "Populated" : "Not Populated"); 419 420 desc_printf(smbios_processor_status_desc(status), 421 fp, " Processor Status: %u", status); 422 423 if (SMB_PRV_LEGACY(p.smbp_voltage)) { 424 oprintf(fp, " Supported Voltages:"); 425 switch (p.smbp_voltage) { 426 case SMB_PRV_5V: 427 oprintf(fp, " 5.0V"); 428 break; 429 case SMB_PRV_33V: 430 oprintf(fp, " 3.3V"); 431 break; 432 case SMB_PRV_29V: 433 oprintf(fp, " 2.9V"); 434 break; 435 } 436 oprintf(fp, "\n"); 437 } else { 438 oprintf(fp, " Supported Voltages: %.1fV\n", 439 (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10); 440 } 441 442 if (p.smbp_corecount != 0) 443 oprintf(fp, " Core Count: %u\n", p.smbp_corecount); 444 else 445 oprintf(fp, " Core Count: Unknown\n"); 446 447 if (p.smbp_coresenabled != 0) 448 oprintf(fp, " Cores Enabled: %u\n", p.smbp_coresenabled); 449 else 450 oprintf(fp, " Cores Enabled: Unknown\n"); 451 452 if (p.smbp_threadcount != 0) 453 oprintf(fp, " Thread Count: %u\n", p.smbp_threadcount); 454 else 455 oprintf(fp, " Thread Count: Unknown\n"); 456 457 if (p.smbp_cflags) { 458 flag_printf(fp, "Processor Characteristics", 459 p.smbp_cflags, sizeof (p.smbp_cflags) * NBBY, 460 smbios_processor_core_flag_name, 461 smbios_processor_core_flag_desc); 462 } 463 464 if (p.smbp_clkspeed != 0) 465 oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed); 466 else 467 oprintf(fp, " External Clock Speed: Unknown\n"); 468 469 if (p.smbp_maxspeed != 0) 470 oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed); 471 else 472 oprintf(fp, " Maximum Speed: Unknown\n"); 473 474 if (p.smbp_curspeed != 0) 475 oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed); 476 else 477 oprintf(fp, " Current Speed: Unknown\n"); 478 479 id_printf(fp, " L1 Cache: ", p.smbp_l1cache); 480 id_printf(fp, " L2 Cache: ", p.smbp_l2cache); 481 id_printf(fp, " L3 Cache: ", p.smbp_l3cache); 482 } 483 484 static void 485 print_cache(smbios_hdl_t *shp, id_t id, FILE *fp) 486 { 487 smbios_cache_t c; 488 489 (void) smbios_info_cache(shp, id, &c); 490 491 oprintf(fp, " Level: %u\n", c.smba_level); 492 oprintf(fp, " Maximum Installed Size: %u bytes\n", c.smba_maxsize); 493 494 if (c.smba_size != 0) 495 oprintf(fp, " Installed Size: %u bytes\n", c.smba_size); 496 else 497 oprintf(fp, " Installed Size: Not Installed\n"); 498 499 if (c.smba_speed != 0) 500 oprintf(fp, " Speed: %uns\n", c.smba_speed); 501 else 502 oprintf(fp, " Speed: Unknown\n"); 503 504 flag_printf(fp, "Supported SRAM Types", 505 c.smba_stype, sizeof (c.smba_stype) * NBBY, 506 smbios_cache_ctype_name, smbios_cache_ctype_desc); 507 508 desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 509 fp, " Current SRAM Type: 0x%x", c.smba_ctype); 510 511 desc_printf(smbios_cache_ecc_desc(c.smba_etype), 512 fp, " Error Correction Type: %u", c.smba_etype); 513 514 desc_printf(smbios_cache_logical_desc(c.smba_ltype), 515 fp, " Logical Cache Type: %u", c.smba_ltype); 516 517 desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 518 fp, " Associativity: %u", c.smba_assoc); 519 520 desc_printf(smbios_cache_mode_desc(c.smba_mode), 521 fp, " Mode: %u", c.smba_mode); 522 523 desc_printf(smbios_cache_loc_desc(c.smba_location), 524 fp, " Location: %u", c.smba_location); 525 526 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 527 smbios_cache_flag_name, smbios_cache_flag_desc); 528 } 529 530 static void 531 print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 532 { 533 smbios_port_t p; 534 535 (void) smbios_info_port(shp, id, &p); 536 537 oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref); 538 oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref); 539 540 desc_printf(smbios_port_conn_desc(p.smbo_itype), 541 fp, " Internal Connector Type: %u", p.smbo_itype); 542 543 desc_printf(smbios_port_conn_desc(p.smbo_etype), 544 fp, " External Connector Type: %u", p.smbo_etype); 545 546 desc_printf(smbios_port_type_desc(p.smbo_ptype), 547 fp, " Port Type: %u", p.smbo_ptype); 548 } 549 550 static void 551 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 552 { 553 smbios_slot_t s; 554 smbios_entry_t e; 555 556 (void) smbios_info_slot(shp, id, &s); 557 (void) smbios_info_smbios(shp, &e); 558 559 oprintf(fp, " Reference Designator: %s\n", s.smbl_name); 560 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 561 562 desc_printf(smbios_slot_type_desc(s.smbl_type), 563 fp, " Type: 0x%x", s.smbl_type); 564 565 desc_printf(smbios_slot_width_desc(s.smbl_width), 566 fp, " Width: 0x%x", s.smbl_width); 567 568 desc_printf(smbios_slot_usage_desc(s.smbl_usage), 569 fp, " Usage: 0x%x", s.smbl_usage); 570 571 desc_printf(smbios_slot_length_desc(s.smbl_length), 572 fp, " Length: 0x%x", s.smbl_length); 573 574 flag_printf(fp, "Slot Characteristics 1", 575 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 576 smbios_slot_ch1_name, smbios_slot_ch1_desc); 577 578 flag_printf(fp, "Slot Characteristics 2", 579 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 580 smbios_slot_ch2_name, smbios_slot_ch2_desc); 581 582 if (check_oem(shp) != 0 && (e.smbe_major < 2 || e.smbe_minor < 6)) 583 return; 584 585 oprintf(fp, " Segment Group: %u\n", s.smbl_sg); 586 oprintf(fp, " Bus Number: %u\n", s.smbl_bus); 587 oprintf(fp, " Device/Function Number: %u\n", s.smbl_df); 588 } 589 590 static void 591 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp) 592 { 593 smbios_obdev_ext_t oe; 594 595 (void) smbios_info_obdevs_ext(shp, id, &oe); 596 597 oprintf(fp, " Reference Designator: %s\n", oe.smboe_name); 598 oprintf(fp, " Device Type: %u\n", oe.smboe_dtype); 599 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti); 600 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg); 601 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus); 602 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df); 603 } 604 605 static void 606 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 607 { 608 smbios_obdev_t *argv; 609 int i, argc; 610 611 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 612 argv = alloca(sizeof (smbios_obdev_t) * argc); 613 (void) smbios_info_obdevs(shp, id, argc, argv); 614 for (i = 0; i < argc; i++) 615 oprintf(fp, " %s\n", argv[i].smbd_name); 616 } 617 } 618 619 static void 620 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 621 { 622 const char **argv; 623 int i, argc; 624 625 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 626 argv = alloca(sizeof (char *) * argc); 627 (void) smbios_info_strtab(shp, id, argc, argv); 628 for (i = 0; i < argc; i++) 629 oprintf(fp, " %s\n", argv[i]); 630 } 631 } 632 633 static void 634 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 635 { 636 smbios_lang_t l; 637 638 (void) smbios_info_lang(shp, &l); 639 640 oprintf(fp, " Current Language: %s\n", l.smbla_cur); 641 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 642 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 643 oprintf(fp, " Installed Languages:\n"); 644 645 print_strtab(shp, id, fp); 646 } 647 648 /*ARGSUSED*/ 649 static void 650 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 651 { 652 smbios_evlog_t ev; 653 uint32_t i; 654 655 (void) smbios_info_eventlog(shp, &ev); 656 657 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 658 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 659 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 660 661 desc_printf(smbios_evlog_method_desc(ev.smbev_method), 662 fp, " Data Access Method: %u", ev.smbev_method); 663 664 flag_printf(fp, "Log Flags", 665 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 666 smbios_evlog_flag_name, smbios_evlog_flag_desc); 667 668 desc_printf(smbios_evlog_format_desc(ev.smbev_format), 669 fp, " Log Header Format: %u", ev.smbev_format); 670 671 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 672 oprintf(fp, " Data Access Address: "); 673 674 switch (ev.smbev_method) { 675 case SMB_EVM_1x1i_1x1d: 676 case SMB_EVM_2x1i_1x1d: 677 case SMB_EVM_1x2i_1x1d: 678 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 679 ev.smbev_addr.eva_io.evi_iaddr, 680 ev.smbev_addr.eva_io.evi_daddr); 681 break; 682 case SMB_EVM_GPNV: 683 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 684 break; 685 default: 686 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 687 } 688 689 oprintf(fp, " Type Descriptors:\n"); 690 691 for (i = 0; i < ev.smbev_typec; i++) { 692 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 693 ev.smbev_typev[i].smbevt_ltype, 694 ev.smbev_typev[i].smbevt_dtype); 695 } 696 } 697 698 static void 699 print_bytes(const uint8_t *data, size_t size, FILE *fp) 700 { 701 size_t row, rows = P2ROUNDUP(size, 16) / 16; 702 size_t col, cols; 703 704 char buf[17]; 705 uint8_t x; 706 707 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 708 "0123456789abcdef\n"); 709 710 for (row = 0; row < rows; row++) { 711 oprintf(fp, " %#4lx: ", (ulong_t)row * 16); 712 cols = MIN(size - row * 16, 16); 713 714 for (col = 0; col < cols; col++) { 715 if (col % 4 == 0) 716 oprintf(fp, " "); 717 x = *data++; 718 oprintf(fp, "%02x", x); 719 buf[col] = x <= ' ' || x > '~' ? '.' : x; 720 } 721 722 for (; col < 16; col++) { 723 if (col % 4 == 0) 724 oprintf(fp, " "); 725 oprintf(fp, " "); 726 buf[col] = ' '; 727 } 728 729 buf[col] = '\0'; 730 oprintf(fp, " %s\n", buf); 731 } 732 733 oprintf(fp, "\n"); 734 } 735 736 static void 737 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 738 { 739 smbios_memarray_t ma; 740 741 (void) smbios_info_memarray(shp, id, &ma); 742 743 desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 744 fp, " Location: %u", ma.smbma_location); 745 746 desc_printf(smbios_memarray_use_desc(ma.smbma_use), 747 fp, " Use: %u", ma.smbma_use); 748 749 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 750 fp, " ECC: %u", ma.smbma_ecc); 751 752 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 753 id_printf(fp, " Memory Error Data: ", ma.smbma_err); 754 oprintf(fp, " Max Capacity: %llu bytes\n", 755 (u_longlong_t)ma.smbma_size); 756 } 757 758 static void 759 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 760 { 761 smbios_memdevice_t md; 762 763 (void) smbios_info_memdevice(shp, id, &md); 764 765 id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 766 id_printf(fp, " Memory Error Data: ", md.smbmd_error); 767 768 if (md.smbmd_twidth != -1u) 769 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 770 else 771 oprintf(fp, " Total Width: Unknown\n"); 772 773 if (md.smbmd_dwidth != -1u) 774 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 775 else 776 oprintf(fp, " Data Width: Unknown\n"); 777 778 switch (md.smbmd_size) { 779 case -1ull: 780 oprintf(fp, " Size: Unknown\n"); 781 break; 782 case 0: 783 oprintf(fp, " Size: Not Populated\n"); 784 break; 785 default: 786 oprintf(fp, " Size: %llu bytes\n", 787 (u_longlong_t)md.smbmd_size); 788 } 789 790 desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 791 fp, " Form Factor: %u", md.smbmd_form); 792 793 if (md.smbmd_set == 0) 794 oprintf(fp, " Set: None\n"); 795 else if (md.smbmd_set == (uint8_t)-1u) 796 oprintf(fp, " Set: Unknown\n"); 797 else 798 oprintf(fp, " Set: %u\n", md.smbmd_set); 799 800 if (md.smbmd_rank != 0) { 801 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank), 802 fp, " Rank: %u", md.smbmd_rank); 803 } else { 804 oprintf(fp, " Rank: Unknown\n"); 805 } 806 807 desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 808 fp, " Memory Type: %u", md.smbmd_type); 809 810 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 811 smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 812 813 if (md.smbmd_speed != 0) 814 oprintf(fp, " Speed: %u MHz\n", md.smbmd_speed); 815 else 816 oprintf(fp, " Speed: Unknown\n"); 817 818 if (md.smbmd_clkspeed != 0) 819 oprintf(fp, " Configured Speed: %u MHz\n", md.smbmd_clkspeed); 820 else 821 oprintf(fp, " Configured Speed: Unknown\n"); 822 823 oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc); 824 oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc); 825 826 if (md.smbmd_minvolt != 0) { 827 oprintf(fp, " Minimum Voltage: %.2fV\n", 828 md.smbmd_minvolt / 1000.0); 829 } else { 830 oprintf(fp, " Minimum Voltage: Unknown\n"); 831 } 832 833 if (md.smbmd_maxvolt != 0) { 834 oprintf(fp, " Maximum Voltage: %.2fV\n", 835 md.smbmd_maxvolt / 1000.0); 836 } else { 837 oprintf(fp, " Maximum Voltage: Unknown\n"); 838 } 839 840 if (md.smbmd_confvolt != 0) { 841 oprintf(fp, " Configured Voltage: %.2fV\n", 842 md.smbmd_confvolt / 1000.0); 843 } else { 844 oprintf(fp, " Configured Voltage: Unknown\n"); 845 } 846 } 847 848 static void 849 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 850 { 851 smbios_memarrmap_t ma; 852 853 (void) smbios_info_memarrmap(shp, id, &ma); 854 855 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 856 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 857 858 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 859 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 860 } 861 862 static void 863 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 864 { 865 smbios_memdevmap_t md; 866 867 (void) smbios_info_memdevmap(shp, id, &md); 868 869 id_printf(fp, " Memory Device: ", md.smbmdm_device); 870 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 871 872 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 873 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 874 875 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 876 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 877 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 878 } 879 880 static void 881 print_hwsec(smbios_hdl_t *shp, FILE *fp) 882 { 883 smbios_hwsec_t h; 884 885 (void) smbios_info_hwsec(shp, &h); 886 887 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 888 fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 889 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 890 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 891 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 892 fp, " Administrator Password Status: %u", h.smbh_adm_ps); 893 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 894 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 895 } 896 897 static void 898 print_boot(smbios_hdl_t *shp, FILE *fp) 899 { 900 smbios_boot_t b; 901 902 (void) smbios_info_boot(shp, &b); 903 904 desc_printf(smbios_boot_desc(b.smbt_status), 905 fp, " Boot Status Code: 0x%x", b.smbt_status); 906 907 if (b.smbt_size != 0) { 908 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 909 print_bytes(b.smbt_data, b.smbt_size, fp); 910 } 911 } 912 913 static void 914 print_ipmi(smbios_hdl_t *shp, FILE *fp) 915 { 916 smbios_ipmi_t i; 917 918 (void) smbios_info_ipmi(shp, &i); 919 920 desc_printf(smbios_ipmi_type_desc(i.smbip_type), 921 fp, " Type: %u", i.smbip_type); 922 923 oprintf(fp, " BMC IPMI Version: %u.%u\n", 924 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 925 926 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 927 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 928 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 929 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 930 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 931 932 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 933 smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 934 } 935 936 static void 937 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp) 938 { 939 int i; 940 smbios_processor_ext_t ep; 941 942 if (check_oem(shp) != 0) 943 return; 944 945 (void) smbios_info_extprocessor(shp, id, &ep); 946 947 oprintf(fp, " Processor: %u\n", ep.smbpe_processor); 948 oprintf(fp, " FRU: %u\n", ep.smbpe_fru); 949 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n); 950 951 for (i = 0; i < ep.smbpe_n; i++) { 952 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i, 953 ep.smbpe_apicid[i]); 954 } 955 } 956 957 static void 958 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp) 959 { 960 smbios_port_ext_t epo; 961 962 if (check_oem(shp) != 0) 963 return; 964 965 (void) smbios_info_extport(shp, id, &epo); 966 967 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis); 968 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port); 969 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype); 970 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl); 971 oprintf(fp, " PHY: %u\n", epo.smbporte_phy); 972 } 973 974 static void 975 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp) 976 { 977 smbios_pciexrc_t pcie; 978 979 if (check_oem(shp) != 0) 980 return; 981 982 (void) smbios_info_pciexrc(shp, id, &pcie); 983 984 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb); 985 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf); 986 } 987 988 static void 989 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp) 990 { 991 smbios_memarray_ext_t em; 992 993 if (check_oem(shp) != 0) 994 return; 995 996 (void) smbios_info_extmemarray(shp, id, &em); 997 998 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma); 999 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp); 1000 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf); 1001 } 1002 1003 static void 1004 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 1005 { 1006 int i; 1007 smbios_memdevice_ext_t emd; 1008 1009 if (check_oem(shp) != 0) 1010 return; 1011 1012 (void) smbios_info_extmemdevice(shp, id, &emd); 1013 1014 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md); 1015 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch); 1016 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs); 1017 1018 for (i = 0; i < emd.smbmdeve_ncs; i++) { 1019 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]); 1020 } 1021 } 1022 1023 static int 1024 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 1025 { 1026 smbios_info_t info; 1027 int hex = opt_x; 1028 const char *s; 1029 1030 if (opt_t != -1 && opt_t != sp->smbstr_type) 1031 return (0); /* skip struct if type doesn't match -t */ 1032 1033 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 1034 sp->smbstr_type == SMB_TYPE_MEMMOD)) 1035 return (0); /* skip struct if type is obsolete */ 1036 1037 if (g_hdr++ == 0 || !opt_s) 1038 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 1039 1040 oprintf(fp, "%-5u %-4lu", 1041 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 1042 1043 if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 1044 oprintf(fp, " %s (type %u)", s, sp->smbstr_type); 1045 else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 1046 sp->smbstr_type < SMB_TYPE_OEM_HI) 1047 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO", 1048 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type); 1049 else 1050 oprintf(fp, " %u", sp->smbstr_type); 1051 1052 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 1053 oprintf(fp, " (%s)\n", s); 1054 else 1055 oprintf(fp, "\n"); 1056 1057 if (opt_s) 1058 return (0); /* only print header line if -s specified */ 1059 1060 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 1061 oprintf(fp, "\n"); 1062 print_common(&info, fp); 1063 } 1064 1065 switch (sp->smbstr_type) { 1066 case SMB_TYPE_BIOS: 1067 oprintf(fp, "\n"); 1068 print_bios(shp, fp); 1069 break; 1070 case SMB_TYPE_SYSTEM: 1071 oprintf(fp, "\n"); 1072 print_system(shp, fp); 1073 break; 1074 case SMB_TYPE_BASEBOARD: 1075 oprintf(fp, "\n"); 1076 print_bboard(shp, sp->smbstr_id, fp); 1077 break; 1078 case SMB_TYPE_CHASSIS: 1079 oprintf(fp, "\n"); 1080 print_chassis(shp, sp->smbstr_id, fp); 1081 break; 1082 case SMB_TYPE_PROCESSOR: 1083 oprintf(fp, "\n"); 1084 print_processor(shp, sp->smbstr_id, fp); 1085 break; 1086 case SMB_TYPE_CACHE: 1087 oprintf(fp, "\n"); 1088 print_cache(shp, sp->smbstr_id, fp); 1089 break; 1090 case SMB_TYPE_PORT: 1091 oprintf(fp, "\n"); 1092 print_port(shp, sp->smbstr_id, fp); 1093 break; 1094 case SMB_TYPE_SLOT: 1095 oprintf(fp, "\n"); 1096 print_slot(shp, sp->smbstr_id, fp); 1097 break; 1098 case SMB_TYPE_OBDEVS: 1099 oprintf(fp, "\n"); 1100 print_obdevs(shp, sp->smbstr_id, fp); 1101 break; 1102 case SMB_TYPE_OEMSTR: 1103 case SMB_TYPE_SYSCONFSTR: 1104 oprintf(fp, "\n"); 1105 print_strtab(shp, sp->smbstr_id, fp); 1106 break; 1107 case SMB_TYPE_LANG: 1108 oprintf(fp, "\n"); 1109 print_lang(shp, sp->smbstr_id, fp); 1110 break; 1111 case SMB_TYPE_EVENTLOG: 1112 oprintf(fp, "\n"); 1113 print_evlog(shp, sp->smbstr_id, fp); 1114 break; 1115 case SMB_TYPE_MEMARRAY: 1116 oprintf(fp, "\n"); 1117 print_memarray(shp, sp->smbstr_id, fp); 1118 break; 1119 case SMB_TYPE_MEMDEVICE: 1120 oprintf(fp, "\n"); 1121 print_memdevice(shp, sp->smbstr_id, fp); 1122 break; 1123 case SMB_TYPE_MEMARRAYMAP: 1124 oprintf(fp, "\n"); 1125 print_memarrmap(shp, sp->smbstr_id, fp); 1126 break; 1127 case SMB_TYPE_MEMDEVICEMAP: 1128 oprintf(fp, "\n"); 1129 print_memdevmap(shp, sp->smbstr_id, fp); 1130 break; 1131 case SMB_TYPE_SECURITY: 1132 oprintf(fp, "\n"); 1133 print_hwsec(shp, fp); 1134 break; 1135 case SMB_TYPE_BOOT: 1136 oprintf(fp, "\n"); 1137 print_boot(shp, fp); 1138 break; 1139 case SMB_TYPE_IPMIDEV: 1140 oprintf(fp, "\n"); 1141 print_ipmi(shp, fp); 1142 break; 1143 case SMB_TYPE_OBDEVEXT: 1144 oprintf(fp, "\n"); 1145 print_obdevs_ext(shp, sp->smbstr_id, fp); 1146 break; 1147 case SUN_OEM_EXT_PROCESSOR: 1148 oprintf(fp, "\n"); 1149 print_extprocessor(shp, sp->smbstr_id, fp); 1150 break; 1151 case SUN_OEM_EXT_PORT: 1152 oprintf(fp, "\n"); 1153 print_extport(shp, sp->smbstr_id, fp); 1154 break; 1155 case SUN_OEM_PCIEXRC: 1156 oprintf(fp, "\n"); 1157 print_pciexrc(shp, sp->smbstr_id, fp); 1158 break; 1159 case SUN_OEM_EXT_MEMARRAY: 1160 oprintf(fp, "\n"); 1161 print_extmemarray(shp, sp->smbstr_id, fp); 1162 break; 1163 case SUN_OEM_EXT_MEMDEVICE: 1164 oprintf(fp, "\n"); 1165 print_extmemdevice(shp, sp->smbstr_id, fp); 1166 break; 1167 default: 1168 hex++; 1169 } 1170 1171 if (hex) 1172 print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 1173 else 1174 oprintf(fp, "\n"); 1175 1176 return (0); 1177 } 1178 1179 static uint16_t 1180 getu16(const char *name, const char *s) 1181 { 1182 u_longlong_t val; 1183 char *p; 1184 1185 errno = 0; 1186 val = strtoull(s, &p, 0); 1187 1188 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 1189 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1190 g_pname, name, s); 1191 exit(SMBIOS_USAGE); 1192 } 1193 1194 return ((uint16_t)val); 1195 } 1196 1197 static uint16_t 1198 getstype(const char *name, const char *s) 1199 { 1200 const char *ts; 1201 uint16_t t; 1202 1203 for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 1204 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 1205 return (t); 1206 } 1207 1208 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1209 g_pname, name, s); 1210 1211 exit(SMBIOS_USAGE); 1212 /*NOTREACHED*/ 1213 } 1214 1215 static int 1216 usage(FILE *fp) 1217 { 1218 (void) fprintf(fp, "Usage: %s " 1219 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 1220 1221 (void) fprintf(fp, 1222 "\t-B disable header validation for broken BIOSes\n" 1223 "\t-e display SMBIOS entry point information\n" 1224 "\t-i display only the specified structure\n" 1225 "\t-O display obsolete structure types\n" 1226 "\t-s display only a summary of structure identifiers and types\n" 1227 "\t-t display only the specified structure type\n" 1228 "\t-w write the raw data to the specified file\n" 1229 "\t-x display raw data for structures\n"); 1230 1231 return (SMBIOS_USAGE); 1232 } 1233 1234 int 1235 main(int argc, char *argv[]) 1236 { 1237 const char *ifile = NULL; 1238 const char *ofile = NULL; 1239 int oflags = 0; 1240 1241 smbios_hdl_t *shp; 1242 smbios_struct_t s; 1243 int err, fd, c; 1244 char *p; 1245 1246 if ((p = strrchr(argv[0], '/')) == NULL) 1247 g_pname = argv[0]; 1248 else 1249 g_pname = p + 1; 1250 1251 while (optind < argc) { 1252 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 1253 switch (c) { 1254 case 'B': 1255 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 1256 break; 1257 case 'e': 1258 opt_e++; 1259 break; 1260 case 'i': 1261 opt_i = getu16("struct ID", optarg); 1262 break; 1263 case 'O': 1264 opt_O++; 1265 break; 1266 case 's': 1267 opt_s++; 1268 break; 1269 case 't': 1270 if (isdigit(optarg[0])) 1271 opt_t = getu16("struct type", optarg); 1272 else 1273 opt_t = getstype("struct type", optarg); 1274 break; 1275 case 'w': 1276 ofile = optarg; 1277 break; 1278 case 'x': 1279 opt_x++; 1280 break; 1281 case 'Z': 1282 oflags |= SMB_O_ZIDS; /* undocumented */ 1283 break; 1284 default: 1285 return (usage(stderr)); 1286 } 1287 } 1288 1289 if (optind < argc) { 1290 if (ifile != NULL) { 1291 (void) fprintf(stderr, "%s: illegal " 1292 "argument -- %s\n", g_pname, argv[optind]); 1293 return (SMBIOS_USAGE); 1294 } 1295 ifile = argv[optind++]; 1296 } 1297 } 1298 1299 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 1300 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 1301 g_pname, smbios_errmsg(err)); 1302 return (SMBIOS_ERROR); 1303 } 1304 1305 if (ofile != NULL) { 1306 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 1307 (void) fprintf(stderr, "%s: failed to open %s: %s\n", 1308 g_pname, ofile, strerror(errno)); 1309 err = SMBIOS_ERROR; 1310 } else if (smbios_write(shp, fd) != 0) { 1311 (void) fprintf(stderr, "%s: failed to write %s: %s\n", 1312 g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 1313 err = SMBIOS_ERROR; 1314 } 1315 smbios_close(shp); 1316 return (err); 1317 } 1318 1319 if (opt_e) { 1320 print_smbios(shp, stdout); 1321 smbios_close(shp); 1322 return (SMBIOS_SUCCESS); 1323 } 1324 1325 if (opt_O && (opt_i != -1 || opt_t != -1)) 1326 opt_O++; /* -i or -t imply displaying obsolete records */ 1327 1328 if (opt_i != -1) 1329 err = smbios_lookup_id(shp, opt_i, &s); 1330 else 1331 err = smbios_iter(shp, print_struct, stdout); 1332 1333 if (err != 0) { 1334 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 1335 g_pname, smbios_errmsg(smbios_errno(shp))); 1336 smbios_close(shp); 1337 return (SMBIOS_ERROR); 1338 } 1339 1340 if (opt_i != -1) 1341 (void) print_struct(shp, &s, stdout); 1342 1343 smbios_close(shp); 1344 return (SMBIOS_SUCCESS); 1345 } 1346