summaryrefslogtreecommitdiff
path: root/src/timedate/timedated.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/timedate/timedated.c')
-rw-r--r--src/timedate/timedated.c113
1 files changed, 57 insertions, 56 deletions
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index fdb4335464..cdb6e5b16c 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -35,6 +35,8 @@
#include "hwclock.h"
#include "conf-files.h"
#include "path-util.h"
+#include "fileio-label.h"
+#include "label.h"
#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
@@ -43,6 +45,7 @@
" <interface name=\"org.freedesktop.timedate1\">\n" \
" <property name=\"Timezone\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"LocalRTC\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"CanNTP\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"NTP\" type=\"b\" access=\"read\"/>\n" \
" <method name=\"SetTime\">\n" \
" <arg name=\"usec_utc\" type=\"x\" direction=\"in\"/>\n" \
@@ -82,10 +85,14 @@ const char timedate_interface[] _introspect_("timedate1") = INTERFACE;
typedef struct TZ {
char *zone;
bool local_rtc;
+ int can_ntp;
int use_ntp;
} TZ;
static TZ tz = {
+ .zone = NULL,
+ .local_rtc = false,
+ .can_ntp = -1,
.use_ntp = -1,
};
@@ -176,14 +183,6 @@ static int read_data(void) {
}
}
-#ifdef HAVE_DEBIAN
- r = read_one_line_file("/etc/timezone", &tz.zone);
- if (r < 0) {
- if (r != -ENOENT)
- log_warning("Failed to read /etc/timezone: %s", strerror(-r));
- }
-#endif
-
have_timezone:
if (isempty(tz.zone)) {
free(tz.zone);
@@ -219,7 +218,7 @@ static int write_data_timezone(void) {
static int write_data_local_rtc(void) {
int r;
- char *s, *w;
+ _cleanup_free_ char *s = NULL, *w = NULL;
r = read_full_file("/etc/adjtime", &s, NULL);
if (r < 0) {
@@ -237,58 +236,45 @@ static int write_data_local_rtc(void) {
size_t a, b;
p = strchr(s, '\n');
- if (!p) {
- free(s);
+ if (!p)
return -EIO;
- }
p = strchr(p+1, '\n');
- if (!p) {
- free(s);
+ if (!p)
return -EIO;
- }
p++;
e = strchr(p, '\n');
- if (!e) {
- free(s);
+ if (!e)
return -EIO;
- }
a = p - s;
b = strlen(e);
w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1);
- if (!w) {
- free(s);
+ if (!w)
return -ENOMEM;
- }
*(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
if (streq(w, NULL_ADJTIME_UTC)) {
- free(w);
-
- if (unlink("/etc/adjtime") < 0) {
+ if (unlink("/etc/adjtime") < 0)
if (errno != ENOENT)
return -errno;
- }
return 0;
}
}
-
- r = write_one_line_file_atomic("/etc/adjtime", w);
- free(w);
-
- return r;
+ label_init("/etc");
+ return write_string_file_atomic_label("/etc/adjtime", w);
}
static char** get_ntp_services(void) {
- char **r = NULL, **files, **i;
+ _cleanup_strv_free_ char **r = NULL, **files;
+ char **i;
int k;
- k = conf_files_list(&files, ".list",
+ k = conf_files_list(&files, ".list", NULL,
"/etc/systemd/ntp-units.d",
"/run/systemd/ntp-units.d",
"/usr/local/lib/systemd/ntp-units.d",
@@ -298,14 +284,14 @@ static char** get_ntp_services(void) {
return NULL;
STRV_FOREACH(i, files) {
- FILE *f;
+ _cleanup_fclose_ FILE *f;
f = fopen(*i, "re");
if (!f)
continue;
for (;;) {
- char line[PATH_MAX], *l, **q;
+ char line[PATH_MAX], *l;
if (!fgets(line, sizeof(line), f)) {
@@ -319,22 +305,17 @@ static char** get_ntp_services(void) {
if (l[0] == 0 || l[0] == '#')
continue;
- q = strv_append(r, l);
- if (!q) {
+ if (strv_extend(&r, l) < 0) {
log_oom();
- break;
+ return NULL;
}
-
- strv_free(r);
- r = q;
}
-
- fclose(f);
}
- strv_free(files);
+ i = r;
+ r = NULL; /* avoid cleanup */
- return strv_uniq(r);
+ return strv_uniq(i);
}
static int read_ntp(DBusConnection *bus) {
@@ -370,8 +351,6 @@ static int read_ntp(DBusConnection *bus) {
goto finish;
}
- if (reply)
- dbus_message_unref(reply);
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
if (!reply) {
if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
@@ -393,6 +372,7 @@ static int read_ntp(DBusConnection *bus) {
goto finish;
}
+ tz.can_ntp = 1;
tz.use_ntp =
streq(s, "enabled") ||
streq(s, "enabled-runtime");
@@ -401,6 +381,7 @@ static int read_ntp(DBusConnection *bus) {
}
/* NTP is not installed. */
+ tz.can_ntp = 0;
tz.use_ntp = 0;
r = 0;
@@ -451,8 +432,6 @@ static int start_ntp(DBusConnection *bus, DBusError *error) {
goto finish;
}
- if (reply)
- dbus_message_unref(reply);
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
if (!reply) {
if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
@@ -541,8 +520,6 @@ static int enable_ntp(DBusConnection *bus, DBusError *error) {
}
}
- if (reply)
- dbus_message_unref(reply);
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
if (!reply) {
if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
@@ -594,6 +571,20 @@ finish:
return r;
}
+static int property_append_can_ntp(DBusMessageIter *i, const char *property, void *data) {
+ dbus_bool_t db;
+
+ assert(i);
+ assert(property);
+
+ db = tz.can_ntp > 0;
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
+ return -ENOMEM;
+
+ return 0;
+}
+
static int property_append_ntp(DBusMessageIter *i, const char *property, void *data) {
dbus_bool_t db;
@@ -611,6 +602,7 @@ static int property_append_ntp(DBusMessageIter *i, const char *property, void *d
static const BusProperty bus_timedate_properties[] = {
{ "Timezone", bus_property_append_string, "s", offsetof(TZ, zone), true },
{ "LocalRTC", bus_property_append_bool, "b", offsetof(TZ, local_rtc) },
+ { "CanNTP", property_append_can_ntp, "b", offsetof(TZ, can_ntp) },
{ "NTP", property_append_ntp, "b", offsetof(TZ, use_ntp) },
{ NULL, }
};
@@ -802,15 +794,24 @@ static DBusHandlerResult timedate_message_handler(
struct timespec ts;
struct tm* tm;
+ if (relative) {
+ usec_t n, x;
+
+ n = now(CLOCK_REALTIME);
+ x = n + utc;
+
+ if ((utc > 0 && x < n) ||
+ (utc < 0 && x > n))
+ return bus_send_error_reply(connection, message, NULL, -EOVERFLOW);
+
+ timespec_store(&ts, x);
+ } else
+ timespec_store(&ts, (usec_t) utc);
+
r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
- if (relative)
- timespec_store(&ts, now(CLOCK_REALTIME) + utc);
- else
- timespec_store(&ts, utc);
-
/* Set system clock */
if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
log_error("Failed to set local time: %m");
@@ -875,7 +876,7 @@ static DBusHandlerResult timedate_message_handler(
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
- if (!dbus_connection_send(connection, reply, NULL))
+ if (!bus_maybe_send_reply(connection, message, reply))
goto oom;
dbus_message_unref(reply);