diff options
Diffstat (limited to 'lib/ipmi_ekanalyzer.c')
-rw-r--r-- | lib/ipmi_ekanalyzer.c | 384 |
1 files changed, 224 insertions, 160 deletions
diff --git a/lib/ipmi_ekanalyzer.c b/lib/ipmi_ekanalyzer.c index 7a6c63d..dbc76b4 100644 --- a/lib/ipmi_ekanalyzer.c +++ b/lib/ipmi_ekanalyzer.c @@ -37,10 +37,14 @@ #include <ipmitool/log.h> #include <ipmitool/helper.h> #include <ipmitool/ipmi_strings.h> +#include <ipmitool/ipmi_fru.h> +#include <ipmitool/ipmi_time.h> #include <stdlib.h> #include <string.h> #include <time.h> +#include <fcntl.h> +#include <sys/stat.h> #define NO_MORE_INFO_FIELD 0xc1 #define TYPE_CODE 0xc0 /*Language code*/ @@ -193,7 +197,7 @@ struct ipmi_ek_amc_p2p_connectivity_record{ struct fru_picmgext_amc_channel_desc_record * ch_desc; unsigned char link_desc_count; struct fru_picmgext_amc_link_desc_record * link_desc; - int * matching_result; /*For link descriptor comparision*/ + int * matching_result; /*For link descriptor comparison*/ }; /***************************************************************************** @@ -216,8 +220,7 @@ static void ipmi_ek_add_record2list( struct ipmi_ek_multi_header ** record, struct ipmi_ek_multi_header ** list_last ); static void ipmi_ek_display_record( struct ipmi_ek_multi_header * record, - struct ipmi_ek_multi_header * list_head, - struct ipmi_ek_multi_header * list_last ); + struct ipmi_ek_multi_header * list_head); static void ipmi_ek_remove_record_from_list( struct ipmi_ek_multi_header * record, @@ -234,7 +237,7 @@ static int ipmi_ekanalyzer_fru_file2structure( char * filename, *****************************************************************************/ static int ipmi_ek_matching_process( int * file_type, int index1, int index2, struct ipmi_ek_multi_header ** list_head, - struct ipmi_ek_multi_header ** list_last, char * opt, + char * opt, struct ipmi_ek_multi_header * pphysical ); static int ipmi_ek_get_resource_descriptor( int port_count, int index, @@ -450,11 +453,11 @@ ipmi_ek_get_file_type(char *argument) * * Global: None * -* Return: OK_STATUS as succes or ERROR_STATUS as error +* Return: OK_STATUS as success or ERROR_STATUS as error * ***************************************************************************/ int -ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) +ipmi_ekanalyzer_main(struct ipmi_intf *__UNUSED__(intf), int argc, char **argv) { int rc = ERROR_STATUS; int file_type[MAX_FILE_NUMBER]; @@ -475,11 +478,12 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) return (-1); } - if (strcmp(argv[argument_offset], "help") == 0) { + if (!strcmp(argv[argument_offset], "help")) { ipmi_ekanalyzer_usage(); return 0; - } else if ((strcmp(argv[argument_offset], "frushow") == 0) - && (argc > (MIN_ARGUMENT-1))) { + } else if (!strcmp(argv[argument_offset], "frushow") + && (argc > (MIN_ARGUMENT-1))) + { for (type_offset = 0; type_offset < (argc-1); type_offset++ ) { argument_offset++; file_type[type_offset] = ipmi_ek_get_file_type(argv[argument_offset]); @@ -495,7 +499,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) */ filename[type_offset] = malloc(strlen(argv[argument_offset]) + 1 - SIZE_OF_FILE_TYPE); - if (filename[type_offset] == NULL) { + if (!filename[type_offset]) { lprintf(LOG_ERR, "malloc failure"); return (-1); } @@ -511,9 +515,9 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) /* Convert from binary data into multi record structure */ rc = ipmi_ekanalyzer_fru_file2structure (filename[type_offset], &list_head, &list_record, &list_last ); - ipmi_ek_display_record(list_record, list_head, list_last); + ipmi_ek_display_record(list_record, list_head); /* Remove record of list */ - while (list_head != NULL) { + while (list_head) { ipmi_ek_remove_record_from_list(list_head, &list_head,&list_last ); if (verbose > 1) { @@ -524,8 +528,9 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) free(filename[type_offset]); filename[type_offset] = NULL; } - } else if ((strcmp(argv[argument_offset], "print") == 0) - || (strcmp(argv[argument_offset], "summary") == 0)) { + } else if (!strcmp(argv[argument_offset], "print") + || !strcmp(argv[argument_offset], "summary")) + { /* Display help text for corresponding command * if not enough parameters were given. */ @@ -537,7 +542,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) int filename_size=0; if (argc < MIN_ARGUMENT) { lprintf(LOG_ERR, "Not enough parameters given."); - if (strcmp(argv[argument_offset], "print") == 0) { + if (!strcmp(argv[argument_offset], "print")) { lprintf(LOG_ERR, " ekanalyzer print [carrier/power/all]" " <xx=frufile> <xx=frufile> [xx=frufile]"); @@ -549,18 +554,20 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) return ERROR_STATUS; } argument_offset++; - if ((strcmp(argv[argument_offset], "carrier") == 0) - || (strcmp(argv[argument_offset], "power") == 0) - || (strcmp(argv[argument_offset], "all") == 0)) { + if (!strcmp(argv[argument_offset], "carrier") + || !strcmp(argv[argument_offset], "power") + || !strcmp(argv[argument_offset], "all")) + { option = argv[argument_offset]; index ++; argc--; - } else if ((strcmp(argv[argument_offset], "match") == 0) - || ( strcmp(argv[argument_offset], "unmatch") == 0)) { + } else if (!strcmp(argv[argument_offset], "match") + || !strcmp(argv[argument_offset], "unmatch")) + { option = argv[argument_offset]; index ++; argc--; - } else if ( strncmp(&argv[argument_offset][2], "=", 1) == 0) { + } else if ('=' == argv[argument_offset][2]) { /* since the command line must receive xx=filename, * so the position of "=" sign is 2 */ @@ -573,7 +580,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) option = "invalid"; printf("Invalid option '%s'\n", argv[argument_offset]); argument_offset--; - if (strcmp(argv[0], "print") == 0) { + if (!strcmp(argv[0], "print")) { lprintf (LOG_ERR, " ekanalyzer print [carrier/power/all]" " <xx=frufile> <xx=frufile> [xx=frufile]"); @@ -584,12 +591,12 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) } rc = ERROR_STATUS; } - if (strcmp(option, "invalid") != 0) { + if (strcmp(option, "invalid")) { int i=0; for (i = 0; i < (argc-1); i++) { file_type[i] = ipmi_ek_get_file_type (argv[index]); if (file_type[i] == ERROR_STATUS) { - /* display the first 2 charactors (file type) of argument */ + /* display the first 2 characters (file type) of argument */ lprintf(LOG_ERR, "Invalid file type: %c%c\n", argv[index][0], argv[index][1]); @@ -603,7 +610,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) filename_size = strlen(argv[index]) - SIZE_OF_FILE_TYPE + 1; if (filename_size > 0) { filename[i] = malloc( filename_size ); - if (filename[i] != NULL) { + if (filename[i]) { strcpy(filename[i], &argv[index][SIZE_OF_FILE_TYPE]); } else { lprintf(LOG_ERR, "ipmitool: malloc failure"); @@ -623,7 +630,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) printf("file name: %s\n", filename[i]); } } - if (strcmp(argv[0], "print") == 0) { + if (!strcmp(argv[0], "print")) { rc = ipmi_ekanalyzer_print((argc-1), option, filename, file_type); } else { @@ -631,7 +638,7 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv) option, filename, file_type); } for (i = 0; i < (argc-1); i++) { - if (filename[i] != NULL) { + if (filename[i]) { free(filename[i]); filename[i] = NULL; } @@ -674,7 +681,7 @@ ipmi_ekanalyzer_print(int argc, char *opt, char **filename, int *file_type) { int return_value = OK_STATUS; /* Display carrier topology */ - if ((strcmp(opt, "carrier") == 0) || (strcmp(opt, "default") == 0)) { + if (!strcmp(opt, "carrier") || !strcmp(opt, "default")) { tboolean found_flag = FALSE; int index = 0; int index_name[argc]; @@ -714,8 +721,9 @@ ipmi_ekanalyzer_print(int argc, char *opt, char **filename, int *file_type) */ tboolean first_data = TRUE; for (list_record[i] = list_head[i]; - list_record[i] != NULL; - list_record[i] = list_record[i]->next) { + list_record[i]; + list_record[i] = list_record[i]->next) + { if (list_record[i]->data[PICMG_ID_OFFSET] == FRU_AMC_CARRIER_P2P) { if (first_data) { printf("%s\n", STAR_LINE_LIMITER); @@ -724,7 +732,7 @@ ipmi_ekanalyzer_print(int argc, char *opt, char **filename, int *file_type) } return_value = ipmi_ek_display_carrier_connectivity(list_record[i]); } else if (list_record[i]->data[PICMG_ID_OFFSET] == FRU_AMC_CARRIER_INFO) { - /*See AMC.0 specification Table3-3 for mor detail*/ + /*See AMC.0 specification Table3-3 for more detail*/ #define COUNT_OFFSET 6 if (first_data) { printf("From Carrier file: %s\n", filename[index_name[i]]); @@ -737,7 +745,7 @@ ipmi_ekanalyzer_print(int argc, char *opt, char **filename, int *file_type) } /*Destroy the list of record*/ for (i = 0; i < argc; i++) { - while (list_head[i] != NULL) { + while (list_head[i]) { ipmi_ek_remove_record_from_list(list_head[i], &list_head[i], &list_last[i]); } @@ -749,10 +757,10 @@ ipmi_ekanalyzer_print(int argc, char *opt, char **filename, int *file_type) } } } - } else if (strcmp(opt, "power") == 0) { + } else if (!strcmp(opt, "power")) { printf("Print power information\n"); return_value = ipmi_ek_display_power(argc, opt, filename, file_type); - } else if (strcmp(opt, "all") == 0) { + } else if (!strcmp(opt, "all")) { printf("Print all information\n"); return_value = ipmi_ek_display_power(argc, opt, filename, file_type); } else { @@ -787,7 +795,7 @@ ipmi_ek_display_carrier_connectivity(struct ipmi_ek_multi_header *record) int offset = START_DATA_OFFSET; struct fru_picmgext_carrier_p2p_record rsc_desc; struct fru_picmgext_carrier_p2p_descriptor *port_desc; - if (record == NULL) { + if (!record) { lprintf(LOG_ERR, "P2P connectivity record is invalid\n"); return ERROR_STATUS; } @@ -915,14 +923,14 @@ ipmi_ek_display_power( int argc, char * opt, char ** filename, int * file_type ) return_value = ipmi_ekanalyzer_fru_file2structure( filename[num_file], &list_head[num_file], &list_record[num_file], &list_last[num_file]); - if ( list_head[num_file] != NULL ){ + if (list_head[num_file]){ for ( list_record[num_file] = list_head[num_file]; - list_record[num_file] != NULL; - list_record[num_file] = list_record[num_file]->next - ){ - if ( ( strcmp(opt, "all") == 0 ) - && ( file_type[num_file] == ON_CARRIER_FRU_FILE ) - ){ + list_record[num_file]; + list_record[num_file] = list_record[num_file]->next) + { + if (!strcmp(opt, "all") + && file_type[num_file] == ON_CARRIER_FRU_FILE) + { if ( list_record[num_file]->data[PICMG_ID_OFFSET] == FRU_AMC_CARRIER_P2P @@ -989,7 +997,7 @@ ipmi_ek_display_power( int argc, char * opt, char ** filename, int * file_type ) return_value = OK_STATUS; /*Destroy the list of record*/ for ( index = 0; index < argc; index++ ){ - while ( list_head[index] != NULL ){ + while (list_head[index]) { ipmi_ek_remove_record_from_list ( list_head[index], &list_head[index],&list_last[index] ); } @@ -1081,7 +1089,7 @@ ipmi_ekanalyzer_ekeying_match( int argc, char * opt, { tboolean return_value = FALSE; - if ( (strcmp(opt, "carrier") == 0 ) || (strcmp(opt, "power") == 0) ){ + if (!strcmp(opt, "carrier") || !strcmp(opt, "power")) { lprintf(LOG_ERR, " ekanalyzer summary [match/ unmatch/ all]"\ " <xx=frufile> <xx=frufile> [xx=frufile]"); return_value = ERROR_STATUS; @@ -1152,13 +1160,13 @@ ipmi_ekanalyzer_ekeying_match( int argc, char * opt, /*Get Carrier p2p connectivity record for physical check*/ for (num_file=0; num_file < argc; num_file++){ if (file_type[num_file] == ON_CARRIER_FRU_FILE ){ - for ( pcarrier_p2p=list_head[num_file]; - pcarrier_p2p != NULL ; - pcarrier_p2p = pcarrier_p2p->next - ){ - if ( pcarrier_p2p->data[PICMG_ID_OFFSET] - == FRU_AMC_CARRIER_P2P - ){ + for (pcarrier_p2p = list_head[num_file]; + pcarrier_p2p; + pcarrier_p2p = pcarrier_p2p->next) + { + if (FRU_AMC_CARRIER_P2P == + pcarrier_p2p->data[PICMG_ID_OFFSET]) + { break; } } @@ -1185,14 +1193,14 @@ ipmi_ekanalyzer_ekeying_match( int argc, char * opt, } return_value = ipmi_ek_matching_process( file_type, match_pair, num_file, list_head, - list_last, opt, pcarrier_p2p); + opt, pcarrier_p2p); } } } match_pair ++; } for( num_file=0; num_file < argc; num_file++ ){ - if (list_head[num_file] != NULL ){ + if (list_head[num_file]) { ipmi_ek_remove_record_from_list( list_head[num_file], &list_record[num_file], &list_last[num_file]); } @@ -1221,8 +1229,6 @@ ipmi_ekanalyzer_ekeying_match( int argc, char * opt, * index2: position of the second record in the list of the record * ipmi_ek_multi_header ** list_head: pointer to the header of a * linked list that contain FRU multi record -* ipmi_ek_multi_header ** list_last: pointer to the tale of a -* linked list that contain FRU multi record * opt: string that contain display option such as "match", "unmatch", or * "all". * pphysical: a pointer that contain a carrier p2p connectivity record @@ -1238,7 +1244,7 @@ ipmi_ekanalyzer_ekeying_match( int argc, char * opt, ***************************************************************************/ static int ipmi_ek_matching_process( int * file_type, int index1, int index2, struct ipmi_ek_multi_header ** list_head, - struct ipmi_ek_multi_header ** list_last, char * opt, + char * opt, struct ipmi_ek_multi_header * pphysical ) { int result = ERROR_STATUS; @@ -1254,13 +1260,13 @@ static int ipmi_ek_matching_process( int * file_type, int index1, int index2, index2 = index_temp; /*index2 indcate an AMC*/ } /*Calculate record size for Carrier file*/ - for ( record=list_head[index1]; record != NULL;record = record->next ){ + for (record = list_head[index1]; record; record = record->next ){ if ( record->data[PICMG_ID_OFFSET] == FRU_AMC_P2P ){ num_amc_record2++; } } /*Calculate record size for amc file*/ - for ( record=list_head[index2]; record != NULL;record = record->next){ + for (record = list_head[index2]; record; record = record->next){ if ( record->data[PICMG_ID_OFFSET] == FRU_AMC_P2P ){ num_amc_record1++; } @@ -1278,17 +1284,17 @@ static int ipmi_ek_matching_process( int * file_type, int index1, int index2, amc_record2 = malloc ( num_amc_record2 * \ sizeof(struct ipmi_ek_amc_p2p_connectivity_record)); - for (record=list_head[index2]; record != NULL;record = record->next){ + for (record = list_head[index2]; record; record = record->next) { if ( record->data[PICMG_ID_OFFSET] == FRU_AMC_P2P ){ result = ipmi_ek_create_amc_p2p_record( record, &amc_record1[index_record1] ); if (result != ERROR_STATUS){ struct ipmi_ek_multi_header * current_record = NULL; - for ( current_record=list_head[index1]; - current_record != NULL ; - current_record = current_record->next - ){ + for (current_record=list_head[index1]; + current_record; + current_record = current_record->next) + { if ( current_record->data[PICMG_ID_OFFSET] == FRU_AMC_P2P ){ result = ipmi_ek_create_amc_p2p_record( current_record, &amc_record2[index_record2] ); @@ -1358,7 +1364,7 @@ ipmi_ek_check_physical_connectivity( { int return_status = OK_STATUS; - if ( record == NULL ){ + if (!record){ printf("NO Carrier p2p connectivity !\n"); return_status = ERROR_STATUS; } @@ -1423,7 +1429,7 @@ ipmi_ek_check_physical_connectivity( rsc_desc.p2p_count ); } - if ( (port_desc != NULL) && (return_status != ERROR_STATUS) ){ + if (port_desc && return_status != ERROR_STATUS) { int j=0; for ( j = 0; j < rsc_desc.p2p_count; j++ ){ @@ -1450,7 +1456,7 @@ ipmi_ek_check_physical_connectivity( (filetype1 ==(port_desc[j].remote_resource_id &0x0f)) ) ){ - if ( ! (strcmp(option, "unmatch") == 0) ){ + if (strcmp(option, "unmatch")){ printf("%s port %d ==> %s port %d\n", val2str(filetype2, ipmi_ekanalyzer_module_type), record1.ch_desc[index1].lane0port, @@ -1473,7 +1479,7 @@ ipmi_ek_check_physical_connectivity( && (filetype2 == (port_desc[j].remote_resource_id & 0x0f)) ){ - if ( ! (strcmp(option, "unmatch") == 0) ){ + if (strcmp(option, "unmatch")){ printf("%s port %d ==> %s port %d\n", val2str(filetype2, ipmi_ekanalyzer_module_type), record1.ch_desc[index1].lane0port, @@ -1487,7 +1493,7 @@ ipmi_ek_check_physical_connectivity( && (record2.rsc_id == (port_desc[j].remote_resource_id)) ){ - if ( ! (strcmp(option, "unmatch") == 0) ){ + if (strcmp(option, "unmatch")){ printf("%s port %d ==> %s %x port %d\n", val2str(filetype2, ipmi_ekanalyzer_module_type), record1.ch_desc[index1].lane0port, @@ -1523,7 +1529,7 @@ ipmi_ek_check_physical_connectivity( } return_status = ERROR_STATUS; } - if (port_desc != NULL){ + if (port_desc) { free(port_desc); port_desc = NULL; } @@ -1603,10 +1609,10 @@ ipmi_ek_compare_link( struct ipmi_ek_multi_header * physic_record, physic_record, file_type1, file_type2, opt ); if ( result == OK_STATUS ){ /*Display the result if option = match or all*/ - if ( (strcmp( opt, "match" ) == 0) - || (strcmp( opt, "all" ) == 0) - || (strcmp( opt, "default" ) == 0) - ){ + if (!strcmp(opt, "match") + || !strcmp(opt, "all") + || !strcmp(opt, "default")) + { tboolean isOEMtype = FALSE; printf(" Matching Result\n"); isOEMtype = ipmi_ek_display_link_descriptor( file_type1, @@ -1663,10 +1669,10 @@ ipmi_ek_compare_link( struct ipmi_ek_multi_header * physic_record, record1, index_ch_desc1, record2, index_ch_desc2, physic_record, file_type1, file_type2, opt ); if ( result == OK_STATUS ){ - if ( (strcmp( opt, "match" ) == 0) - || (strcmp( opt, "all" ) == 0) - || (strcmp( opt, "default" ) == 0) - ){ + if (!strcmp( opt, "match" ) + || !strcmp(opt, "all") + || !strcmp(opt, "default")) + { tboolean isOEMtype = FALSE; printf(" Matching Result\n"); isOEMtype = ipmi_ek_display_link_descriptor( file_type1, @@ -1694,7 +1700,7 @@ ipmi_ek_compare_link( struct ipmi_ek_multi_header * physic_record, } } - if ( (strcmp(opt, "unmatch") == 0) || (strcmp(opt, "all") == 0) ){ + if (!strcmp(opt, "unmatch") || !strcmp(opt, "all")) { int isOEMtype = FALSE; printf(" Unmatching result\n"); for (index1 = 0; index1 < record1.link_desc_count; index1++){ @@ -1939,12 +1945,12 @@ ipmi_ek_compare_link_descriptor( * * Function name: ipmi_ek_compare_asym * -* Description: This function compares 2 asymetric match of 2 +* Description: This function compares 2 asymmetric match of 2 * amc link descriptors * * Restriction: None * -* Input: asym[COMPARE_CANDIDATE]: Contain 2 asymetric match for comparison +* Input: asym[COMPARE_CANDIDATE]: Contain 2 asymmetric match for comparison * * Output: None * @@ -2055,7 +2061,7 @@ ipmi_ek_compare_number_of_enable_port( * destination (its value = "To"). ( it is set to "" if it is not * a source nor destination * link_desc: AMC link descriptor -* asym: asymetric match +* asym: asymmetric match * * Output: None * @@ -2208,7 +2214,7 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record, int index_oem = 0; amc_record->oem_guid = malloc(amc_record->guid_count * \ sizeof(struct fru_picmgext_guid)); - if (amc_record->oem_guid == NULL) { + if (!amc_record->oem_guid) { return ERROR_STATUS; } for (index_oem = 0; index_oem < amc_record->guid_count; @@ -2238,7 +2244,7 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record, int ch_index = 0; amc_record->ch_desc = malloc((amc_record->ch_count) * \ sizeof(struct fru_picmgext_amc_channel_desc_record)); - if (amc_record->ch_desc == NULL) { + if (!amc_record->ch_desc) { return ERROR_STATUS; } for (ch_index = 0; ch_index < amc_record->ch_count; @@ -2264,7 +2270,7 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record, int i=0; amc_record->link_desc = malloc(amc_record->link_desc_count * \ sizeof(struct fru_picmgext_amc_link_desc_record)); - if (amc_record->link_desc == NULL) { + if (!amc_record->link_desc) { return ERROR_STATUS; } for (i = 0; i< amc_record->link_desc_count; i++) { @@ -2347,7 +2353,7 @@ ipmi_ek_get_resource_descriptor(int port_count, int index, * * Global: None * -* Return: Return OK_STATUS on sucess, ERROR_STATUS on error +* Return: Return OK_STATUS on success, ERROR_STATUS on error * ***************************************************************************/ static int @@ -2358,7 +2364,7 @@ ipmi_ek_display_fru_header(char *filename) int ret = 0; input_file = fopen(filename, "r"); - if (input_file == NULL) { + if (!input_file) { lprintf(LOG_ERR, "File '%s' not found.", filename); return (ERROR_STATUS); } @@ -2413,7 +2419,7 @@ ipmi_ek_display_fru_header_detail(char *filename) FILE *input_file; size_t file_offset = 0; struct fru_header header; - time_t tval; + time_t ts; int ret = 0; unsigned char data = 0; unsigned char lan_code = 0; @@ -2421,7 +2427,7 @@ ipmi_ek_display_fru_header_detail(char *filename) unsigned int board_length = 0; input_file = fopen(filename, "r"); - if (input_file == NULL) { + if (!input_file) { lprintf(LOG_ERR, "File '%s' not found.", filename); return (-1); } @@ -2439,6 +2445,8 @@ ipmi_ek_display_fru_header_detail(char *filename) if (header.offset.internal != 0) { unsigned char format_version; unsigned long len = 0; + uint8_t *area_offset; + uint8_t next_offset = UINT8_MAX; printf("%s\n", EQUAL_LINE_LIMITER); printf("FRU Internal Use Info\n"); @@ -2452,12 +2460,46 @@ ipmi_ek_display_fru_header_detail(char *filename) } printf("Format Version: %d\n", (format_version & 0x0f)); - if (header.offset.chassis > 0) { - len = (header.offset.chassis * FACTOR_OFFSET) - - (header.offset.internal * FACTOR_OFFSET); - } else { - len = (header.offset.board * FACTOR_OFFSET) - - (header.offset.internal * FACTOR_OFFSET); + /* Internal use area doesn't contain the size byte. + * We need to calculate its size by finding the area + * that is next. Areas may not follow the same order + * as their offsets listed in the header, so we need + * to find the area that is physically next to the + * internal use area. + */ + for (area_offset = &header.offset.internal + 1; + area_offset <= &header.offset.multi; + ++area_offset) + { + /* If the area is closer to us than the previously + * checked one, make it our best candidate + */ + if (*area_offset < next_offset + && *area_offset > header.offset.internal) + { + next_offset = *area_offset; + } + } + + /* If there was at least one area after internal use one, + * then we must have found it and can use it to calculate + * length. Otherwise, everything till the end of file is + * internal use area expect for the last (checksum) byte. + */ + if (next_offset < UINT8_MAX) { + len = (next_offset - header.offset.internal) * FACTOR_OFFSET; + --len; /* First byte of internal use area is version and we've + already read it */ + } + else { + struct stat fs; + long curpos = ftell(input_file); + if (curpos < 0 || 0 > fstat(fileno(input_file), &fs)) { + lprintf(LOG_ERR, "Failed to determine FRU file size"); + fclose(input_file); + return -1; + } + len = fs.st_size - curpos - 1; /* Last byte is checksum */ } printf("Length: %ld\n", len); printf("Data dump:\n"); @@ -2541,33 +2583,40 @@ ipmi_ek_display_fru_header_detail(char *filename) fclose(input_file); return (-1); } - tval = ((mfg_date[2] << 16) + (mfg_date[1] << 8) - + (mfg_date[0])); - tval = tval * 60; - tval = tval + secs_from_1970_1996; - printf("Board Mfg Date: %ld, %s", tval, - asctime(localtime(&tval))); + + ts = ipmi_fru2time_t(mfg_date); + printf("Board Mfg Date: %ld, %s\n", + (IPMI_TIME_UNSPECIFIED == ts) + ? FRU_BOARD_DATE_UNSPEC + : ts, + ipmi_timestamp_numeric(ts)); board_length -= SIZE_MFG_DATE; + /* Board Mfg */ file_offset = ipmi_ek_display_board_info_area( input_file, "Board Manufacture Data", &board_length); ret = fseek(input_file, file_offset, SEEK_SET); + /* Board Product */ file_offset = ipmi_ek_display_board_info_area( input_file, "Board Product Name", &board_length); ret = fseek(input_file, file_offset, SEEK_SET); + /* Board Serial */ file_offset = ipmi_ek_display_board_info_area( input_file, "Board Serial Number", &board_length); ret = fseek(input_file, file_offset, SEEK_SET); + /* Board Part */ file_offset = ipmi_ek_display_board_info_area( input_file, "Board Part Number", &board_length); ret = fseek(input_file, file_offset, SEEK_SET); + /* FRU file ID */ file_offset = ipmi_ek_display_board_info_area( input_file, "FRU File ID", &board_length); ret = fseek(input_file, file_offset, SEEK_SET); + /* Additional Custom Mfg. */ file_offset = ipmi_ek_display_board_info_area( input_file, "Custom", &board_length); @@ -2614,7 +2663,7 @@ ipmi_ek_display_chassis_info_area(FILE *input_file, long offset) unsigned char ch_type = 0; unsigned int len; - if (input_file == NULL) { + if (!input_file) { lprintf(LOG_ERR, "No file stream to read."); return (-1); } @@ -2696,12 +2745,18 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, int ret = 0; unsigned char len = 0; unsigned int size_board = 0; - if (input_file == NULL || board_type == NULL - || board_length == NULL) { + int custom_fields = 0; + if (!input_file || !board_type || !board_length) { return (size_t)(-1); } file_offset = ftell(input_file); + /* + * TODO: This whole file's code is extremely dirty and wicked. + * Must eventually switch to using ipmi_fru.c code or some + * specialized FRU library. + */ + /* Board length*/ ret = fread(&len, 1, 1, input_file); if ((ret != 1) || ferror(input_file)) { @@ -2710,21 +2765,22 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, } (*board_length)--; - /* Bit 5:0 of Board Mfg type represent legnth */ + /* Bit 5:0 of Board Mfg type represent length */ size_board = (len & 0x3f); if (size_board == 0) { printf("%s: None\n", board_type); goto out; } - if (strncmp(board_type, "Custom", 6 ) != 0) { - unsigned char *data; + if (strcmp(board_type, "Custom")) { + unsigned char *data, *str; unsigned int i = 0; - data = malloc(size_board); - if (data == NULL) { + data = malloc(size_board + 1); /* Make room for type/length field */ + if (!data) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return (size_t)(-1); } - ret = fread(data, size_board, 1, input_file); + data[0] = len; /* Save the type/length byte in 'data' */ + ret = fread(data + 1, size_board, 1, input_file); if ((ret != 1) || ferror(input_file)) { lprintf(LOG_ERR, "Invalid board type size!"); free(data); @@ -2733,17 +2789,11 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, } printf("%s type: 0x%02x\n", board_type, len); printf("%s: ", board_type); - for (i = 0; i < size_board; i++) { - if ((len & TYPE_CODE) == TYPE_CODE) { - printf("%c", data[i]); - } else { - /* other than language code (binary, BCD, - * ASCII 6 bit...) is not supported - */ - printf("%02x", data[i]); - } - } - printf("\n"); + i = 0; + str = (unsigned char *)get_fru_area_str(data, &i); + printf("%s\n", str); + free(str); + str = NULL; free(data); data = NULL; (*board_length) -= size_board; @@ -2756,7 +2806,12 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, /* take the rest of data in the area minus 1 byte of * checksum */ - printf("Additional Custom Mfg. length: 0x%02x\n", len); + if (custom_fields) { + printf("End of Custom Mfg. fields (0x%02x)\n", len); + } else { + printf("No Additional Custom Mfg. fields (0x%02x)\n", len); + } + padding = (*board_length) - 1; if ((padding > 0) && (!feof(input_file))) { printf("Unused space: %d (bytes)\n", padding); @@ -2770,36 +2825,47 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, printf("Checksum: 0x%02x\n", checksum); goto out; } + custom_fields++; printf("Additional Custom Mfg. length: 0x%02x\n", len); if ((size_board > 0) && (size_board < (*board_length))) { - unsigned char * additional_data = NULL; + unsigned char *additional_data, *str; unsigned int i = 0; - additional_data = malloc(size_board); - if (additional_data == NULL) { + additional_data = malloc(size_board + 1); /* Make room for type/length field */ + if (!additional_data) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return (size_t)(-1); } - ret = fread(additional_data, size_board, 1, input_file); + additional_data[0] = len; + ret = fread(additional_data + 1, size_board, 1, input_file); if ((ret != 1) || ferror(input_file)) { lprintf(LOG_ERR, "Invalid Additional Data!"); - if (additional_data != NULL) { + if (additional_data) { free(additional_data); additional_data = NULL; } goto out; } - printf("Additional Custom Mfg. Data: %02x", - additional_data[0]); - for (i = 1; i < size_board; i++) { - printf("-%02x", additional_data[i]); - } - printf("\n"); + printf("Additional Custom Mfg. Data: "); + i = 0; + str = (unsigned char *)get_fru_area_str(additional_data, &i); + printf("%s\n", str); + free(str); + str = NULL; free(additional_data); additional_data = NULL; + (*board_length) -= size_board; + ret = fread(&len, 1, 1, input_file); + if ((ret != 1) || ferror(input_file)) { + lprintf(LOG_ERR, "Invalid Length!"); + goto out; + } + (*board_length)--; + size_board = (len & 0x3f); } else { - printf("No Additional Custom Mfg. %d\n", *board_length); + printf("ERROR: File has insufficient data (%d bytes) for the " + "Additional Custom Mfg. field\n", *board_length); goto out; } } @@ -2838,7 +2904,7 @@ ipmi_ek_display_product_info_area(FILE *input_file, long offset) unsigned char data = 0; unsigned int len = 0; - if (input_file == NULL) { + if (!input_file) { lprintf(LOG_ERR, "No file stream to read."); return (-1); } @@ -2924,7 +2990,6 @@ ipmi_ek_display_product_info_area(FILE *input_file, long offset) * * Input: record: a pointer to current record * list_head: a pointer to header of the list -* list_last: a pointer to tale of the list * * Output: None * @@ -2935,17 +3000,16 @@ ipmi_ek_display_product_info_area(FILE *input_file, long offset) ***************************************************************************/ static void ipmi_ek_display_record(struct ipmi_ek_multi_header *record, - struct ipmi_ek_multi_header *list_head, - struct ipmi_ek_multi_header *list_last) + struct ipmi_ek_multi_header *list_head) { - if (list_head == NULL) { + if (!list_head) { printf("***empty list***\n"); return; } printf("%s\n", EQUAL_LINE_LIMITER); printf("FRU Multi Info area\n"); printf("%s\n", EQUAL_LINE_LIMITER); - for (record = list_head; record != NULL; record = record->next) { + for (record = list_head; record; record = record->next) { printf("Record Type ID: 0x%02x\n", record->header.type); printf("Record Format version: 0x%02x\n", record->header.format); @@ -3398,7 +3462,7 @@ ipmi_ek_display_board_p2p_record(struct ipmi_ek_multi_header *record) printf("ShMC Cross-connect (two-pair)\n"); break; default: - printf("Unknwon\n"); + printf("Unknown\n"); break; } } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET) { @@ -3413,17 +3477,17 @@ ipmi_ek_display_board_p2p_record(struct ipmi_ek_multi_header *record) printf("FC-PI\n"); break; default: - printf("Unknwon\n"); + printf("Unknown\n"); break; } } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND) { - printf("Unknwon\n"); + printf("Unknown\n"); } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR) { - printf("Unknwon\n"); + printf("Unknown\n"); } else if (d->type == FRU_PICMGEXT_LINK_TYPE_PCIE) { - printf("Unknwon\n"); + printf("Unknown\n"); } else { - printf("Unknwon\n"); + printf("Unknown\n"); } printf("\tLink Type:\t\t0x%02x - ", d->type); if (d->type == 0 || d->type == 0xff) { @@ -4007,7 +4071,7 @@ ipmi_ek_display_clock_config_record(struct ipmi_ek_multi_header *record) * * Restriction: None * -* Input/Ouput: filename1: name of the file that contain FRU binary data +* Input/Output: filename1: name of the file that contain FRU binary data * record: a pointer to current record * list_head: a pointer to header of the list * list_last: a pointer to tale of the list @@ -4031,7 +4095,7 @@ ipmi_ekanalyzer_fru_file2structure(char *filename, int ret = 0; input_file = fopen(filename, "r"); - if (input_file == NULL) { + if (!input_file) { lprintf(LOG_ERR, "File: '%s' is not found", filename); return ERROR_STATUS; } @@ -4058,7 +4122,7 @@ ipmi_ekanalyzer_fru_file2structure(char *filename, fseek(input_file, multi_offset, SEEK_SET); while (!feof(input_file)) { *list_record = malloc(sizeof(struct ipmi_ek_multi_header)); - if (*list_record == NULL) { + if (!(*list_record)) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return ERROR_STATUS; } @@ -4076,7 +4140,7 @@ ipmi_ekanalyzer_fru_file2structure(char *filename, continue; } (*list_record)->data = malloc((*list_record)->header.len); - if ((*list_record)->data == NULL) { + if (!(*list_record)->data) { lprintf(LOG_ERR, "Failed to allocation memory size %d\n", (*list_record)->header.len); record_count++; @@ -4121,7 +4185,7 @@ ipmi_ekanalyzer_fru_file2structure(char *filename, * * Function name: ipmi_ek_add_record2list * -* Description: this function adds a sigle FRU multi record to a linked list of +* Description: this function adds a single FRU multi record to a linked list of * FRU multi record. * * Restriction: None @@ -4140,18 +4204,18 @@ ipmi_ek_add_record2list(struct ipmi_ek_multi_header **record, struct ipmi_ek_multi_header **list_head, struct ipmi_ek_multi_header **list_last) { - if (*list_head == NULL) { - *list_head = *record; - (*record)->prev = NULL; - if (verbose > 2) { - printf("Adding first record to list\n"); - } - } else { + if (*list_head) { (*list_last)->next = *record; (*record)->prev = *list_last; if (verbose > 2) { printf("Add 1 record to list\n"); } + } else { + *list_head = *record; + (*record)->prev = NULL; + if (verbose > 2) { + printf("Adding first record to list\n"); + } } *list_last = *record; (*record)->next = NULL; @@ -4161,7 +4225,7 @@ ipmi_ek_add_record2list(struct ipmi_ek_multi_header **record, * * Function name: ipmi_ek_remove_record_from_list * -* Description: this function removes a sigle FRU multi record from a linked +* Description: this function removes a single FRU multi record from a linked * list of FRU multi record. * * Restriction: None @@ -4180,12 +4244,12 @@ ipmi_ek_remove_record_from_list(struct ipmi_ek_multi_header *record, struct ipmi_ek_multi_header **list_head, struct ipmi_ek_multi_header **list_last) { - if (record->prev == NULL) { + if (!record->prev) { *list_head = record->next; } else { record->prev->next = record->next; } - if (record->next == NULL) { + if (!record->next) { (*list_last) = record->prev; } else { record->next->prev = record->prev; |