Refactor timestamp handling

Handle all date/time stamps uniformly, taking in account the host
endianness. Respect the local time zone and the '-Z' option for
all ipmitool commands. Unify the date and time formatting.
Add correct handling of IPMI timestamps 'since system startup'
and for 'unspecified' timestamps.

Partially resolves ipmitool/ipmitool#23

Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
This commit is contained in:
Alexander Amelkin 2018-07-26 19:40:44 +03:00
parent a4ac8ce4ab
commit f0d5c17ea7
No known key found for this signature in database
GPG Key ID: E893587B5B74178D
16 changed files with 485 additions and 367 deletions

View File

@ -67,7 +67,6 @@
#define IPMI_PAYLOAD_TYPE_RAKP_4 0x15 #define IPMI_PAYLOAD_TYPE_RAKP_4 0x15
extern int verbose; extern int verbose;
extern int time_in_utc;
extern int csv_output; extern int csv_output;
struct ipmi_rq { struct ipmi_rq {

View File

@ -591,7 +591,10 @@ struct fru_picmgext_amc_link_desc_record {
#endif #endif
/* FRU Board manufacturing date */ /* FRU Board manufacturing date */
static const uint64_t secs_from_1970_1996 = 820454400; static inline time_t ipmi_fru2time_t(void *mfg_date) {
const uint64_t secs_from_1970_1996 = 820454400;
return ipmi24toh(mfg_date) * 60 + secs_from_1970_1996;
}
static const char * chassis_type_desc[] __attribute__((unused)) = { static const char * chassis_type_desc[] __attribute__((unused)) = {
"Unspecified", "Other", "Unknown", "Unspecified", "Other", "Unknown",
"Desktop", "Low Profile Desktop", "Pizza Box", "Desktop", "Low Profile Desktop", "Pizza Box",

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2018 Alexander Amelkin. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holder, nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* THE COPYRIGHT HOLDER AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* THE COPYRIGHT HOLDER OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
* PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE
* THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS
* SOFTWARE, EVEN IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
*/
#ifndef IPMI_TIME_H
#define IPMI_TIME_H
#include <time.h>
#include <stdbool.h>
extern bool time_in_utc;
/* Special values according to IPMI v2.0, rev. 1.1, section 37.1 */
#define IPMI_TIME_UNSPECIFIED 0xFFFFFFFFu
#define IPMI_TIME_INIT_DONE 0x20000000u
#define SECONDS_A_DAY (24 * 60 * 60)
/*
* Check whether the timestamp is in seconds since Epoch or since
* the system startup.
*/
static inline bool ipmi_timestamp_is_special(time_t ts)
{
return (ts < IPMI_TIME_INIT_DONE);
}
/*
* Check whether the timestamp is valid at all
*/
static inline bool ipmi_timestamp_is_valid(time_t ts)
{
return (ts != IPMI_TIME_UNSPECIFIED);
}
/*
* Just 26 characters are required for asctime_r(), plus timezone info.
* However just to be safe locale-wise and assuming that in no locale
* the date/time string exceeds the 'standard' legacy terminal width,
* the buffer size is set here to 80.
*/
#define IPMI_ASCTIME_SZ 80
typedef char ipmi_datebuf_t[IPMI_ASCTIME_SZ];
/*
* These are ipmitool-specific versions that take
* in account the command line options
*/
char *ipmi_asctime_r(time_t stamp, ipmi_datebuf_t outbuf);
size_t ipmi_strftime(char *s, int max, const char *format, time_t stamp);
/* These return pointers to static arrays and aren't thread safe */
char *ipmi_timestamp_fmt(uint32_t stamp, const char *fmt);
char *ipmi_timestamp_string(uint32_t stamp); /* Day Mon DD HH:MM:SS YYYY ZZZ */
char *ipmi_timestamp_numeric(uint32_t stamp); /* MM/DD/YYYY HH:MM:SS ZZZ */
char *ipmi_timestamp_date(uint32_t stamp); /* MM/DD/YYYY ZZZ */
char *ipmi_timestamp_time(uint32_t stamp); /* HH:MM:SS ZZZ */
/* Subtract the UTC offset from local time_t */
time_t ipmi_localtime2utc(time_t local);
#endif

View File

@ -42,7 +42,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \ ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \ ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \ ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
ipmi_lanp6.c ipmi_cfgp.c ipmi_quantaoem.c \ ipmi_lanp6.c ipmi_cfgp.c ipmi_quantaoem.c ipmi_time.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h ../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic libipmitool_la_LDFLAGS = -export-dynamic

View File

@ -42,6 +42,7 @@
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_chassis.h> #include <ipmitool/ipmi_chassis.h>
#include <ipmitool/ipmi_time.h>
extern int verbose; extern int verbose;
@ -699,45 +700,19 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
case 6: case 6:
{ {
unsigned long session_id; unsigned long session_id;
unsigned long timestamp; uint32_t timestamp;
char time_buf[40];
time_t out_time;
struct tm *strtm;
session_id = ((unsigned long) rsp->data[3]); session_id = ((unsigned long) rsp->data[3]);
session_id |= (((unsigned long) rsp->data[4])<<8); session_id |= (((unsigned long) rsp->data[4])<<8);
session_id |= (((unsigned long) rsp->data[5])<<16); session_id |= (((unsigned long) rsp->data[5])<<16);
session_id |= (((unsigned long) rsp->data[6])<<24); session_id |= (((unsigned long) rsp->data[6])<<24);
timestamp = ((unsigned long) rsp->data[7]); timestamp = ipmi32toh(&rsp->data[7]);
timestamp |= (((unsigned long) rsp->data[8])<<8);
timestamp |= (((unsigned long) rsp->data[9])<<16);
timestamp |= (((unsigned long) rsp->data[10])<<24);
memset(time_buf, 0, 40);
if(time_in_utc)
strtm = gmtime(&out_time);
else
strtm = localtime(&out_time);
strftime(
time_buf,
sizeof(time_buf),
"%m/%d/%Y %H:%M:%S", strtm
);
printf(" Boot Initiator Info :\n"); printf(" Boot Initiator Info :\n");
printf(" Channel Number : %d\n", (rsp->data[2] & 0x0f)); printf(" Channel Number : %d\n", (rsp->data[2] & 0x0f));
printf(" Session Id : %08lXh\n",session_id); printf(" Session Id : %08lXh\n",session_id);
if(timestamp != 0) printf(" Timestamp : %s\n", ipmi_timestamp_numeric(timestamp));
{
printf(" Timestamp : %08lXh, %s\n",timestamp,time_buf);
}
else
{
printf(" Timestamp : %08lXh, undefined\n",timestamp);
}
} }
break; break;
case 7: case 7:

View File

@ -56,6 +56,7 @@
#include <ipmitool/ipmi_entity.h> #include <ipmitool/ipmi_entity.h>
#include <ipmitool/ipmi_constants.h> #include <ipmitool/ipmi_constants.h>
#include <ipmitool/ipmi_sensor.h> #include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_time.h>
#include "../src/plugins/lanplus/lanplus.h" #include "../src/plugins/lanplus/lanplus.h"
@ -1399,11 +1400,7 @@ ipmi_dcmi_pwr_rd(struct ipmi_intf * intf, uint8_t sample_time)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
struct power_reading val; struct power_reading val;
struct tm tm_t;
time_t t;
uint8_t msg_data[4]; /* number of request data bytes */ uint8_t msg_data[4]; /* number of request data bytes */
memset(&tm_t, 0, sizeof(tm_t));
memset(&t, 0, sizeof(t));
msg_data[0] = IPMI_DCMI; /* Group Extension Identification */ msg_data[0] = IPMI_DCMI; /* Group Extension Identification */
if (sample_time) { if (sample_time) {
@ -1429,8 +1426,6 @@ ipmi_dcmi_pwr_rd(struct ipmi_intf * intf, uint8_t sample_time)
/* rsp->data[0] is equal to response data byte 2 in spec */ /* rsp->data[0] is equal to response data byte 2 in spec */
/* printf("Group Extension Identification: %02x\n", rsp->data[0]); */ /* printf("Group Extension Identification: %02x\n", rsp->data[0]); */
memcpy(&val, rsp->data, sizeof (val)); memcpy(&val, rsp->data, sizeof (val));
t = val.time_stamp;
gmtime_r(&t, &tm_t);
printf("\n"); printf("\n");
printf(" Instantaneous power reading: %8d Watts\n", printf(" Instantaneous power reading: %8d Watts\n",
val.curr_pwr); val.curr_pwr);
@ -1441,7 +1436,7 @@ ipmi_dcmi_pwr_rd(struct ipmi_intf * intf, uint8_t sample_time)
printf(" Average power reading over sample period: %8d Watts\n", printf(" Average power reading over sample period: %8d Watts\n",
val.avg_pwr); val.avg_pwr);
printf(" IPMI timestamp: %s", printf(" IPMI timestamp: %s",
asctime(&tm_t)); ipmi_timestamp_numeric(ipmi32toh(&val.time_stamp)));
printf(" Sampling period: "); printf(" Sampling period: ");
if (sample_time) if (sample_time)
printf("%s \n", val2str2(val.sample,dcmi_sampling_vals)); printf("%s \n", val2str2(val.sample,dcmi_sampling_vals));
@ -2876,12 +2871,8 @@ ipmi_nm_get_statistics(struct ipmi_intf * intf, int argc, char **argv)
uint8_t policy_id = -1; uint8_t policy_id = -1;
uint8_t have_policy_id = FALSE; uint8_t have_policy_id = FALSE;
int policy_mode = 0; int policy_mode = 0;
int cut;
char *units = ""; char *units = "";
char datebuf[27];
struct nm_statistics stats; struct nm_statistics stats;
struct tm tm_t;
time_t t;
argv++; argv++;
if (!argv[0] || if (!argv[0] ||
@ -2943,11 +2934,6 @@ ipmi_nm_get_statistics(struct ipmi_intf * intf, int argc, char **argv)
} }
if (_ipmi_nm_statistics(intf, mode, domain, policy_id, &stats)) if (_ipmi_nm_statistics(intf, mode, domain, policy_id, &stats))
return -1; return -1;
t = stats.time_stamp;
gmtime_r(&t, &tm_t);
sprintf(datebuf, "%s", asctime(&tm_t));
cut = strlen(datebuf) -1;
datebuf[cut] = 0;
if (csv_output) { if (csv_output) {
printf("%s,%s,%s,%s,%s,%d,%d,%d,%d,%s,%d\n", printf("%s,%s,%s,%s,%s,%d,%d,%d,%d,%s,%d\n",
val2str2(stats.id_state & 0xF, nm_domain_vals), val2str2(stats.id_state & 0xF, nm_domain_vals),
@ -2964,7 +2950,7 @@ ipmi_nm_get_statistics(struct ipmi_intf * intf, int argc, char **argv)
stats.min_value, stats.min_value,
stats.max_value, stats.max_value,
stats.ave_value, stats.ave_value,
datebuf, ipmi_timestamp_numeric(ipmi32toh(&stats.time_stamp)),
stats.stat_period); stats.stat_period);
return 0; return 0;
} }
@ -2992,7 +2978,7 @@ ipmi_nm_get_statistics(struct ipmi_intf * intf, int argc, char **argv)
printf(" Average reading over sample period: %8d %s\n", printf(" Average reading over sample period: %8d %s\n",
stats.ave_value, units); stats.ave_value, units);
printf(" IPMI timestamp: %s\n", printf(" IPMI timestamp: %s\n",
datebuf); ipmi_timestamp_numeric(ipmi32toh(&stats.time_stamp)));
printf(" Sampling period: %08d Seconds.\n", printf(" Sampling period: %08d Seconds.\n",
stats.stat_period); stats.stat_period);
printf("\n"); printf("\n");

View File

@ -62,6 +62,7 @@
#include <ipmitool/ipmi_entity.h> #include <ipmitool/ipmi_entity.h>
#include <ipmitool/ipmi_fru.h> #include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_sensor.h> #include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_time.h>
#define DELL_OEM_NETFN (uint8_t)(0x30) #define DELL_OEM_NETFN (uint8_t)(0x30)
#define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) #define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9)
@ -201,7 +202,6 @@ static int ipmi_lan_set_nic_selection_12g(struct ipmi_intf *intf,
/* Power monitor Function prototypes */ /* Power monitor Function prototypes */
static int ipmi_delloem_powermonitor_main(struct ipmi_intf *intf, int argc, static int ipmi_delloem_powermonitor_main(struct ipmi_intf *intf, int argc,
char **argv); char **argv);
static void ipmi_time_to_str(time_t rawTime, char *strTime);
static int ipmi_get_sensor_reading(struct ipmi_intf *intf, static int ipmi_get_sensor_reading(struct ipmi_intf *intf,
unsigned char sensorNumber, SensorReadingType *pSensorReadingData); unsigned char sensorNumber, SensorReadingType *pSensorReadingData);
static int ipmi_get_power_capstatus_command(struct ipmi_intf *intf); static int ipmi_get_power_capstatus_command(struct ipmi_intf *intf);
@ -2601,24 +2601,7 @@ ipmi_delloem_powermonitor_main(struct ipmi_intf * intf, int argc, char ** argv)
} }
return rc; return rc;
} }
/*
* Function Name: ipmi_time_to_str
*
* Description: This function converts ipmi time format into gmtime format
* Input: rawTime - ipmi time format
* Output: strTime - gmtime format
*
* Return:
*/
static void
ipmi_time_to_str(time_t rawTime, char * strTime)
{
struct tm *tm;
char *temp;
tm = gmtime(&rawTime);
temp = asctime(tm);
strcpy(strTime,temp);
}
/* /*
* Function Name: ipmi_get_sensor_reading * Function Name: ipmi_get_sensor_reading
* *
@ -2768,24 +2751,15 @@ ipmi_powermgmt(struct ipmi_intf * intf)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint8_t msg_data[2]; uint8_t msg_data[2];
uint32_t cumStartTimeConv; uint32_t cumStartTime;
uint32_t cumReadingConv; uint32_t cumReading;
uint32_t maxPeakStartTimeConv; uint32_t maxPeakStartTime;
uint32_t ampPeakTimeConv; uint32_t ampPeakTime;
uint16_t ampReadingConv; uint32_t wattPeakTime;
uint32_t wattPeakTimeConv; uint32_t bmctime;
uint32_t wattReadingConv;
uint32_t bmctimeconv;
uint32_t * bmctimeconvval;
IPMI_POWER_MONITOR * pwrMonitorInfo; IPMI_POWER_MONITOR * pwrMonitorInfo;
char cumStartTime[26];
char maxPeakStartTime[26];
char ampPeakTime[26];
char wattPeakTime[26];
char bmctime[26];
int ampReading; int ampReading;
int ampReadingRemainder; int ampReadingRemainder;
int remainder; int remainder;
@ -2807,12 +2781,7 @@ ipmi_powermgmt(struct ipmi_intf * intf)
rsp->ccode); rsp->ccode);
return -1; return -1;
} }
bmctimeconvval=(uint32_t*)rsp->data; bmctime = ipmi32toh(rsp->data);
# if WORDS_BIGENDIAN
bmctimeconv=BSWAP_32(*bmctimeconvval);
# else
bmctimeconv=*bmctimeconvval;
# endif
/* get powermanagement info*/ /* get powermanagement info*/
req.msg.netfn = DELL_OEM_NETFN; req.msg.netfn = DELL_OEM_NETFN;
@ -2847,54 +2816,35 @@ ipmi_powermgmt(struct ipmi_intf * intf)
} }
pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp->data; pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp->data;
# if WORDS_BIGENDIAN cumStartTime = ipmi32toh(&pwrMonitorInfo->cumStartTime);
cumStartTimeConv = BSWAP_32(pwrMonitorInfo->cumStartTime); cumReading = ipmi32toh(&pwrMonitorInfo->cumReading);
cumReadingConv = BSWAP_32(pwrMonitorInfo->cumReading); maxPeakStartTime = ipmi32toh(&pwrMonitorInfo->maxPeakStartTime);
maxPeakStartTimeConv = BSWAP_32(pwrMonitorInfo->maxPeakStartTime); ampPeakTime = ipmi32toh(&pwrMonitorInfo->ampPeakTime);
ampPeakTimeConv = BSWAP_32(pwrMonitorInfo->ampPeakTime); ampReading = ipmi16toh(&pwrMonitorInfo->ampReading);
ampReadingConv = BSWAP_16(pwrMonitorInfo->ampReading); wattPeakTime = ipmi32toh(&pwrMonitorInfo->wattPeakTime);
wattPeakTimeConv = BSWAP_32(pwrMonitorInfo->wattPeakTime); wattReading = ipmi16toh(&pwrMonitorInfo->wattReading);
wattReadingConv = BSWAP_16(pwrMonitorInfo->wattReading);
# else
cumStartTimeConv = pwrMonitorInfo->cumStartTime;
cumReadingConv = pwrMonitorInfo->cumReading;
maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime;
ampPeakTimeConv = pwrMonitorInfo->ampPeakTime;
ampReadingConv = pwrMonitorInfo->ampReading;
wattPeakTimeConv = pwrMonitorInfo->wattPeakTime;
wattReadingConv = pwrMonitorInfo->wattReading;
# endif
ipmi_time_to_str(cumStartTimeConv, cumStartTime); remainder = (cumReading % 1000);
ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime); cumReading = cumReading / 1000;
ipmi_time_to_str(ampPeakTimeConv, ampPeakTime);
ipmi_time_to_str(wattPeakTimeConv, wattPeakTime);
ipmi_time_to_str(bmctimeconv, bmctime);
remainder = (cumReadingConv % 1000);
cumReadingConv = cumReadingConv / 1000;
remainder = (remainder + 50) / 100; remainder = (remainder + 50) / 100;
ampReading = ampReadingConv; ampReadingRemainder = ampReading % 10;
ampReadingRemainder = ampReading%10; ampReading = ampReading / 10;
ampReading = ampReading/10;
wattReading = wattReadingConv;
printf("Power Tracking Statistics\n"); printf("Power Tracking Statistics\n");
printf("Statistic : Cumulative Energy Consumption\n"); printf("Statistic : Cumulative Energy Consumption\n");
printf("Start Time : %s", cumStartTime); printf("Start Time : %s", ipmi_timestamp_numeric(cumStartTime));
printf("Finish Time : %s", bmctime); printf("Finish Time : %s", ipmi_timestamp_numeric(bmctime));
printf("Reading : %d.%d kWh\n\n", cumReadingConv, remainder); printf("Reading : %d.%d kWh\n\n", cumReading, remainder);
printf("Statistic : System Peak Power\n"); printf("Statistic : System Peak Power\n");
printf("Start Time : %s", maxPeakStartTime); printf("Start Time : %s", ipmi_timestamp_numeric(maxPeakStartTime));
printf("Peak Time : %s", wattPeakTime); printf("Peak Time : %s", ipmi_timestamp_numeric(wattPeakTime));
printf("Peak Reading : %d W\n\n", wattReading); printf("Peak Reading : %d W\n\n", wattReading);
printf("Statistic : System Peak Amperage\n"); printf("Statistic : System Peak Amperage\n");
printf("Start Time : %s", maxPeakStartTime); printf("Start Time : %s", ipmi_timestamp_numeric(maxPeakStartTime));
printf("Peak Time : %s", ampPeakTime); printf("Peak Time : %s", ipmi_timestamp_numeric(ampPeakTime));
printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder); printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder);
return 0; return 0;
} }
@ -3394,12 +3344,7 @@ ipmi_get_minpower_consmpt_history(struct ipmi_intf * intf,
static int static int
ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit) ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit)
{ {
char timestr[30]; uint64_t tmp;
uint32_t lastminutepeakpower;
uint32_t lasthourpeakpower;
uint32_t lastdaypeakpower;
uint32_t lastweekpeakpower;
uint64_t tempbtuphrconv;
int rc = 0; int rc = 0;
IPMI_AVGPOWER_CONSUMP_HISTORY avgpower; IPMI_AVGPOWER_CONSUMP_HISTORY avgpower;
@ -3430,95 +3375,85 @@ ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit)
"Last Day Last Week\n\n"); "Last Day Last Week\n\n");
if (unit == btuphr) { if (unit == btuphr) {
printf("Average Power Consumption "); printf("Average Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastminutepower); tmp = watt_to_btuphr_conversion(avgpower.lastminutepower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lasthourpower); tmp = watt_to_btuphr_conversion(avgpower.lasthourpower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastdaypower); tmp = watt_to_btuphr_conversion(avgpower.lastdaypower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastweakpower); tmp = watt_to_btuphr_conversion(avgpower.lastweakpower);
printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv); printf("%4" PRId64 " BTU/hr\n", tmp);
printf("Max Power Consumption "); printf("Max Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastminutepower); tmp = watt_to_btuphr_conversion(stPeakpower.lastminutepower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lasthourpower); tmp = watt_to_btuphr_conversion(stPeakpower.lasthourpower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastdaypower); tmp = watt_to_btuphr_conversion(stPeakpower.lastdaypower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastweakpower); tmp = watt_to_btuphr_conversion(stPeakpower.lastweakpower);
printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv); printf("%4" PRId64 " BTU/hr\n", tmp);
printf("Min Power Consumption "); printf("Min Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastminutepower); tmp = watt_to_btuphr_conversion(stMinpower.lastminutepower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lasthourpower); tmp = watt_to_btuphr_conversion(stMinpower.lasthourpower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastdaypower); tmp = watt_to_btuphr_conversion(stMinpower.lastdaypower);
printf("%4" PRId64 " BTU/hr ", tempbtuphrconv); printf("%4" PRId64 " BTU/hr ", tmp);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastweakpower); tmp = watt_to_btuphr_conversion(stMinpower.lastweakpower);
printf("%4" PRId64 " BTU/hr\n\n", tempbtuphrconv); printf("%4" PRId64 " BTU/hr\n\n", tmp);
} else { } else {
printf("Average Power Consumption "); printf("Average Power Consumption ");
tempbtuphrconv = (avgpower.lastminutepower); tmp = avgpower.lastminutepower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (avgpower.lasthourpower); tmp = avgpower.lasthourpower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (avgpower.lastdaypower); tmp = avgpower.lastdaypower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv=(avgpower.lastweakpower); tmp = avgpower.lastweakpower;
printf("%4" PRId64 " W \n", tempbtuphrconv); printf("%4" PRId64 " W \n", tmp);
printf("Max Power Consumption "); printf("Max Power Consumption ");
tempbtuphrconv = (stPeakpower.lastminutepower); tmp = stPeakpower.lastminutepower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stPeakpower.lasthourpower); tmp = stPeakpower.lasthourpower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stPeakpower.lastdaypower); tmp = stPeakpower.lastdaypower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stPeakpower.lastweakpower); tmp = stPeakpower.lastweakpower;
printf("%4" PRId64 " W \n", tempbtuphrconv); printf("%4" PRId64 " W \n", tmp);
printf("Min Power Consumption "); printf("Min Power Consumption ");
tempbtuphrconv = (stMinpower.lastminutepower); tmp = stMinpower.lastminutepower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stMinpower.lasthourpower); tmp = stMinpower.lasthourpower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stMinpower.lastdaypower); tmp = stMinpower.lastdaypower;
printf("%4" PRId64 " W ", tempbtuphrconv); printf("%4" PRId64 " W ", tmp);
tempbtuphrconv = (stMinpower.lastweakpower); tmp = stMinpower.lastweakpower;
printf("%4" PRId64 " W \n\n", tempbtuphrconv); printf("%4" PRId64 " W \n\n", tmp);
} }
lastminutepeakpower = stPeakpower.lastminutepowertime;
lasthourpeakpower = stPeakpower.lasthourpowertime;
lastdaypeakpower = stPeakpower.lastdaypowertime;
lastweekpeakpower = stPeakpower.lastweekpowertime;
printf("Max Power Time\n"); printf("Max Power Time\n");
ipmi_time_to_str(lastminutepeakpower, timestr); printf("Last Minute : %s",
printf("Last Minute : %s",timestr); ipmi_timestamp_numeric(stPeakpower.lastminutepowertime));
ipmi_time_to_str(lasthourpeakpower, timestr); printf("Last Hour : %s",
printf("Last Hour : %s",timestr); ipmi_timestamp_numeric(stPeakpower.lasthourpowertime));
ipmi_time_to_str(lastdaypeakpower, timestr); printf("Last Day : %s",
printf("Last Day : %s",timestr); ipmi_timestamp_numeric(stPeakpower.lastdaypowertime));
ipmi_time_to_str(lastweekpeakpower, timestr); printf("Last Week : %s",
printf("Last Week : %s",timestr); ipmi_timestamp_numeric(stPeakpower.lastweekpowertime));
lastminutepeakpower=stMinpower.lastminutepowertime;
lasthourpeakpower=stMinpower.lasthourpowertime;
lastdaypeakpower=stMinpower.lastdaypowertime;
lastweekpeakpower=stMinpower.lastweekpowertime;
printf("Min Power Time\n"); printf("Min Power Time\n");
ipmi_time_to_str(lastminutepeakpower, timestr); printf("Last Minute : %s",
printf("Last Minute : %s", timestr); ipmi_timestamp_numeric(stMinpower.lastminutepowertime));
ipmi_time_to_str(lasthourpeakpower, timestr); printf("Last Hour : %s",
printf("Last Hour : %s", timestr); ipmi_timestamp_numeric(stMinpower.lasthourpowertime));
ipmi_time_to_str(lastdaypeakpower, timestr); printf("Last Day : %s",
printf("Last Day : %s", timestr); ipmi_timestamp_numeric(stMinpower.lastdaypowertime));
ipmi_time_to_str(lastweekpeakpower, timestr); printf("Last Week : %s",
printf("Last Week : %s", timestr); ipmi_timestamp_numeric(stMinpower.lastweekpowertime));
return rc; return rc;
} }
/* /*

View File

@ -38,6 +38,7 @@
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_fru.h> #include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_time.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -2415,13 +2416,12 @@ ipmi_ek_display_fru_header_detail(char *filename)
FILE *input_file; FILE *input_file;
size_t file_offset = 0; size_t file_offset = 0;
struct fru_header header; struct fru_header header;
time_t tval; time_t ts;
int ret = 0; int ret = 0;
unsigned char data = 0; unsigned char data = 0;
unsigned char lan_code = 0; unsigned char lan_code = 0;
unsigned char mfg_date[SIZE_MFG_DATE]; unsigned char mfg_date[SIZE_MFG_DATE];
unsigned int board_length = 0; unsigned int board_length = 0;
struct tm *strtm;
input_file = fopen(filename, "r"); input_file = fopen(filename, "r");
if (!input_file) { if (!input_file) {
@ -2544,36 +2544,36 @@ ipmi_ek_display_fru_header_detail(char *filename)
fclose(input_file); fclose(input_file);
return (-1); return (-1);
} }
tval = ((mfg_date[2] << 16) + (mfg_date[1] << 8)
+ (mfg_date[0])); ts = ipmi_fru2time_t(mfg_date);
tval = tval * 60; printf("Board Mfg Date: %ld, %s\n", ts, ipmi_timestamp_numeric(ts));
tval = tval + secs_from_1970_1996;
if(time_in_utc)
strtm = gmtime(&tval);
else
strtm = localtime(&tval);
printf("Board Mfg Date: %ld, %s", tval, asctime(strtm));
board_length -= SIZE_MFG_DATE; board_length -= SIZE_MFG_DATE;
/* Board Mfg */ /* Board Mfg */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "Board Manufacture Data", &board_length); input_file, "Board Manufacture Data", &board_length);
ret = fseek(input_file, file_offset, SEEK_SET); ret = fseek(input_file, file_offset, SEEK_SET);
/* Board Product */ /* Board Product */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "Board Product Name", &board_length); input_file, "Board Product Name", &board_length);
ret = fseek(input_file, file_offset, SEEK_SET); ret = fseek(input_file, file_offset, SEEK_SET);
/* Board Serial */ /* Board Serial */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "Board Serial Number", &board_length); input_file, "Board Serial Number", &board_length);
ret = fseek(input_file, file_offset, SEEK_SET); ret = fseek(input_file, file_offset, SEEK_SET);
/* Board Part */ /* Board Part */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "Board Part Number", &board_length); input_file, "Board Part Number", &board_length);
ret = fseek(input_file, file_offset, SEEK_SET); ret = fseek(input_file, file_offset, SEEK_SET);
/* FRU file ID */ /* FRU file ID */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "FRU File ID", &board_length); input_file, "FRU File ID", &board_length);
ret = fseek(input_file, file_offset, SEEK_SET); ret = fseek(input_file, file_offset, SEEK_SET);
/* Additional Custom Mfg. */ /* Additional Custom Mfg. */
file_offset = ipmi_ek_display_board_info_area( file_offset = ipmi_ek_display_board_info_area(
input_file, "Custom", &board_length); input_file, "Custom", &board_length);

