diff options
Diffstat (limited to 'lib/ipmi_sel.c')
-rw-r--r-- | lib/ipmi_sel.c | 442 |
1 files changed, 200 insertions, 242 deletions
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c index 8b0395e..31c0eea 100644 --- a/lib/ipmi_sel.c +++ b/lib/ipmi_sel.c @@ -29,7 +29,6 @@ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -#define _BSD_SOURCE #include <string.h> #include <strings.h> @@ -38,6 +37,7 @@ #include <time.h> #include <ctype.h> #include <errno.h> +#include <stdbool.h> #include <ipmitool/helper.h> #include <ipmitool/log.h> @@ -50,8 +50,9 @@ #include <ipmitool/ipmi_fru.h> #include <ipmitool/ipmi_sensor.h> #include <ipmitool/ipmi_strings.h> +#include <ipmitool/ipmi_quantaoem.h> +#include <ipmitool/ipmi_time.h> -extern int verbose; static int sel_extended = 0; static int sel_oem_nrecs = 0; @@ -123,13 +124,13 @@ int ipmi_sel_oem_init(const char * filename) int i, j, k, n, byte; char buf[15][150]; - if (filename == NULL) { + if (!filename) { lprintf(LOG_ERR, "No SEL OEM filename provided"); return -1; } fp = ipmi_open_file_read(filename); - if (fp == NULL) { + if (!fp) { lprintf(LOG_ERR, "Could not open %s file", filename); return -1; } @@ -193,7 +194,7 @@ int ipmi_sel_oem_init(const char * filename) return 0; } -static void ipmi_sel_oem_message(struct sel_event_record * evt, int verbose) +static void ipmi_sel_oem_message(struct sel_event_record * evt) { /* * Note: although we have a verbose argument, currently the output @@ -238,34 +239,6 @@ ipmi_get_event_type(uint8_t code) } static char * -ipmi_sel_timestamp(uint32_t stamp) -{ - static char tbuf[40]; - time_t s = (time_t)stamp; - memset(tbuf, 0, 40); - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&s)); - return tbuf; -} - -static char * -ipmi_sel_timestamp_date(uint32_t stamp) -{ - static char tbuf[11]; - time_t s = (time_t)stamp; - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", gmtime(&s)); - return tbuf; -} - -static char * -ipmi_sel_timestamp_time(uint32_t stamp) -{ - static char tbuf[9]; - time_t s = (time_t)stamp; - strftime(tbuf, sizeof(tbuf), "%H:%M:%S", gmtime(&s)); - return tbuf; -} - -static char * hex2ascii (uint8_t * hexChars, uint8_t numBytes) { int count; @@ -315,11 +288,11 @@ ipmi_get_oem(struct ipmi_intf * intf) req.msg.data_len = 0; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get Device ID command failed"); return IPMI_OEM_UNKNOWN; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Get Device ID command failed: %#x %s", rsp->ccode, val2str(rsp->ccode, completion_code_vals)); return IPMI_OEM_UNKNOWN; @@ -348,11 +321,11 @@ ipmi_sel_add_entry(struct ipmi_intf * intf, struct sel_event_record * rec) ipmi_sel_print_std_entry(intf, rec); rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Add SEL Entry failed"); return -1; } - else if (rsp->ccode > 0) { + else if (rsp->ccode) { lprintf(LOG_ERR, "Add SEL Entry failed: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -373,15 +346,15 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename) uint8_t rqdata[8]; struct sel_event_record sel_event; - if (filename == NULL) + if (!filename) return -1; fp = ipmi_open_file_read(filename); - if (fp == NULL) + if (!fp) return -1; while (feof(fp) == 0) { - if (fgets(buf, 1024, fp) == NULL) + if (!fgets(buf, 1024, fp)) continue; /* clip off optional comment tail indicated by # */ @@ -447,25 +420,26 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename) return rc; } -static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = { +static struct ipmi_event_sensor_types __UNUSED__(oem_kontron_event_reading_types[]) = { { 0x70 , 0x00 , 0xff, "Code Assert" }, { 0x71 , 0x00 , 0xff, "Code Assert" }, { 0, 0, 0xFF, NULL } }; - + +/* NOTE: unused paramter kept in for consistency. */ char * -get_kontron_evt_desc(struct ipmi_intf *intf, struct sel_event_record * rec) +get_kontron_evt_desc(struct ipmi_intf *__UNUSED__(intf), struct sel_event_record *rec) { - char * description = NULL; + char *description = NULL; /* * Kontron OEM events are described in the product's user manual, but are limited in favor of - * sensor specific + * sensor specific */ /* Only standard records are defined so far */ if( rec->record_type < 0xC0 ){ const struct ipmi_event_sensor_types *st=NULL; - for ( st=oem_kontron_event_types ; st->desc != NULL; st++){ + for (st = oem_kontron_event_types; st->desc; st++){ if (st->code == rec->sel_type.standard_type.event_type ){ size_t len =strlen(st->desc); description = (char*)malloc( len + 1 ); @@ -480,10 +454,10 @@ get_kontron_evt_desc(struct ipmi_intf *intf, struct sel_event_record * rec) } char * -get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) +get_viking_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) { /* - * Newisys OEM event descriptions can be retrieved through an + * Viking OEM event descriptions can be retrieved through an * OEM IPMI command. */ struct ipmi_rs * rsp; @@ -506,12 +480,12 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) req.msg.data = msg_data; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { if (verbose) lprintf(LOG_ERR, "Error issuing OEM command"); return NULL; } - if (rsp->ccode > 0) { + if (rsp->ccode) { if (verbose) lprintf(LOG_ERR, "OEM command returned error code: %s", val2str(rsp->ccode, completion_code_vals)); @@ -521,17 +495,17 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) /* Verify our response before we use it */ if (rsp->data_len < 5) { - lprintf(LOG_ERR, "Newisys OEM response too short"); + lprintf(LOG_ERR, "Viking OEM response too short"); return NULL; } else if (rsp->data_len != (4 + rsp->data[3])) { - lprintf(LOG_ERR, "Newisys OEM response has unexpected length"); + lprintf(LOG_ERR, "Viking OEM response has unexpected length"); return NULL; } - else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_NEWISYS) + else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_VIKING) { - lprintf(LOG_ERR, "Newisys OEM response has unexpected length"); + lprintf(LOG_ERR, "Viking OEM response has unexpected length"); return NULL; } @@ -565,9 +539,9 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) if (rec->sel_type.standard_type.event_type != 0x6F) { return NULL; } - /* Allocate mem for te Description string */ + /* Allocate mem for the Description string */ desc = malloc(sizeof(char) * SIZE_OF_DESC); - if (desc == NULL) { + if (!desc) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return NULL; } @@ -583,17 +557,17 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) req.msg.data_len = 0; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, " Error getting system info"); - if (desc != NULL) { + if (desc) { free(desc); desc = NULL; } return NULL; - } else if (rsp->ccode > 0) { + } else if (rsp->ccode) { lprintf(LOG_ERR, " Error getting system info: %s", val2str(rsp->ccode, completion_code_vals)); - if (desc != NULL) { + if (desc) { free(desc); desc = NULL; } @@ -602,7 +576,7 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) /* check the chipset type */ oem_id = ipmi_get_oem_id(intf); if (oem_id == 0) { - if (desc != NULL) { + if (desc) { free(desc); desc = NULL; } @@ -705,7 +679,7 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) /* * Function : Decoding the SEL OEM Bytes for the DELL Platforms. - * Description : The below fucntion will decode the SEL Events OEM Bytes for the Dell specific Sensors only. + * Description : The below function will decode the SEL Events OEM Bytes for the Dell specific Sensors only. * The below function will append the additional information Strings/description to the normal sel desc. * With this the SEL will display additional information sent via OEM Bytes of the SEL Record. * NOTE : Specific to DELL Platforms only. @@ -738,7 +712,7 @@ char * get_dell_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) if (0x6F == rec->sel_type.standard_type.event_type) { sensor_type = rec->sel_type.standard_type.sensor_type; - /* Allocate mem for te Description string */ + /* Allocate mem for the Description string */ desc = (char*)malloc(SIZE_OF_DESC); if(NULL == desc) return NULL; @@ -787,17 +761,17 @@ char * get_dell_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) if (NULL == rsp) { lprintf(LOG_ERR, " Error getting system info"); - if (desc != NULL) { + if (desc) { free(desc); desc = NULL; } return NULL; } - else if (rsp->ccode > 0) + else if (rsp->ccode) { lprintf(LOG_ERR, " Error getting system info: %s", val2str(rsp->ccode, completion_code_vals)); - if (desc != NULL) { + if (desc) { free(desc); desc = NULL; } @@ -896,11 +870,11 @@ char * get_dell_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) if(SENSOR_TYPE_EVT_LOG == sensor_type) { if(0x03 == (data1 & MASK_LOWER_NIBBLE)) - snprintf(desc,SIZE_OF_DESC,"All Even Logging Dissabled"); + snprintf(desc,SIZE_OF_DESC,"All Even Logging Disabled"); } } /* - * Based on the above error, we need to find whcih memory slot or + * Based on the above error, we need to find which memory slot or * Card has got the Errors/Sel Generated. */ if(data1 & OEM_CODE_IN_BYTE2 ) @@ -1042,7 +1016,7 @@ char * get_dell_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) } break; - /* This Event is for BMC to Othe Hardware or CPU . */ + /* This Event is for BMC to other Hardware or CPU . */ case SENSOR_TYPE_VER_CHANGE: if((0x02 == (data1 & MASK_LOWER_NIBBLE))&&((data1 & OEM_CODE_IN_BYTE2) && (data1 & OEM_CODE_IN_BYTE3))) { @@ -1231,8 +1205,8 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec) switch (ipmi_get_oem(intf)) { - case IPMI_OEM_NEWISYS: - desc = get_newisys_evt_desc(intf, rec); + case IPMI_OEM_VIKING: + desc = get_viking_evt_desc(intf, rec); break; case IPMI_OEM_KONTRON: desc = get_kontron_evt_desc(intf, rec); @@ -1244,6 +1218,9 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec) case IPMI_OEM_SUPERMICRO_47488: desc = get_supermicro_evt_desc(intf, rec); break; + case IPMI_OEM_QUANTA: + desc = oem_qct_get_evt_desc(intf, rec); + break; case IPMI_OEM_UNKNOWN: default: break; @@ -1282,9 +1259,9 @@ ipmi_get_first_event_sensor_type(struct ipmi_intf *intf, code = event_type; } - for (evt = start; evt->desc != NULL || next != NULL; evt++) { + for (evt = start; evt->desc || next; evt++) { /* check if VITA sensor event types has finished */ - if (evt->desc == NULL) { + if (!evt->desc) { /* proceed with next table */ evt = next; next = NULL; @@ -1303,7 +1280,7 @@ ipmi_get_next_event_sensor_type(const struct ipmi_event_sensor_types *evt) { const struct ipmi_event_sensor_types *start = evt; - for (evt = start + 1; evt->desc != NULL; evt++) { + for (evt = start + 1; evt->desc; evt++) { if (evt->code == start->code) { return evt; } @@ -1321,7 +1298,7 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char char *sfx = NULL; /* This will be assigned if the Platform is DELL, additional info is appended to the current Description */ - if (desc == NULL) + if (!desc) return; *desc = NULL; @@ -1349,6 +1326,9 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char sfx = ipmi_get_oem_desc(intf, rec); break; /* add your oem sensor assignation here */ + case IPMI_OEM_QUANTA: + sfx = ipmi_get_oem_desc(intf, rec); + break; default: lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description", rec->sel_type.standard_type.sensor_type ); @@ -1359,9 +1339,12 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char case IPMI_OEM_SUPERMICRO: case IPMI_OEM_SUPERMICRO_47488: sfx = ipmi_get_oem_desc(intf, rec); - break; + break; + case IPMI_OEM_QUANTA: + sfx = ipmi_get_oem_desc(intf, rec); + break; default: - break; + break; } } /* @@ -1387,10 +1370,11 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char offset = rec->sel_type.standard_type.event_data[0] & 0xf; for (evt = ipmi_get_first_event_sensor_type(intf, - rec->sel_type.standard_type.sensor_type, - rec->sel_type.standard_type.event_type); - evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) { - if ((evt->offset == offset && evt->desc != NULL) && + rec->sel_type.standard_type.sensor_type, + rec->sel_type.standard_type.event_type); + evt; evt = ipmi_get_next_event_sensor_type(evt)) + { + if ((evt->offset == offset && evt->desc) && ((evt->data == ALL_OFFSETS_SPECIFIED) || ((rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK) && (evt->data == rec->sel_type.standard_type.event_data[1])))) @@ -1513,7 +1497,7 @@ ipmi_get_sensor_type(struct ipmi_intf *intf, uint8_t code) type = ipmi_get_generic_sensor_type(code); } - if (type == NULL) { + if (!type) { type = "Unknown"; } @@ -1537,10 +1521,10 @@ ipmi_sel_get_info(struct ipmi_intf * intf) req.msg.cmd = IPMI_CMD_GET_SEL_INFO; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get SEL Info command failed"); return -1; - } else if (rsp->ccode > 0) { + } else if (rsp->ccode) { lprintf(LOG_ERR, "Get SEL Info command failed: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -1583,14 +1567,14 @@ ipmi_sel_get_info(struct ipmi_intf * intf) printf("Last Add Time : Not Available\n"); else printf("Last Add Time : %s\n", - ipmi_sel_timestamp(buf2long(rsp->data + 5))); + ipmi_timestamp_numeric(buf2long(rsp->data + 5))); if ((!memcmp(rsp->data + 9, &fs, 4)) || (!memcmp(rsp->data + 9, &zeros, 4))) printf("Last Del Time : Not Available\n"); else printf("Last Del Time : %s\n", - ipmi_sel_timestamp(buf2long(rsp->data + 9))); + ipmi_timestamp_numeric(buf2long(rsp->data + 9))); printf("Overflow : %s\n", @@ -1618,12 +1602,12 @@ ipmi_sel_get_info(struct ipmi_intf * intf) req.msg.cmd = IPMI_CMD_GET_SEL_ALLOC_INFO; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get SEL Allocation Info command failed"); return -1; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Get SEL Allocation Info command failed: %s", val2str(rsp->ccode, completion_code_vals)); @@ -1664,11 +1648,11 @@ ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id, req.msg.data_len = 6; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get SEL Entry %x command failed", id); return 0; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Get SEL Entry %x command failed: %s", id, val2str(rsp->ccode, completion_code_vals)); return 0; @@ -1751,7 +1735,7 @@ ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt { char * description; - if (fp == NULL) + if (!fp) return; ipmi_get_event_desc(intf, evt, &description); @@ -1766,9 +1750,9 @@ ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt evt->sel_type.standard_type.event_data[2], ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type), evt->sel_type.standard_type.sensor_num, - (description != NULL) ? description : "Unknown"); + description ? description : "Unknown"); - if (description != NULL) { + if (description) { free(description); description = NULL; } @@ -1828,18 +1812,19 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) } else { if (evt->record_type < 0xc0) - printf("%s", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp)); + printf("%s", ipmi_timestamp_date(evt->sel_type.standard_type.timestamp)); else - printf("%s", ipmi_sel_timestamp_date(evt->sel_type.oem_ts_type.timestamp)); + printf("%s", ipmi_timestamp_date(evt->sel_type.oem_ts_type.timestamp)); + if (csv_output) printf(","); else printf(" | "); - + if (evt->record_type < 0xc0) - printf("%s", ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp)); + printf("%s", ipmi_timestamp_time(evt->sel_type.standard_type.timestamp)); else - printf("%s", ipmi_sel_timestamp_time(evt->sel_type.oem_ts_type.timestamp)); + printf("%s", ipmi_timestamp_time(evt->sel_type.oem_ts_type.timestamp)); if (csv_output) printf(","); @@ -1877,13 +1862,13 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++) printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]); } - ipmi_sel_oem_message(evt, 0); + ipmi_sel_oem_message(evt); printf ("\n"); return; } /* lookup SDR entry based on sensor number and type */ - if (sdr != NULL) { + if (sdr) { printf("%s ", ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type)); switch (sdr->type) { @@ -1940,7 +1925,7 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) printf("Asserted"); } - if (sdr != NULL && evt->sel_type.standard_type.event_type == 1) { + if (sdr && evt->sel_type.standard_type.event_type == 1) { /* * Threshold Event */ @@ -1970,8 +1955,20 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) (trigger_reading==(int)trigger_reading) ? 0 : 2, trigger_reading); if (threshold_reading_provided) { + /* According to Table 29-6, Event Data byte 1 contains, + * among other info, the offset from the Threshold type + * code. According to Table 42-2, all even offsets + * are 'going low', and all odd offsets are 'going high' + */ + bool going_high = + (evt->sel_type.standard_type.event_data[0] + & EVENT_OFFSET_MASK) % 2; + if (evt->sel_type.standard_type.event_dir) { + /* Event is de-asserted so the inequality is reversed */ + going_high = !going_high; + } printf(" %s Threshold %.*f %s", - ((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<", + going_high ? ">" : "<", (threshold_reading==(int)threshold_reading) ? 0 : 2, threshold_reading, ipmi_sdr_get_unit_string(sdr->record.common->unit.pct, @@ -1986,9 +1983,12 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) case IPMI_OEM_SUPERMICRO: case IPMI_OEM_SUPERMICRO_47488: print_sensor = 0; - break; + break; + case IPMI_OEM_QUANTA: + print_sensor = 0; + break; default: - break; + break; } /* * Sensor-Specific Discrete @@ -2043,11 +2043,11 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor { printf(" Timestamp : "); if (evt->record_type < 0xc0) - printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp), - ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp)); + printf("%s %s", ipmi_timestamp_date(evt->sel_type.standard_type.timestamp), + ipmi_timestamp_time(evt->sel_type.standard_type.timestamp)); else - printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.oem_ts_type.timestamp), - ipmi_sel_timestamp_time(evt->sel_type.oem_ts_type.timestamp)); + printf("%s %s", ipmi_timestamp_date(evt->sel_type.oem_ts_type.timestamp), + ipmi_timestamp_time(evt->sel_type.oem_ts_type.timestamp)); printf("\n"); } @@ -2068,7 +2068,7 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++) printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]); printf(" [%s]\n\n",hex2ascii (evt->sel_type.oem_nots_type.oem_defined, SEL_OEM_NOTS_DATA_LEN)); - ipmi_sel_oem_message(evt, 1); + ipmi_sel_oem_message(evt); } return; } @@ -2111,7 +2111,7 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_ evt->sel_type.standard_type.gen_id, evt->sel_type.standard_type.sensor_num, evt->sel_type.standard_type.sensor_type); - if (sdr == NULL) + if (!sdr) { ipmi_sel_print_std_entry_verbose(intf, evt); return; @@ -2133,8 +2133,8 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_ if (evt->record_type < 0xe0) { printf(" Timestamp : "); - printf("%s %s\n", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp), - ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp)); + printf("%s %s\n", ipmi_timestamp_date(evt->sel_type.standard_type.timestamp), + ipmi_timestamp_time(evt->sel_type.standard_type.timestamp)); } @@ -2268,11 +2268,11 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav req.msg.cmd = IPMI_CMD_GET_SEL_INFO; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get SEL Info command failed"); return -1; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Get SEL Info command failed: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -2285,21 +2285,6 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav return 0; } - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_STORAGE; - req.msg.cmd = IPMI_CMD_RESERVE_SEL; - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { - lprintf(LOG_ERR, "Reserve SEL command failed"); - return -1; - } - if (rsp->ccode > 0) { - lprintf(LOG_ERR, "Reserve SEL command failed: %s", - val2str(rsp->ccode, completion_code_vals)); - return -1; - } - if (count < 0) { /** Show only the most recent 'count' records. */ int i; @@ -2307,11 +2292,11 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav req.msg.cmd = IPMI_CMD_GET_SEL_INFO; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Get SEL Info command failed"); return -1; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Get SEL Info command failed: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -2336,7 +2321,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav } } - if (savefile != NULL) { + if (savefile) { fp = ipmi_open_file_write(savefile); } @@ -2361,7 +2346,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav else ipmi_sel_print_std_entry(intf, &evt); - if (fp != NULL) { + if (fp) { if (binary) fwrite(&evt, 1, 16, fp); else @@ -2373,7 +2358,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav } } - if (fp != NULL) + if (fp) fclose(fp); return 0; @@ -2410,7 +2395,7 @@ ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana, * the command line */ sel_iana = iana; - if (strncmp("pps", format, 3) == 0) { + if (!strcmp("pps", format)) { /* Parser for the following format */ /* 0x001F: Event: at Mar 27 06:41:10 2007;from:(0x9a,0,7); * sensor:(0xc3,119); event:0x6f(asserted): 0xA3 0x00 0x88 @@ -2418,13 +2403,13 @@ ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana, * Supports a tweak for hotswap events that are already interpreted. */ fp = ipmi_open_file(readfile, 0); - if (fp == NULL) { + if (!fp) { lprintf(LOG_ERR, "Failed to open file '%s' for reading.", readfile); return (-1); } buffer = (char *)malloc((size_t)256); - if (buffer == NULL) { + if (!buffer) { lprintf(LOG_ERR, "ipmitool: malloc failure"); fclose(fp); return (-1); @@ -2433,7 +2418,7 @@ ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana, /* Only allow complete lines to be parsed, * hardcoded maximum line length */ - if (fgets(buffer, 256, fp) == NULL) { + if (!fgets(buffer, 256, fp)) { status = (-1); break; } @@ -2687,11 +2672,11 @@ ipmi_sel_reserve(struct ipmi_intf * intf) req.msg.cmd = IPMI_CMD_RESERVE_SEL; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_WARN, "Unable to reserve SEL"); return 0; } - if (rsp->ccode > 0) { + if (rsp->ccode) { printf("Unable to reserve SEL: %s", val2str(rsp->ccode, completion_code_vals)); return 0; @@ -2713,8 +2698,6 @@ ipmi_sel_get_time(struct ipmi_intf * intf) { struct ipmi_rs * rsp; struct ipmi_rq req; - static char tbuf[40]; - uint32_t timei; time_t time; memset(&req, 0, sizeof(req)); @@ -2723,13 +2706,12 @@ ipmi_sel_get_time(struct ipmi_intf * intf) rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { - lprintf(LOG_ERR, "Get SEL Time command failed"); - return -1; - } - if (rsp->ccode > 0) { + if (!rsp || rsp->ccode) { lprintf(LOG_ERR, "Get SEL Time command failed: %s", - val2str(rsp->ccode, completion_code_vals)); + rsp + ? val2str(rsp->ccode, completion_code_vals) + : "Unknown" + ); return -1; } if (rsp->data_len != 4) { @@ -2738,15 +2720,8 @@ ipmi_sel_get_time(struct ipmi_intf * intf) return -1; } - memcpy(&timei, rsp->data, 4); -#if WORDS_BIGENDIAN - time = (time_t)(BSWAP_32(timei)); -#else - time = (time_t)timei; -#endif - - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&time)); - printf("%s\n", tbuf); + time = ipmi32toh(rsp->data); + printf("%s\n", ipmi_timestamp_numeric(time)); return 0; } @@ -2762,76 +2737,65 @@ ipmi_sel_get_time(struct ipmi_intf * intf) static int ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - struct tm tm = {0}; - time_t t; - uint32_t timei; - const char * time_format = "%m/%d/%Y %H:%M:%S"; + struct ipmi_rs *rsp; + struct ipmi_rq req; + struct tm tm = {0}; + uint8_t msg_data[4] = {0}; + time_t t; + const char *time_format = "%x %X"; /* Use locale-defined format */ memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_STORAGE; req.msg.cmd = IPMI_SET_SEL_TIME; /* See if user requested set to current client system time */ - if (strncasecmp(time_string, "now", 3) == 0) { + if (strcasecmp(time_string, "now") == 0) { t = time(NULL); + /* + * Now we have local time in t, but BMC requires UTC + */ + t = ipmi_localtime2utc(t); } else { - /* Now how do we get our time_t from our ascii version? */ - if (strptime(time_string, time_format, &tm) == 0) { - lprintf(LOG_ERR, "Specified time could not be parsed"); - return -1; + bool error = true; /* Assume the string is invalid */ + /* Now let's extract time_t from the supplied string */ + if (strptime(time_string, time_format, &tm) != NULL) { + tm.tm_isdst = (-1); /* look up DST information */ + t = mktime(&tm); + if (t >= 0) { + /* Surprisingly, the user hasn't mistaken ;) */ + error = false; + } } - tm.tm_isdst = (-1); /* look up DST information */ - t = mktime(&tm); - if (t < 0) { + + if (error) { lprintf(LOG_ERR, "Specified time could not be parsed"); return -1; } + + /* + * If `-c` wasn't specified then t we've just got is in local timesone + */ + if (!time_in_utc) { + t = ipmi_localtime2utc(t); + } } - { - //modify UTC time to local time expressed in number of seconds from 1/1/70 0:0:0 1970 GMT - struct tm * tm_tmp = {0}; - int gt_year,gt_yday,gt_hour,gt_min,lt_year,lt_yday,lt_hour,lt_min; - int delta_hour; - tm_tmp=gmtime(&t); - gt_year=tm_tmp->tm_year; - gt_yday=tm_tmp->tm_yday; - gt_hour=tm_tmp->tm_hour; - gt_min=tm_tmp->tm_min; - memset(&*tm_tmp, 0, sizeof(struct tm)); - tm_tmp=localtime(&t); - lt_year=tm_tmp->tm_year; - lt_yday=tm_tmp->tm_yday; - lt_hour=tm_tmp->tm_hour; - lt_min=tm_tmp->tm_min; - delta_hour=lt_hour - gt_hour; - if ( (lt_year > gt_year) || ((lt_year == gt_year) && (lt_yday > gt_yday)) ) - delta_hour += 24; - if ( (lt_year < gt_year) || ((lt_year == gt_year) && (lt_yday < gt_yday)) ) - delta_hour -= 24; - - t += (delta_hour * 60 * 60) + (lt_min - gt_min) * 60; - } - - timei = (uint32_t)t; - req.msg.data = (uint8_t *)&timei; - req.msg.data_len = 4; - -#if WORDS_BIGENDIAN - timei = BSWAP_32(timei); -#endif + /* + * At this point `t` is UTC. Convert it to LE and send. + */ + + req.msg.data = msg_data; + htoipmi32(t, req.msg.data); + req.msg.data_len = sizeof(msg_data); rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { - lprintf(LOG_ERR, "Set SEL Time command failed"); - return -1; - } - if (rsp->ccode > 0) { + if (!rsp || rsp->ccode) { lprintf(LOG_ERR, "Set SEL Time command failed: %s", - val2str(rsp->ccode, completion_code_vals)); + rsp + ? val2str(rsp->ccode, completion_code_vals) + : "Unknown" + ); return -1; } @@ -2840,8 +2804,6 @@ ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string) return 0; } - - static int ipmi_sel_clear(struct ipmi_intf * intf) { @@ -2869,11 +2831,11 @@ ipmi_sel_clear(struct ipmi_intf * intf) req.msg.data_len = 6; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Unable to clear SEL"); return -1; } - if (rsp->ccode > 0) { + if (rsp->ccode) { lprintf(LOG_ERR, "Unable to clear SEL: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -2892,7 +2854,7 @@ ipmi_sel_delete(struct ipmi_intf * intf, int argc, char ** argv) uint8_t msg_data[4]; int rc = 0; - if (argc == 0 || strncmp(argv[0], "help", 4) == 0) { + if (!argc || !strcmp(argv[0], "help")) { lprintf(LOG_ERR, "usage: delete <id>...<id>\n"); return -1; } @@ -2923,11 +2885,11 @@ ipmi_sel_delete(struct ipmi_intf * intf, int argc, char ** argv) req.msg.data_len = 4; rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Unable to delete entry %d", id); rc = -1; } - else if (rsp->ccode > 0) { + else if (rsp->ccode) { lprintf(LOG_ERR, "Unable to delete entry %d: %s", id, val2str(rsp->ccode, completion_code_vals)); rc = -1; @@ -2953,16 +2915,11 @@ ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv) int rc = 0; uint16_t id; - if (argc == 0 || strncmp(argv[0], "help", 4) == 0) { + if (!argc || !strcmp(argv[0], "help")) { lprintf(LOG_ERR, "usage: sel get <id>...<id>"); return (-1); } - if (ipmi_sel_reserve(intf) == 0) { - lprintf(LOG_ERR, "Unable to reserve SEL"); - return (-1); - } - for (i = 0; i < argc; i++) { if (str2ushort(argv[i], &id) != 0) { lprintf(LOG_ERR, "Given SEL ID '%s' is invalid.", @@ -2994,7 +2951,7 @@ ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv) evt.sel_type.standard_type.gen_id, evt.sel_type.standard_type.sensor_num, evt.sel_type.standard_type.sensor_type); - if (sdr == NULL) { + if (!sdr) { continue; } @@ -3042,10 +2999,10 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) if (argc == 0) rc = ipmi_sel_get_info(intf); - else if (strncmp(argv[0], "help", 4) == 0) + else if (!strcmp(argv[0], "help")) lprintf(LOG_ERR, "SEL Commands: " "info clear delete list elist get add time save readraw writeraw interpret"); - else if (strncmp(argv[0], "interpret", 9) == 0) { + else if (!strcmp(argv[0], "interpret")) { uint32_t iana = 0; if (argc < 4) { lprintf(LOG_NOTICE, "usage: sel interpret iana filename format(pps)"); @@ -3058,37 +3015,37 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) } rc = ipmi_sel_interpret(intf, iana, argv[2], argv[3]); } - else if (strncmp(argv[0], "info", 4) == 0) + else if (!strcmp(argv[0], "info")) rc = ipmi_sel_get_info(intf); - else if (strncmp(argv[0], "save", 4) == 0) { + else if (!strcmp(argv[0], "save")) { if (argc < 2) { lprintf(LOG_NOTICE, "usage: sel save <filename>"); return 0; } rc = ipmi_sel_save_entries(intf, 0, argv[1]); } - else if (strncmp(argv[0], "add", 3) == 0) { + else if (!strcmp(argv[0], "add")) { if (argc < 2) { lprintf(LOG_NOTICE, "usage: sel add <filename>"); return 0; } rc = ipmi_sel_add_entries_fromfile(intf, argv[1]); } - else if (strncmp(argv[0], "writeraw", 8) == 0) { + else if (!strcmp(argv[0], "writeraw")) { if (argc < 2) { lprintf(LOG_NOTICE, "usage: sel writeraw <filename>"); return 0; } rc = ipmi_sel_writeraw(intf, argv[1]); } - else if (strncmp(argv[0], "readraw", 7) == 0) { + else if (!strcmp(argv[0], "readraw")) { if (argc < 2) { lprintf(LOG_NOTICE, "usage: sel readraw <filename>"); return 0; } rc = ipmi_sel_readraw(intf, argv[1]); } - else if (strncmp(argv[0], "ereadraw", 8) == 0) { + else if (!strcmp(argv[0], "ereadraw")) { if (argc < 2) { lprintf(LOG_NOTICE, "usage: sel ereadraw <filename>"); return 0; @@ -3096,8 +3053,9 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) sel_extended = 1; rc = ipmi_sel_readraw(intf, argv[1]); } - else if (strncmp(argv[0], "list", 4) == 0 || - strncmp(argv[0], "elist", 5) == 0) { + else if (!strcmp(argv[0], "list") + || !strcmp(argv[0], "elist")) + { /* * Usage: * list - show all SEL entries @@ -3108,7 +3066,7 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) int sign = 1; char *countstr = NULL; - if (strncmp(argv[0], "elist", 5) == 0) + if (!strcmp(argv[0], "elist")) sel_extended = 1; else sel_extended = 0; @@ -3119,10 +3077,10 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) else if (argc == 3) { countstr = argv[2]; - if (strncmp(argv[1], "last", 4) == 0) { + if (!strcmp(argv[1], "last")) { sign = -1; } - else if (strncmp(argv[1], "first", 5) != 0) { + else if (strcmp(argv[1], "first")) { lprintf(LOG_ERR, "Unknown sel list option"); return -1; } @@ -3139,26 +3097,26 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) rc = ipmi_sel_list_entries(intf,count); } - else if (strncmp(argv[0], "clear", 5) == 0) + else if (!strcmp(argv[0], "clear")) rc = ipmi_sel_clear(intf); - else if (strncmp(argv[0], "delete", 6) == 0) { + else if (!strcmp(argv[0], "delete")) { if (argc < 2) lprintf(LOG_ERR, "usage: sel delete <id>...<id>"); else rc = ipmi_sel_delete(intf, argc-1, &argv[1]); } - else if (strncmp(argv[0], "get", 3) == 0) { + else if (!strcmp(argv[0], "get")) { if (argc < 2) lprintf(LOG_ERR, "usage: sel get <entry>"); else rc = ipmi_sel_show_entry(intf, argc-1, &argv[1]); } - else if (strncmp(argv[0], "time", 4) == 0) { + else if (!strcmp(argv[0], "time")) { if (argc < 2) lprintf(LOG_ERR, "sel time commands: get set"); - else if (strncmp(argv[1], "get", 3) == 0) + else if (!strcmp(argv[1], "get")) ipmi_sel_get_time(intf); - else if (strncmp(argv[1], "set", 3) == 0) { + else if (!strcmp(argv[1], "set")) { if (argc < 3) lprintf(LOG_ERR, "usage: sel time set \"mm/dd/yyyy hh:mm:ss\""); else |