/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-***/
#include <errno.h>
#include <string.h>
}
static int context_add_ntp_service(Context *c, const char *s) {
- _cleanup_free_ char *name = NULL;
UnitStatusInfo *u;
if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
LIST_FOREACH(units, u, c->units) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *path = NULL;
unit_status_info_clear(u);
return 0;
}
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_time, "t", now(CLOCK_REALTIME));
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_ntp_sync, "b", ntp_synced());
+
static int property_get_rtc_time(
sd_bus *bus,
const char *path,
return sd_bus_message_append(reply, "t", t);
}
-static int property_get_time(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- return sd_bus_message_append(reply, "t", now(CLOCK_REALTIME));
-}
-
-static int property_get_ntp_sync(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- return sd_bus_message_append(reply, "b", ntp_synced());
-}
-
static int property_get_can_ntp(
sd_bus *bus,
const char *path,
static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
+ int interactive, r;
const char *z;
- int interactive;
- char *t;
- int r;
assert(m);
assert(c);
if (r < 0)
return r;
- if (!timezone_is_valid(z))
+ if (!timezone_is_valid(z, LOG_DEBUG))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
if (streq_ptr(z, c->zone))
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- t = strdup(z);
- if (!t)
- return -ENOMEM;
-
- free(c->zone);
- c->zone = t;
+ r = free_and_strdup(&c->zone, z);
+ if (r < 0)
+ return r;
/* 1. Write new configuration file */
r = context_write_data_timezone(c);
return sd_bus_error_set_errnof(error, r, "Failed to set time zone: %m");
}
- /* 2. Tell the kernel our timezone */
- clock_set_timezone(NULL);
+ /* 2. Make glibc notice the new timezone */
+ tzset();
+
+ /* 3. Tell the kernel our timezone */
+ r = clock_set_timezone(NULL);
+ if (r < 0)
+ log_debug_errno(r, "Failed to tell kernel about timezone, ignoring: %m");
if (c->local_rtc) {
struct timespec ts;
struct tm *tm;
- /* 3. Sync RTC from system clock, with the new delta */
+ /* 4. Sync RTC from system clock, with the new delta */
assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
assert_se(tm = localtime(&ts.tv_sec));
- clock_set_hwclock(tm);
+
+ r = clock_set_hwclock(tm);
+ if (r < 0)
+ log_debug_errno(r, "Failed to sync time to hardware clock, ignoring: %m");
}
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_TIMEZONE_CHANGE_STR,
"TIMEZONE=%s", c->zone,
- LOG_MESSAGE("Changed time zone to '%s'.", c->zone),
- NULL);
+ "TIMEZONE_SHORTNAME=%s", tzname[daylight],
+ "DAYLIGHT=%i", daylight,
+ LOG_MESSAGE("Changed time zone to '%s' (%s).", c->zone, tzname[daylight]));
(void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "Timezone", NULL);
}
/* 2. Tell the kernel our timezone */
- clock_set_timezone(NULL);
+ r = clock_set_timezone(NULL);
+ if (r < 0)
+ log_debug_errno(r, "Failed to tell kernel about timezone, ignoring: %m");
/* 3. Synchronize clocks */
assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
if (fix_system) {
struct tm tm;
- /* Sync system clock from RTC; first,
- * initialize the timezone fields of
- * struct tm. */
+ /* Sync system clock from RTC; first, initialize the timezone fields of struct tm. */
if (c->local_rtc)
tm = *localtime(&ts.tv_sec);
else
tm = *gmtime(&ts.tv_sec);
- /* Override the main fields of
- * struct tm, but not the timezone
- * fields */
- if (clock_get_hwclock(&tm) >= 0) {
-
- /* And set the system clock
- * with this */
+ /* Override the main fields of struct tm, but not the timezone fields */
+ r = clock_get_hwclock(&tm);
+ if (r < 0)
+ log_debug_errno(r, "Failed to get hardware clock, ignoring: %m");
+ else {
+ /* And set the system clock with this */
if (c->local_rtc)
ts.tv_sec = mktime(&tm);
else
ts.tv_sec = timegm(&tm);
- clock_settime(CLOCK_REALTIME, &ts);
+ if (clock_settime(CLOCK_REALTIME, &ts) < 0)
+ log_debug_errno(errno, "Failed to update system clock, ignoring: %m");
}
} else {
else
tm = gmtime(&ts.tv_sec);
- clock_set_hwclock(tm);
+ r = clock_set_hwclock(tm);
+ if (r < 0)
+ log_debug_errno(r, "Failed to sync time to hardware clock, ignoring: %m");
}
log_info("RTC configured to %s time.", c->local_rtc ? "local" : "UTC");
tm = localtime(&ts.tv_sec);
else
tm = gmtime(&ts.tv_sec);
- clock_set_hwclock(tm);
+
+ r = clock_set_hwclock(tm);
+ if (r < 0)
+ log_debug_errno(r, "Failed to update hardware clock, ignoring: %m");
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
"REALTIME="USEC_FMT, timespec_load(&ts),
- LOG_MESSAGE("Changed local time to %s", ctime(&ts.tv_sec)),
- NULL);
+ LOG_MESSAGE("Changed local time to %s", ctime(&ts.tv_sec)));
return sd_bus_reply_method_return(m, NULL);
}