View File

@ -38,6 +38,7 @@
#include <ipmitool/ipmi_mc.h> #include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_sdr.h> #include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_strings.h> /* IANA id strings */ #include <ipmitool/ipmi_strings.h> /* IANA id strings */
#include <ipmitool/ipmi_time.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -997,9 +998,8 @@ fru_area_print_board(struct ipmi_intf * intf, struct fru_info * fru,
uint8_t * fru_data; uint8_t * fru_data;
uint32_t fru_len; uint32_t fru_len;
uint32_t i; uint32_t i;
time_t tval; time_t ts;
uint8_t tmp[2]; uint8_t tmp[2];
struct tm *strtm;
fru_len = 0; fru_len = 0;
@ -1034,14 +1034,8 @@ fru_area_print_board(struct ipmi_intf * intf, struct fru_info * fru,
*/ */
i = 3; i = 3;
tval=((fru_data[i+2] << 16) + (fru_data[i+1] << 8) + (fru_data[i])); ts = ipmi_fru2time_t(&fru_data[i]);
tval=tval * 60; printf(" Board Mfg Date : %s\n", ipmi_timestamp_string(ts));
tval=tval + secs_from_1970_1996;
if(time_in_utc)
strtm = gmtime(&tval);
else
strtm = localtime(&tval);
printf(" Board Mfg Date : %s", asctime(strtm));
i += 3; /* skip mfg. date time */ i += 3; /* skip mfg. date time */
fru_area = get_fru_area_str(fru_data, &i); fru_area = get_fru_area_str(fru_data, &i);

View File

@ -47,6 +47,7 @@
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_mc.h> #include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_time.h>
extern int verbose; extern int verbose;
@ -731,8 +732,6 @@ ipmi_mc_print_guid(struct ipmi_intf *intf, ipmi_guid_mode_t guid_mode)
[GUID_DUMP] = "Unknown (data dumped)" [GUID_DUMP] = "Unknown (data dumped)"
}; };
char tbuf[40] = { 0 };
struct tm *tm;
int rc; int rc;
rc = _ipmi_mc_get_guid(intf, (ipmi_guid_t *)guid_data); rc = _ipmi_mc_get_guid(intf, (ipmi_guid_t *)guid_data);
@ -776,12 +775,7 @@ ipmi_mc_print_guid(struct ipmi_intf *intf, ipmi_guid_mode_t guid_mode)
printf(" (%d)\n", GUID_VERSION((int)guid.time_hi_and_version)); printf(" (%d)\n", GUID_VERSION((int)guid.time_hi_and_version));
break; break;
case GUID_VERSION_TIME: case GUID_VERSION_TIME:
if(time_in_utc) printf("\nTimestamp : %s\n", ipmi_timestamp_numeric(guid.time));
tm = gmtime(&guid.time);
else
tm = localtime(&guid.time);
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", tm);
printf("\nTimestamp : %s\n", tbuf);
break; break;
default: default:
printf("\n"); printf("\n");

