chiark / gitweb /
util: rename write_one_line_file() to write_string_file()
[elogind.git] / src / timedate / timedated.c
index 784dadc631bde15e49c6b7aab9889d172a241e55..e068724903f57bd85758c77f919cdd3e95b1e079 100644 (file)
@@ -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,12 @@ 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 = {
+        .can_ntp = -1,
         .use_ntp = -1,
 };
 
@@ -176,14 +181,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);
@@ -199,19 +196,10 @@ static int write_data_timezone(void) {
         int r = 0;
         _cleanup_free_ char *p = NULL;
 
-#ifdef TARGET_DEBIAN
-        struct stat st;
-#endif
-
         if (!tz.zone) {
                 if (unlink("/etc/localtime") < 0 && errno != ENOENT)
                         r = -errno;
 
-#ifdef TARGET_DEBIAN
-                if (unlink("/etc/timezone") < 0 && errno != ENOENT)
-                        r = -errno;
-#endif
-
                 return r;
         }
 
@@ -223,14 +211,6 @@ static int write_data_timezone(void) {
         if (r < 0)
                 return r;
 
-#ifdef TARGET_DEBIAN
-        if (stat("/etc/timezone", &st) == 0 && S_ISREG(st.st_mode)) {
-                r = write_one_line_file_atomic("/etc/timezone", tz.zone);
-                if (r < 0)
-                        return r;
-        }
-#endif
-
         return 0;
 }
 
@@ -294,8 +274,8 @@ static int write_data_local_rtc(void) {
                         return 0;
                 }
         }
-
-        r = write_one_line_file_atomic("/etc/adjtime", w);
+        label_init("/etc");
+        r = write_string_file_atomic_label("/etc/adjtime", w);
         free(w);
 
         return r;
@@ -305,7 +285,7 @@ static char** get_ntp_services(void) {
         char **r = NULL, **files, **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",
@@ -387,8 +367,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")) {
@@ -410,6 +388,7 @@ static int read_ntp(DBusConnection *bus) {
                         goto finish;
                 }
 
+                tz.can_ntp = 1;
                 tz.use_ntp =
                         streq(s, "enabled") ||
                         streq(s, "enabled-runtime");
@@ -418,6 +397,7 @@ static int read_ntp(DBusConnection *bus) {
         }
 
         /* NTP is not installed. */
+        tz.can_ntp = 0;
         tz.use_ntp = 0;
         r = 0;
 
@@ -468,8 +448,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") ||
@@ -558,8 +536,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")) {
@@ -611,6 +587,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;
 
@@ -628,6 +618,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, }
 };
@@ -819,15 +810,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");
@@ -892,7 +892,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);