From cde2ba2c18cce3f403d8d01444b33ed2fcfc946c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Sep 2023 11:08:29 +0800 Subject: [PATCH] Uptime: detect boot time --- src/detection/uptime/uptime.h | 8 ++++++- src/detection/uptime/uptime_bsd.c | 30 ++++++++++++++++++--------- src/detection/uptime/uptime_linux.c | 20 ++++++++++++------ src/detection/uptime/uptime_windows.c | 13 ++++++++++-- src/detection/users/users_windows.c | 2 +- src/modules/uptime/uptime.c | 24 ++++++++++++++------- 6 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h index 447b13d5b..105e1bfa5 100644 --- a/src/detection/uptime/uptime.h +++ b/src/detection/uptime/uptime.h @@ -5,6 +5,12 @@ #include "fastfetch.h" -const char* ffDetectUptime(uint64_t* result); +typedef struct FFUptimeResult +{ + uint64_t bootTime; + uint64_t uptime; +} FFUptimeResult; + +const char* ffDetectUptime(FFUptimeResult* result); #endif diff --git a/src/detection/uptime/uptime_bsd.c b/src/detection/uptime/uptime_bsd.c index 4e3a707c6..0b1bf00c7 100644 --- a/src/detection/uptime/uptime_bsd.c +++ b/src/detection/uptime/uptime_bsd.c @@ -4,18 +4,28 @@ #include #include -const char* ffDetectUptime(uint64_t* result) +const char* ffDetectUptime(FFUptimeResult* result) { - struct timeval bootTime; - size_t bootTimeSize = sizeof(bootTime); - if(sysctl( - (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, - &bootTime, &bootTimeSize, - NULL, 0 - ) != 0) - return "sysctl({CTL_KERN, KERN_BOOTTIME}) failed"; + { + struct timeval bootTime; + size_t bootTimeSize = sizeof(bootTime); + if(sysctl( + (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, + &bootTime, &bootTimeSize, + NULL, 0 + ) != 0) + return "sysctl({CTL_KERN, KERN_BOOTTIME}) failed"; - *result = (uint64_t) difftime(time(NULL), bootTime.tv_sec); + result->bootTime = (uint64_t) bootTime.tv_sec * 1000 + (uint64_t) bootTime.tv_usec / 1000; + } + + { + struct timespec realTime; + if(clock_gettime(CLOCK_REALTIME, &realTime) != 0) + return "clock_gettime(CLOCK_REALTIME) failed"; + uint64_t now = (uint64_t) realTime.tv_sec * 1000 + (uint64_t) realTime.tv_nsec / 1000000; + result->uptime = now - result->bootTime; + } return NULL; } diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c index 0339bc7e6..039d550da 100644 --- a/src/detection/uptime/uptime_linux.c +++ b/src/detection/uptime/uptime_linux.c @@ -1,12 +1,20 @@ #include "uptime.h" -#include +#include -const char* ffDetectUptime(uint64_t* result) +const char* ffDetectUptime(FFUptimeResult* result) { - struct sysinfo info; - if(sysinfo(&info) != 0) - return "sysinfo() failed"; - *result = (uint64_t) info.uptime; + struct timespec uptime; + if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) + return "clock_gettime(CLOCK_BOOTTIME) failed"; + + result->uptime = (uint64_t) uptime.tv_sec * 1000 + (uint64_t) uptime.tv_nsec / 1000000; + + struct timespec realTime; + if(clock_gettime(CLOCK_REALTIME, &realTime) != 0) + return "clock_gettime(CLOCK_REALTIME) failed"; + + result->bootTime = (uint64_t) realTime.tv_sec * 1000 + (uint64_t) realTime.tv_nsec / 1000000 + result->uptime; + return NULL; } diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c index 55053ab24..10f7157bb 100644 --- a/src/detection/uptime/uptime_windows.c +++ b/src/detection/uptime/uptime_windows.c @@ -2,8 +2,17 @@ #include -const char* ffDetectUptime(uint64_t* result) +static inline uint64_t to_ms(uint64_t ret) { - *result = GetTickCount64() / 1000; + ret -= 116444736000000000ull; + return ret / 10000ull; +} + +const char* ffDetectUptime(FFUptimeResult* result) +{ + result->uptime = GetTickCount64(); + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + result->bootTime = to_ms(*(uint64_t*) &fileTime) - result->uptime; return NULL; } diff --git a/src/detection/users/users_windows.c b/src/detection/users/users_windows.c index 6ef912670..0c222ef91 100644 --- a/src/detection/users/users_windows.c +++ b/src/detection/users/users_windows.c @@ -4,7 +4,7 @@ #include #include -static uint64_t to_ms(uint64_t ret) +static inline uint64_t to_ms(uint64_t ret) { ret -= 116444736000000000ull; return ret / 10000ull; diff --git a/src/modules/uptime/uptime.c b/src/modules/uptime/uptime.c index 89c93fd17..74bce2798 100644 --- a/src/modules/uptime/uptime.c +++ b/src/modules/uptime/uptime.c @@ -8,9 +8,9 @@ void ffPrintUptime(FFUptimeOptions* options) { - uint64_t uptime; + FFUptimeResult result; - const char* error = ffDetectUptime(&uptime); + const char* error = ffDetectUptime(&result); if(error) { @@ -18,10 +18,17 @@ void ffPrintUptime(FFUptimeOptions* options) return; } - uint32_t days = (uint32_t) uptime / 86400; - uint32_t hours = (uint32_t) (uptime - (days * 86400)) / 3600; - uint32_t minutes = (uint32_t) (uptime - (days * 86400) - (hours * 3600)) / 60; - uint32_t seconds = (uint32_t) uptime - (days * 86400) - (hours * 3600) - (minutes * 60); + uint64_t uptime = result.uptime; + + uint32_t milliseconds = (uint32_t) (uptime % 1000); + uptime /= 1000; + uint32_t seconds = (uint32_t) (uptime % 60); + uptime /= 60; + uint32_t minutes = (uint32_t) (uptime % 60); + uptime /= 60; + uint32_t hours = (uint32_t) (uptime % 24); + uptime /= 24; + uint32_t days = (uint32_t) uptime; if(options->moduleArgs.outputFormat.length == 0) { @@ -74,7 +81,10 @@ void ffPrintUptime(FFUptimeOptions* options) {FF_FORMAT_ARG_TYPE_UINT, &days}, {FF_FORMAT_ARG_TYPE_UINT, &hours}, {FF_FORMAT_ARG_TYPE_UINT, &minutes}, - {FF_FORMAT_ARG_TYPE_UINT, &seconds} + {FF_FORMAT_ARG_TYPE_UINT, &seconds}, + {FF_FORMAT_ARG_TYPE_UINT, &milliseconds}, + {FF_FORMAT_ARG_TYPE_UINT64, &result.uptime}, + {FF_FORMAT_ARG_TYPE_UINT64, &result.bootTime}, }); } }