View File

@ -42,6 +42,7 @@
#include <ipmitool/ipmi_mc.h> #include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_pef.h> #include <ipmitool/ipmi_pef.h>
#include <ipmitool/ipmi_sel.h> #include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_time.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
extern int verbose; extern int verbose;
@ -1193,8 +1194,6 @@ ipmi_pef2_get_status(struct ipmi_intf *intf)
struct ipmi_rs *rsp; struct ipmi_rs *rsp;
struct ipmi_rq req; struct ipmi_rq req;
struct pef_cfgparm_selector psel; struct pef_cfgparm_selector psel;
char tbuf[40];
uint32_t timei;
time_t ts; time_t ts;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
@ -1206,15 +1205,9 @@ ipmi_pef2_get_status(struct ipmi_intf *intf)
"Last S/W processed ID"); "Last S/W processed ID");
return (-1); return (-1);
} }
memcpy(&timei, rsp->data, sizeof(timei));
#if WORDS_BIGENDIAN
timei = BSWAP_32(timei);
#endif
ts = (time_t)timei;
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&ts)); ts = ipmi32toh(rsp->data);
ipmi_pef_print_str("Last SEL addition", ipmi_timestamp_numeric(ts));
ipmi_pef_print_str("Last SEL addition", tbuf);
ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]); ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]);
ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]); ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]);
ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]); ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]);

