X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftimedate%2Ftimedated.c;h=5d3b8c41e6cd59ced4a8141500410c96ae036131;hb=1930eed2a7855d2df06ccf51f9e394428bf547e2;hp=95255def298a2e22d54b886561997a30133809ce;hpb=24efb112451413c1013d5f7fe27d7e2cd407647a;p=elogind.git diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 95255def2..5d3b8c41e 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "sd-id128.h" #include "sd-messages.h" @@ -37,6 +38,7 @@ #include "fileio-label.h" #include "label.h" #include "bus-util.h" +#include "bus-errors.h" #include "event-util.h" #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n" @@ -45,84 +47,24 @@ typedef struct Context { char *zone; bool local_rtc; - unsigned can_ntp; - unsigned use_ntp; + bool can_ntp; + bool use_ntp; Hashmap *polkit_registry; } Context; -static void context_reset(Context *c) { - assert(c); - - free(c->zone); - c->zone = NULL; - - c->local_rtc = false; - c->can_ntp = c->use_ntp = -1; -} - static void context_free(Context *c, sd_bus *bus) { assert(c); - context_reset(c); + free(c->zone); bus_verify_polkit_async_registry_free(bus, c->polkit_registry); } -static bool valid_timezone(const char *name) { - const char *p; - char *t; - bool slash = false; - int r; - struct stat st; - - assert(name); - - if (*name == '/' || *name == 0) - return false; - - for (p = name; *p; p++) { - if (!(*p >= '0' && *p <= '9') && - !(*p >= 'a' && *p <= 'z') && - !(*p >= 'A' && *p <= 'Z') && - !(*p == '-' || *p == '_' || *p == '+' || *p == '/')) - return false; - - if (*p == '/') { - - if (slash) - return false; - - slash = true; - } else - slash = false; - } - - if (slash) - return false; - - t = strappend("/usr/share/zoneinfo/", name); - if (!t) - return false; - - r = stat(t, &st); - free(t); - - if (r < 0) - return false; - - if (!S_ISREG(st.st_mode)) - return false; - - return true; -} - static int context_read_data(Context *c) { _cleanup_free_ char *t = NULL; int r; assert(c); - context_reset(c); - r = readlink_malloc("/etc/localtime", &t); if (r < 0) { if (r == -EINVAL) @@ -323,18 +265,12 @@ static int context_read_ntp(Context *c, sd_bus *bus) { if (r < 0) return r; - c->can_ntp = 1; - c->use_ntp = - streq(s, "enabled") || - streq(s, "enabled-runtime"); + c->can_ntp = true; + c->use_ntp = STR_IN_SET(s, "enabled", "enabled-runtime"); return 0; } - /* NTP is not installed. */ - c->can_ntp = 0; - c->use_ntp = 0; - return 0; } @@ -465,7 +401,7 @@ static int property_get_rtc_time( int r; zero(tm); - r = clock_get_time(&tm); + r = clock_get_hwclock(&tm); if (r == -EBUSY) { log_warning("/dev/rtc is busy. Is somebody keeping it open continuously? That's not a good idea... Returning a bogus RTC timestamp."); t = 0; @@ -519,7 +455,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s if (r < 0) return r; - if (!valid_timezone(z)) + if (!timezone_is_valid(z)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z); if (streq_ptr(z, c->zone)) @@ -555,7 +491,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s /* 3. 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_time(tm); + clock_set_hwclock(tm); } log_struct(LOG_INFO, @@ -621,7 +557,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata, /* Override the main fields of * struct tm, but not the timezone * fields */ - if (clock_get_time(&tm) >= 0) { + if (clock_get_hwclock(&tm) >= 0) { /* And set the system clock * with this */ @@ -642,7 +578,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata, else tm = gmtime(&ts.tv_sec); - clock_set_time(tm); + clock_set_hwclock(tm); } log_info("RTC configured to %s time.", c->local_rtc ? "local" : "UTC"); @@ -664,6 +600,9 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu assert(m); assert(c); + if (c->use_ntp) + return sd_bus_error_setf(error, BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, "Automatic time synchronization is enabled"); + r = sd_bus_message_read(m, "xbb", &utc, &relative, &interactive); if (r < 0) return r; @@ -705,8 +644,7 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu tm = localtime(&ts.tv_sec); else tm = gmtime(&ts.tv_sec); - - clock_set_time(tm); + clock_set_hwclock(tm); log_struct(LOG_INFO, MESSAGE_ID(SD_MESSAGE_TIME_CHANGE), @@ -752,14 +690,12 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus return sd_bus_reply_method_return(m, NULL); } -#include - static const sd_bus_vtable timedate_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("LocalRTC", "b", NULL, offsetof(Context, local_rtc), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("CanNTP", "b", bus_property_get_tristate, offsetof(Context, can_ntp), 0), - SD_BUS_PROPERTY("NTP", "b", bus_property_get_tristate, offsetof(Context, use_ntp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("LocalRTC", "b", bus_property_get_bool, offsetof(Context, local_rtc), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("CanNTP", "b", bus_property_get_bool, offsetof(Context, can_ntp), 0), + SD_BUS_PROPERTY("NTP", "b", bus_property_get_bool, offsetof(Context, use_ntp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("NTPSynchronized", "b", property_get_ntp_sync, 0, 0), SD_BUS_PROPERTY("TimeUSec", "t", property_get_time, 0, 0), SD_BUS_PROPERTY("RTCTimeUSec", "t", property_get_rtc_time, 0, 0), @@ -809,13 +745,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { } int main(int argc, char *argv[]) { - Context context = { - .zone = NULL, - .local_rtc = false, - .can_ntp = -1, - .use_ntp = -1, - }; - + Context context = {}; _cleanup_event_unref_ sd_event *event = NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; int r;