#include <errno.h>
#include <sys/stat.h>
+#include <sys/timex.h>
#include <sys/types.h>
#include <unistd.h>
#include "bus-log-control-api.h"
#include "bus-map-properties.h"
#include "bus-polkit.h"
+#include "bus-unit-util.h"
#include "clock-util.h"
#include "conf-files.h"
-#include "def.h"
+#include "constants.h"
#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
p->active_state = mfree(p->active_state);
}
-static void unit_status_info_free(UnitStatusInfo *p) {
- assert(p);
+static UnitStatusInfo *unit_status_info_free(UnitStatusInfo *p) {
+ if (!p)
+ return NULL;
unit_status_info_clear(p);
free(p->name);
free(p->path);
- free(p);
+ return mfree(p);
}
-static void context_clear(Context *c) {
- UnitStatusInfo *p;
+DEFINE_TRIVIAL_CLEANUP_FUNC(UnitStatusInfo*, unit_status_info_free);
+static void context_clear(Context *c) {
assert(c);
free(c->zone);
sd_bus_slot_unref(c->slot_job_removed);
- while ((p = c->units)) {
- LIST_REMOVE(units, c->units, p);
- unit_status_info_free(p);
- }
+ LIST_CLEAR(units, c->units, unit_status_info_free);
}
static int context_add_ntp_service(Context *c, const char *s, const char *source) {
- UnitStatusInfo *u;
+ _cleanup_(unit_status_info_freep) UnitStatusInfo *unit = NULL;
+
+ assert(c);
+ assert(s);
+ assert(source);
if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
return -EINVAL;
if (streq(u->name, s))
return 0;
- u = new0(UnitStatusInfo, 1);
- if (!u)
+ unit = new0(UnitStatusInfo, 1);
+ if (!unit)
return -ENOMEM;
- u->name = strdup(s);
- if (!u->name) {
- free(u);
+ unit->name = strdup(s);
+ if (!unit->name)
return -ENOMEM;
- }
- LIST_APPEND(units, c->units, u);
- log_unit_debug(u, "added from %s.", source);
+ LIST_APPEND(units, c->units, unit);
+ log_unit_debug(unit, "added from %s.", source);
+ TAKE_PTR(unit);
return 0;
}
static int context_parse_ntp_services_from_disk(Context *c) {
_cleanup_strv_free_ char **files = NULL;
- char **f;
int r;
r = conf_files_list_strv(&files, ".list", NULL, CONF_FILES_FILTER_MASKED, UNIT_LIST_DIRS);
for (;;) {
_cleanup_free_ char *line = NULL;
- const char *word;
- r = read_line(file, LINE_MAX, &line);
+ r = read_stripped_line(file, LINE_MAX, &line);
if (r < 0) {
log_error_errno(r, "Failed to read %s, ignoring: %m", *f);
continue;
if (r == 0)
break;
- word = strstrip(line);
- if (isempty(word) || startswith(word, "#"))
+ if (isempty(line) || startswith(line, "#"))
continue;
- r = context_add_ntp_service(c, word, *f);
+ r = context_add_ntp_service(c, line, *f);
if (r < 0)
- log_warning_errno(r, "Failed to add NTP service \"%s\", ignoring: %m", word);
+ log_warning_errno(r, "Failed to add NTP service \"%s\", ignoring: %m", line);
}
}
}
static int context_ntp_service_is_active(Context *c) {
- UnitStatusInfo *info;
int count = 0;
assert(c);
}
static int context_ntp_service_exists(Context *c) {
- UnitStatusInfo *info;
int count = 0;
assert(c);
}
}
- r = mac_selinux_init();
+ r = mac_init();
if (r < 0)
return r;
{ "UnitFileState", "s", NULL, offsetof(UnitStatusInfo, unit_file_state) },
{}
};
- UnitStatusInfo *u;
int r;
assert(c);
}
static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- Context *c = userdata;
- UnitStatusInfo *u;
+ Context *c = ASSERT_PTR(userdata);
const char *path;
unsigned n = 0;
int r;
- assert(c);
assert(m);
r = sd_bus_message_read(m, "uoss", NULL, &path, NULL, NULL);
if (r < 0)
return r;
- r = bus_call_method(bus, bus_systemd_mgr, "Reload", error, NULL, NULL);
+ r = bus_service_manager_reload(bus);
if (r < 0)
return r;
return 0;
}
+static bool ntp_synced(void) {
+ struct timex txc = {};
+
+ if (adjtimex(&txc) < 0)
+ return false;
+
+ /* Consider the system clock synchronized if the reported maximum error is smaller than the maximum
+ * value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from
+ * touching the RTC. */
+ return txc.maxerror < 16000000;
+}
+
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());
void *userdata,
sd_bus_error *error) {
- Context *c = userdata;
+ Context *c = ASSERT_PTR(userdata);
int r;
- assert(c);
assert(bus);
assert(property);
assert(reply);
void *userdata,
sd_bus_error *error) {
- Context *c = userdata;
+ Context *c = ASSERT_PTR(userdata);
int r;
- assert(c);
assert(bus);
assert(property);
assert(reply);
}
static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- Context *c = userdata;
+ Context *c = ASSERT_PTR(userdata);
int interactive, r;
const char *z;
assert(m);
- assert(c);
r = sd_bus_message_read(m, "sb", &z, &interactive);
if (r < 0)
if (streq_ptr(z, c->zone))
return sd_bus_reply_method_return(m, NULL);
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_TIME,
"org.freedesktop.timedate1.set-timezone",
- NULL,
+ /* details= */ NULL,
interactive,
- UID_INVALID,
+ /* good_user= */ UID_INVALID,
&c->polkit_registry,
error);
if (r < 0)
static int method_set_local_rtc(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int lrtc, fix_system, interactive;
- Context *c = userdata;
+ Context *c = ASSERT_PTR(userdata);
struct timespec ts;
int r;
assert(m);
- assert(c);
r = sd_bus_message_read(m, "bbb", &lrtc, &fix_system, &interactive);
if (r < 0)
if (lrtc == c->local_rtc && !fix_system)
return sd_bus_reply_method_return(m, NULL);
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_TIME,
"org.freedesktop.timedate1.set-local-rtc",
- NULL,
+ /* details= */ NULL,
interactive,
- UID_INVALID,
+ /* good_user= */ UID_INVALID,
&c->polkit_registry,
error);
if (r < 0)
sd_bus *bus = sd_bus_message_get_bus(m);
char buf[FORMAT_TIMESTAMP_MAX];
int relative, interactive, r;
- Context *c = userdata;
+ Context *c = ASSERT_PTR(userdata);
int64_t utc;
struct timespec ts;
usec_t start;
struct tm tm;
assert(m);
- assert(c);
if (c->slot_job_removed)
return sd_bus_error_set(error, BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, "Previous request is not finished, refusing.");
} else
timespec_store(&ts, (usec_t) utc);
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_TIME,
"org.freedesktop.timedate1.set-time",
- NULL,
+ /* details= */ NULL,
interactive,
- UID_INVALID,
+ /* good_user= */ UID_INVALID,
&c->polkit_registry,
error);
if (r < 0)
static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot = NULL;
sd_bus *bus = sd_bus_message_get_bus(m);
- Context *c = userdata;
- UnitStatusInfo *u;
+ Context *c = ASSERT_PTR(userdata);
const UnitStatusInfo *selected = NULL;
int enable, interactive, q, r;
assert(m);
assert(bus);
- assert(c);
r = sd_bus_message_read(m, "bb", &enable, &interactive);
if (r < 0)
if (context_ntp_service_exists(c) <= 0)
return sd_bus_error_set(error, BUS_ERROR_NO_NTP_SUPPORT, "NTP not supported");
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_TIME,
"org.freedesktop.timedate1.set-ntp",
- NULL,
+ /* details= */ NULL,
interactive,
- UID_INVALID,
+ /* good_user= */ UID_INVALID,
&c->polkit_registry,
error);
if (r < 0)
SD_BUS_PROPERTY("TimeUSec", "t", property_get_time, 0, 0),
SD_BUS_PROPERTY("RTCTimeUSec", "t", property_get_rtc_time, 0, 0),
- SD_BUS_METHOD_WITH_NAMES("SetTime",
- "xbb",
- SD_BUS_PARAM(usec_utc)
- SD_BUS_PARAM(relative)
- SD_BUS_PARAM(interactive),
- NULL,,
- method_set_time,
- SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD_WITH_NAMES("SetTimezone",
- "sb",
- SD_BUS_PARAM(timezone)
- SD_BUS_PARAM(interactive),
- NULL,,
- method_set_timezone,
- SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD_WITH_NAMES("SetLocalRTC",
- "bbb",
- SD_BUS_PARAM(local_rtc)
- SD_BUS_PARAM(fix_system)
- SD_BUS_PARAM(interactive),
- NULL,,
- method_set_local_rtc,
- SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD_WITH_NAMES("SetNTP",
- "bb",
- SD_BUS_PARAM(use_ntp)
- SD_BUS_PARAM(interactive),
- NULL,,
- method_set_ntp,
- SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD_WITH_NAMES("ListTimezones",
- NULL,,
- "as",
- SD_BUS_PARAM(timezones),
- method_list_timezones,
- SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("SetTime",
+ SD_BUS_ARGS("x", usec_utc, "b", relative, "b", interactive),
+ SD_BUS_NO_RESULT,
+ method_set_time,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("SetTimezone",
+ SD_BUS_ARGS("s", timezone, "b", interactive),
+ SD_BUS_NO_RESULT,
+ method_set_timezone,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("SetLocalRTC",
+ SD_BUS_ARGS("b", local_rtc, "b", fix_system, "b", interactive),
+ SD_BUS_NO_RESULT,
+ method_set_local_rtc,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("SetNTP",
+ SD_BUS_ARGS("b", use_ntp, "b", interactive),
+ SD_BUS_NO_RESULT,
+ method_set_ntp,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("ListTimezones",
+ SD_BUS_NO_ARGS,
+ SD_BUS_RESULT("as", timezones),
+ method_list_timezones,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};