View File

@ -52,6 +52,7 @@
#include <ipmitool/ipmi_entity.h> #include <ipmitool/ipmi_entity.h>
#include <ipmitool/ipmi_constants.h> #include <ipmitool/ipmi_constants.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_time.h>
#if HAVE_CONFIG_H #if HAVE_CONFIG_H
# include <config.h> # include <config.h>
@ -4209,24 +4210,6 @@ ipmi_sdr_get_info(struct ipmi_intf *intf,
return 0; return 0;
} }
/* ipmi_sdr_timestamp - return string from timestamp value
*
* @stamp: 32bit timestamp
*
* returns pointer to static buffer
*/
static char *
ipmi_sdr_timestamp(time_t stamp)
{
static char tbuf[40];
time_t s = (time_t) stamp;
memset(tbuf, 0, 40);
if (stamp)
strftime(tbuf, sizeof (tbuf), "%m/%d/%Y %H:%M:%S",
gmtime(&s));
return tbuf;
}
/* /*
* ipmi_sdr_print_info * ipmi_sdr_print_info
* *
@ -4278,7 +4261,7 @@ ipmi_sdr_print_info(struct ipmi_intf *intf)
{ {
timestamp = ipmi32toh(sdr_repository_info timestamp = ipmi32toh(sdr_repository_info
.most_recent_addition_timestamp); .most_recent_addition_timestamp);
printf("%s\n", ipmi_sdr_timestamp(timestamp)); printf("%s\n", ipmi_timestamp_numeric(timestamp));
} }
else { else {
printf("NA\n"); printf("NA\n");
@ -4288,7 +4271,7 @@ ipmi_sdr_print_info(struct ipmi_intf *intf)
if(sdr_repository_info.delete_sdr_supported) { if(sdr_repository_info.delete_sdr_supported) {
timestamp = ipmi32toh(sdr_repository_info timestamp = ipmi32toh(sdr_repository_info
.most_recent_erase_timestamp); .most_recent_erase_timestamp);
printf("%s\n", ipmi_sdr_timestamp(timestamp)); printf("%s\n", ipmi_timestamp_numeric(timestamp));
} }
else { else {
printf("NA\n"); printf("NA\n");

View File

@ -37,6 +37,7 @@
#include <time.h> #include <time.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdbool.h>
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
@ -50,6 +51,7 @@
#include <ipmitool/ipmi_sensor.h> #include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_quantaoem.h> #include <ipmitool/ipmi_quantaoem.h>
#include <ipmitool/ipmi_time.h>
static int sel_extended = 0; static int sel_extended = 0;
static int sel_oem_nrecs = 0; static int sel_oem_nrecs = 0;
@ -236,34 +238,6 @@ ipmi_get_event_type(uint8_t code)
return "Reserved"; return "Reserved";
} }
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 * static char *
hex2ascii (uint8_t * hexChars, uint8_t numBytes) hex2ascii (uint8_t * hexChars, uint8_t numBytes)
{ {
@ -1592,14 +1566,14 @@ ipmi_sel_get_info(struct ipmi_intf * intf)
printf("Last Add Time : Not Available\n"); printf("Last Add Time : Not Available\n");
else else
printf("Last Add Time : %s\n", 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)) || if ((!memcmp(rsp->data + 9, &fs, 4)) ||
(!memcmp(rsp->data + 9, &zeros, 4))) (!memcmp(rsp->data + 9, &zeros, 4)))
printf("Last Del Time : Not Available\n"); printf("Last Del Time : Not Available\n");
else else
printf("Last Del Time : %s\n", printf("Last Del Time : %s\n",
ipmi_sel_timestamp(buf2long(rsp->data + 9))); ipmi_timestamp_numeric(buf2long(rsp->data + 9)));
printf("Overflow : %s\n", printf("Overflow : %s\n",
@ -1837,18 +1811,19 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
} }
else { else {
if (evt->record_type < 0xc0) 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 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) if (csv_output)
printf(","); printf(",");
else else
printf(" | "); printf(" | ");
if (evt->record_type < 0xc0) 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 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) if (csv_output)
printf(","); printf(",");
@ -2055,11 +2030,11 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
{ {
printf(" Timestamp : "); printf(" Timestamp : ");
if (evt->record_type < 0xc0) if (evt->record_type < 0xc0)
printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp), printf("%s %s", ipmi_timestamp_date(evt->sel_type.standard_type.timestamp),
ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp)); ipmi_timestamp_time(evt->sel_type.standard_type.timestamp));
else else
printf("%s %s", ipmi_sel_timestamp_date(evt->sel_type.oem_ts_type.timestamp), printf("%s %s", ipmi_timestamp_date(evt->sel_type.oem_ts_type.timestamp),
ipmi_sel_timestamp_time(evt->sel_type.oem_ts_type.timestamp)); ipmi_timestamp_time(evt->sel_type.oem_ts_type.timestamp));
printf("\n"); printf("\n");
} }
@ -2145,8 +2120,8 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_
if (evt->record_type < 0xe0) if (evt->record_type < 0xe0)
{ {
printf(" Timestamp : "); printf(" Timestamp : ");
printf("%s %s\n", ipmi_sel_timestamp_date(evt->sel_type.standard_type.timestamp), printf("%s %s\n", ipmi_timestamp_date(evt->sel_type.standard_type.timestamp),
ipmi_sel_timestamp_time(evt->sel_type.standard_type.timestamp)); ipmi_timestamp_time(evt->sel_type.standard_type.timestamp));
} }
@ -2725,8 +2700,6 @@ ipmi_sel_get_time(struct ipmi_intf * intf)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
static char tbuf[40];
uint32_t timei;
time_t time; time_t time;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
@ -2749,15 +2722,8 @@ ipmi_sel_get_time(struct ipmi_intf * intf)
return -1; return -1;
} }
memcpy(&timei, rsp->data, 4); time = ipmi32toh(rsp->data);
#if WORDS_BIGENDIAN printf("%s\n", ipmi_timestamp_numeric(time));
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);
return 0; return 0;
} }
@ -2773,12 +2739,11 @@ ipmi_sel_get_time(struct ipmi_intf * intf)
static int static int
ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string) ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
{ {
struct ipmi_rs * rsp; struct ipmi_rs *rsp;
struct ipmi_rq req; struct ipmi_rq req;
struct tm tm = {0}; struct tm tm = {0};
time_t t; time_t t;
uint32_t timei; const char *time_format = "%x %X"; /* Use locale-defined format */
const char * time_format = "%m/%d/%Y %H:%M:%S";
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_STORAGE; req.msg.netfn = IPMI_NETFN_STORAGE;
@ -2787,57 +2752,43 @@ ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
/* See if user requested set to current client system time */ /* See if user requested set to current client system time */
if (strncasecmp(time_string, "now", 3) == 0) { if (strncasecmp(time_string, "now", 3) == 0) {
t = time(NULL); t = time(NULL);
/*
* Now we have local time in t, but BMC requires UTC
*/
t = ipmi_localtime2utc(t);
} }
else { else {
/* Now how do we get our time_t from our ascii version? */ bool error = true; /* Assume the string is invalid */
if (strptime(time_string, time_format, &tm) == 0) { /* Now let's extract time_t from the supplied string */
if (!strptime(time_string, time_format, &tm)) {
tm.tm_isdst = (-1); /* look up DST information */
t = mktime(&tm);
if (t >= 0) {
/* Surprisingly, the user hasn't mistaken ;) */
error = false;
}
}
if (error) {
lprintf(LOG_ERR, "Specified time could not be parsed"); lprintf(LOG_ERR, "Specified time could not be parsed");
return -1; return -1;
} }
tm.tm_isdst = (-1); /* look up DST information */
t = mktime(&tm); /*
if (t < 0) { * If `-c` wasn't specified then t we've just got is in local timesone
lprintf(LOG_ERR, "Specified time could not be parsed"); */
return -1; 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 * At this point `t` is UTC. Convert it to LE and send.
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));
if(time_in_utc)
tm_tmp=gmtime(&t);
else
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; htoipmi32(t, req.msg.data);
}
timei = (uint32_t)t;
req.msg.data = (uint8_t *)&timei;
req.msg.data_len = 4; req.msg.data_len = 4;
#if WORDS_BIGENDIAN
timei = BSWAP_32(timei);
#endif
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (!rsp || rsp->ccode) {
lprintf(LOG_ERR, "Set SEL Time command failed: %s", lprintf(LOG_ERR, "Set SEL Time command failed: %s",

217
lib/ipmi_time.c Normal file
View File

@ -0,0 +1,217 @@
/*
* Copyright (c) 2018 Alexander Amelkin. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holder, nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* THE COPYRIGHT HOLDER AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* THE COPYRIGHT HOLDER OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
* PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE
* THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS
* SOFTWARE, EVEN IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
*/
#include <time.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h> /* snprintf */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <ipmitool/ipmi_time.h>
bool time_in_utc; /* Set by '-Z' command line option */
time_t
ipmi_localtime2utc(time_t local)
{
struct tm tm;
gmtime_r(&local, &tm);
tm.tm_isdst = (-1);
return mktime(&tm);
}
/**
* @brief Convert a timestamp to a formatted string,
* considering the '-Z' option. Acts as if tzset() was called.
*
* @param[out] s The output string buffer
* @param[in] max The size of the output string buffer including the
* terminating null byte
* @param[in] format The format string, as in strftime(), ignored for
* special timestamp values as per section 37.1 of
* IPMI v2.0 specification rev 1.1.
* @param[in] stamp The time stamp to convert
*
* @returns the number of bytes written to s or 0, see strftime()
*/
size_t
ipmi_strftime(char *s, int max, const char *format, time_t stamp)
{
struct tm tm;
if (IPMI_TIME_UNSPECIFIED == stamp) {
return snprintf(s, max, "Unknown");
}
else if (stamp <= IPMI_TIME_INIT_DONE) {
/* Timestamp is relative to BMC start, no GMT offset */
gmtime_r(&stamp, &tm);
return strftime(s, max, format, &tm);
}
if (time_in_utc || ipmi_timestamp_is_special(stamp)) {
/*
* The user wants the time reported in UTC or the stamp represents the
* number of seconds since system power on. In any case, don't apply
* the timezone offset.
*/
gmtime_r(&stamp, &tm);
daylight = -1;
} else {
/*
* The user wants the time reported in local time zone.
*/
localtime_r(&stamp, &tm);
}
return strftime(s, max, format, &tm);
}
/**
* @brief Convert a timestamp to string, considering the '-Z' option.
* Similar to asctime_r(), but takes time_t instead of struct tm,
* and the string is in form "Wed Jun 30 21:49:08 1993 TZD" without
* the new line at the end.
*
* @param[in] stamp The timestamp to convert
* @param[out] outbuf The buffer to write the string to.
* @param[in] len The maximum length of the output buffer.
* Recommended size is IPMI_ASCTIME_SZ.
*
* @returns outbuf
*/
char *
ipmi_asctime_r(const time_t stamp, ipmi_datebuf_t outbuf)
{
const char *format = "%c %Z";
if (ipmi_timestamp_is_special(stamp)) {
if (stamp < SECONDS_A_DAY) {
format = "S+%H:%M:%S";
}
/*
* IPMI_TIME_INIT_DONE is over 17 years. This should never
* happen normally, but we'll support this anyway.
*/
else {
format = "S+%yy %jd %H:%M:%S";
}
}
ipmi_strftime(outbuf, IPMI_ASCTIME_SZ, format, stamp);
return outbuf;
}
char *
ipmi_timestamp_fmt(uint32_t stamp, const char *fmt)
{
/*
* It's assumed that supplied 'fmt' is never longer
* than IPMI_ASCTIME_SZ
*/
static ipmi_datebuf_t datebuf;
ipmi_strftime(datebuf, sizeof(datebuf), fmt, stamp);
return datebuf;
}
char *
ipmi_timestamp_string(uint32_t stamp)
{
const char *format = "%c %Z";
if (!ipmi_timestamp_is_valid(stamp)) {
return "Unspecified";
}
if (ipmi_timestamp_is_special(stamp)) {
if (stamp < SECONDS_A_DAY) {
format = "S+ %H:%M:%S";
}
/*
* IPMI_TIME_INIT_DONE is over 17 years. This should never
* happen normally, but we'll support this anyway.
*/
else {
format = "S+ %y years %j days %H:%M:%S";
}
}
return ipmi_timestamp_fmt(stamp, format);
}
char *
ipmi_timestamp_numeric(uint32_t stamp)
{
const char *format = "%x %X %Z";
if (!ipmi_timestamp_is_valid(stamp)) {
return "Unspecified";
}
if (ipmi_timestamp_is_special(stamp)) {
if (stamp < SECONDS_A_DAY) {
format = "S+ %H:%M:%S";
}
/*
* IPMI_TIME_INIT_DONE is over 17 years. This should never
* happen normally, but we'll support this anyway.
*/
else {
format = "S+ %y/%j %H:%M:%S";
}
}
return ipmi_timestamp_fmt(stamp, format);
}
char *
ipmi_timestamp_date(uint32_t stamp)
{
const char *format = "%x";
if (!ipmi_timestamp_is_valid(stamp)) {
return "Unspecified";
}
if (ipmi_timestamp_is_special(stamp)) {
format = "S+ %y/%j";
}
return ipmi_timestamp_fmt(stamp, format);
}
char *
ipmi_timestamp_time(uint32_t stamp)
{
if (!ipmi_timestamp_is_valid(stamp)) {
return "Unspecified";
}
/* Format is the same for both normal and special timestamps */
return ipmi_timestamp_fmt(stamp, "%X %Z");
}

View File

@ -88,7 +88,6 @@ char pidfile[64];
/* global variables */ /* global variables */
int verbose = 0; int verbose = 0;
int csv_output = 0; int csv_output = 0;
int time_in_utc = 0;
uint16_t selwatch_count = 0; /* number of entries in the SEL */ uint16_t selwatch_count = 0; /* number of entries in the SEL */
uint16_t selwatch_lastid = 0; /* current last entry in the SEL */ uint16_t selwatch_lastid = 0; /* current last entry in the SEL */
int selwatch_pctused = 0; /* current percent usage in the SEL */ int selwatch_pctused = 0; /* current percent usage in the SEL */

View File

@ -80,9 +80,7 @@ extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv); extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
extern int ipmi_lan6_main(struct ipmi_intf *intf, int argc, char **argv); extern int ipmi_lan6_main(struct ipmi_intf *intf, int argc, char **argv);
int csv_output = 0; int csv_output = 0;
int time_in_utc = 0;
int verbose = 0; int verbose = 0;
struct ipmi_cmd ipmitool_cmd_list[] = { struct ipmi_cmd ipmitool_cmd_list[] = {