#include <stdlib.h>
#include <stdbool.h>
-#include <unistd.h>
#include <getopt.h>
#include <locale.h>
-#include <string.h>
-#include <sys/timex.h>
#include "sd-bus.h"
#include "bus-util.h"
#include "build.h"
#include "strv.h"
#include "pager.h"
-#include "time-dst.h"
static bool arg_no_pager = false;
static bool arg_ask_password = true;
bool ntp_synced;
} StatusInfo;
-static const char *jump_str(int delta_minutes, char *s, size_t size) {
- if (delta_minutes == 60)
- return "one hour forward";
- if (delta_minutes == -60)
- return "one hour backwards";
- if (delta_minutes < 0) {
- snprintf(s, size, "%i minutes backwards", -delta_minutes);
- return s;
- }
- if (delta_minutes > 0) {
- snprintf(s, size, "%i minutes forward", delta_minutes);
- return s;
- }
- return "";
-}
-
static void print_status_info(const StatusInfo *i) {
char a[FORMAT_TIMESTAMP_MAX];
- char b[FORMAT_TIMESTAMP_MAX];
- char s[32];
struct tm tm;
time_t sec;
bool have_time = false;
- _cleanup_free_ char *zc = NULL, *zn = NULL;
- time_t t, tc, tn;
- int dn = 0;
- bool is_dstc = false, is_dstn = false;
+ const char *old_tz = NULL, *tz;
int r;
assert(i);
- /* Enforce the values of /etc/localtime */
- if (getenv("TZ")) {
- fprintf(stderr, "Warning: Ignoring the TZ variable. Reading the system's time zone setting only.\n\n");
- unsetenv("TZ");
- }
+ /* Save the old $TZ */
+ tz = getenv("TZ");
+ if (tz)
+ old_tz = strdupa(tz);
+
+ /* Set the new $TZ */
+ if (setenv("TZ", i->timezone, true) < 0)
+ log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
+ else
+ tzset();
if (i->time != 0) {
sec = (time_t) (i->time / USEC_PER_SEC);
have_time = true;
- } else if (arg_transport == BUS_TRANSPORT_LOCAL) {
+ } else if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE)) {
sec = time(NULL);
have_time = true;
} else
- fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n");
+ log_warning("Could not get time from timedated and not operating locally, ignoring.");
if (have_time) {
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) > 0);
- char_array_0(a);
- printf(" Local time: %s\n", a);
-
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)) > 0);
- char_array_0(a);
- printf(" Universal time: %s\n", a);
+ xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
+ printf(" Local time: %.*s\n", (int) sizeof(a), a);
+
+ xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
+ printf(" Universal time: %.*s\n", (int) sizeof(a), a);
} else {
printf(" Local time: %s\n", "n/a");
printf(" Universal time: %s\n", "n/a");
if (i->rtc_time > 0) {
time_t rtc_sec;
- rtc_sec = (time_t)(i->rtc_time / USEC_PER_SEC);
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm)) > 0);
- char_array_0(a);
- printf(" RTC time: %s\n", a);
+ rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
+ xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
+ printf(" RTC time: %.*s\n", (int) sizeof(a), a);
} else
printf(" RTC time: %s\n", "n/a");
- if (have_time) {
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0);
- char_array_0(a);
- }
+ if (have_time)
+ xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
- printf(" Time zone: %s (%s)\n"
+ /* Restore the $TZ */
+ if (old_tz)
+ r = setenv("TZ", old_tz, true);
+ else
+ r = unsetenv("TZ");
+ if (r < 0)
+ log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
+ else
+ tzset();
+
+ printf(" Time zone: %s (%.*s)\n"
" NTP enabled: %s\n"
"NTP synchronized: %s\n"
" RTC in local TZ: %s\n",
- strna(i->timezone), have_time ? a : "n/a",
+ strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
yes_no(i->ntp_synced),
yes_no(i->rtc_local));
- if (have_time) {
- r = time_get_dst(sec, "/etc/localtime",
- &tc, &zc, &is_dstc,
- &tn, &dn, &zn, &is_dstn);
- if (r < 0)
- printf(" DST active: %s\n", "n/a");
- else {
- printf(" DST active: %s\n", yes_no(is_dstc));
-
- t = tc - 1;
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
- char_array_0(a);
-
- zero(tm);
- assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
- char_array_0(b);
- printf(" Last DST change: DST %s at\n"
- " %s\n"
- " %s\n",
- is_dstc ? "began" : "ended", a, b);
-
- t = tn - 1;
- zero(tm);
- assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
- char_array_0(a);
-
- zero(tm);
- assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
- char_array_0(b);
- printf(" Next DST change: DST %s (the clock jumps %s) at\n"
- " %s\n"
- " %s\n",
- is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b);
- }
- } else
- printf(" DST active: %s\n", yes_no(is_dstc));
-
if (i->rtc_local)
fputs("\n" ANSI_HIGHLIGHT_ON
"Warning: The system is configured to read the RTC time in the local time zone. This\n"
map,
&info);
if (r < 0) {
- log_error("Failed to query server: %s", strerror(-r));
+ log_error_errno(r, "Failed to query server: %m");
goto fail;
}
assert(n == 1);
r = get_timezones(&zones);
- if (r < 0) {
- log_error("Failed to read list of time zones: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to read list of time zones: %m");
pager_open_if_enabled();
strv_print(zones);
break;
case 'M':
- arg_transport = BUS_TRANSPORT_CONTAINER;
+ arg_transport = BUS_TRANSPORT_MACHINE;
arg_host = optarg;
break;
}
int main(int argc, char *argv[]) {
- _cleanup_bus_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_close_unref_ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
r = bus_open_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
- log_error("Failed to create bus connection: %s", strerror(-r));
+ log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
}