X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Ftimedate%2Ftimedated.c;h=bb134b7fffb4ee16102affaf25ef0ca48b533d93;hp=fdb4335464fd6dbfe1981d86b2b412568498592e;hb=7e7d4da22925c329d668334aec3b3e7f21f63bc3;hpb=f274ece0f76b5709408821e317e87aef76123db6 diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index fdb433546..bb134b7ff 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 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \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; + char _cleanup_free_ *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; + char _cleanup_strv_free_ **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; + FILE _cleanup_fclose_ *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);