timedated.c revision 72edcff5db936e54cfc322d9392ec46e2428fd9b
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2011 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <dbus/dbus.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0a6f50c0afdfc434b492493bd9efab20cbee8623Thomas Hindoe Paaboel Andersen#include <errno.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <string.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <unistd.h>
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "systemd/sd-id128.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "systemd/sd-messages.h"
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering#include "util.h"
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering#include "strv.h"
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek#include "dbus-common.h"
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering#include "polkit.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "def.h"
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering#include "hwclock.h"
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering#include "conf-files.h"
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens#include "path-util.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
5f402ae84bbc08fe8de5682e371b3f66c387da52Daniel Mack
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#define INTERFACE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <interface name=\"org.freedesktop.timedate1\">\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <property name=\"Timezone\" type=\"s\" access=\"read\"/>\n" \
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen " <property name=\"LocalRTC\" type=\"b\" access=\"read\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <property name=\"NTP\" type=\"b\" access=\"read\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <method name=\"SetTime\">\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"usec_utc\" type=\"x\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"relative\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " </method>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <method name=\"SetTimezone\">\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"timezone\" type=\"s\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen " </method>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <method name=\"SetLocalRTC\">\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"local_rtc\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"fix_system\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " </method>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <method name=\"SetNTP\">\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"use_ntp\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " </method>\n" \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " </interface>\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering#define INTROSPECTION \
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "<node>\n" \
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering INTERFACE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BUS_PROPERTIES_INTERFACE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BUS_INTROSPECTABLE_INTERFACE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BUS_PEER_INTERFACE \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "</node>\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#define INTERFACES_LIST \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering BUS_GENERIC_INTERFACES_LIST \
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "org.freedesktop.timedate1\0"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poetteringconst char timedate_interface[] _introspect_("timedate1") = INTERFACE;
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poetteringtypedef struct TZ {
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering char *zone;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering bool local_rtc;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering int use_ntp;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering} TZ;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic TZ tz = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .use_ntp = -1,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic usec_t remain_until;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void free_data(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(tz.zone);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tz.zone = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tz.local_rtc = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool valid_timezone(const char *name) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt const char *p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *t;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool slash = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen struct stat st;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (*name == '/' || *name == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (p = name; *p; p++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!(*p >= '0' && *p <= '9') &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering !(*p >= 'a' && *p <= 'z') &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering !(*p >= 'A' && *p <= 'Z') &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering !(*p == '-' || *p == '_' || *p == '+' || *p == '/'))
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*p == '/') {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (slash)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering slash = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering slash = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (slash)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = strappend("/usr/share/zoneinfo/", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = stat(t, &st);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(t);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!S_ISREG(st.st_mode))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int read_data(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *t = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free_data();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = readlink_malloc("/etc/localtime", &t);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -EINVAL)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to get target of /etc/localtime: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = path_startswith(t, "/usr/share/zoneinfo/");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = path_startswith(t, "../usr/share/zoneinfo/");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tz.zone = strdup(e);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!tz.zone)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto have_timezone;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef TARGET_FEDORA
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = parse_env_file("/etc/sysconfig/clock", NEWLINE,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "ZONE", &tz.zone,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0 && r != -ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to read /etc/sysconfig/clock: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef HAVE_DEBIAN
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = read_one_line_file("/etc/timezone", &tz.zone);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r != -ENOENT)
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen log_warning("Failed to read /etc/timezone: %s", strerror(-r));
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringhave_timezone:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (isempty(tz.zone)) {
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø free(tz.zone);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen tz.zone = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tz.local_rtc = hwclock_is_localtime() > 0;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int write_data_timezone(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *p = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen#ifdef TARGET_DEBIAN
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct stat st;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (!tz.zone) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (unlink("/etc/localtime") < 0 && errno != ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -errno;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen#ifdef TARGET_DEBIAN
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (unlink("/etc/timezone") < 0 && errno != ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strappend("../usr/share/zoneinfo/", tz.zone);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (!p)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = symlink_atomic(p, "/etc/localtime");
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef TARGET_DEBIAN
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (stat("/etc/timezone", &st) == 0 && S_ISREG(st.st_mode)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = write_one_line_file_atomic("/etc/timezone", tz.zone);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int write_data_local_rtc(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *s, *w;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = read_full_file("/etc/adjtime", &s, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r != -ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!tz.local_rtc)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen w = strdup(NULL_ADJTIME_LOCAL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!w)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *p, *e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t a, b;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strchr(s, '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EIO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strchr(p+1, '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EIO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = strchr(p, '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt free(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EIO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a = p - s;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt b = strlen(e);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!w) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering if (streq(w, NULL_ADJTIME_UTC)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(w);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (unlink("/etc/adjtime") < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno != ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = write_one_line_file_atomic("/etc/adjtime", w);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(w);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic char** get_ntp_services(void) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char **r = NULL, **files, **i;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering k = conf_files_list(&files, ".list",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "/etc/systemd/ntp-units.d",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "/run/systemd/ntp-units.d",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "/usr/local/lib/systemd/ntp-units.d",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "/usr/lib/systemd/ntp-units.d",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering NULL);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (k < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering STRV_FOREACH(i, files) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering FILE *f;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering f = fopen(*i, "re");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!f)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering continue;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering for (;;) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char line[PATH_MAX], *l, **q;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!fgets(line, sizeof(line), f)) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (ferror(f))
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to read NTP units file: %m");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering l = strstrip(line);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (l[0] == 0 || l[0] == '#')
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering continue;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering q = strv_append(r, l);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!q) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering strv_free(r);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = q;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering fclose(f);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering strv_free(files);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return strv_uniq(r);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int read_ntp(DBusConnection *bus) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering DBusMessage *m = NULL, *reply = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering DBusError error;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char **i, **l;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt assert(bus);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dbus_error_init(&error);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering l = get_ntp_services();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering STRV_FOREACH(i, l) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const char *s;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (m)
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt dbus_message_unref(m);
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt m = dbus_message_new_method_call(
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "org.freedesktop.systemd1",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "/org/freedesktop/systemd1",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "org.freedesktop.systemd1.Manager",
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering "GetUnitFileState");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!m) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!dbus_message_append_args(m,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering DBUS_TYPE_STRING, i,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering DBUS_TYPE_INVALID)) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (reply)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dbus_message_unref(reply);
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering if (!reply) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* This implementation does not exist, try next one */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dbus_error_free(&error);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_error("Failed to issue method call: %s", bus_error_message(&error));
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = -EIO;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering goto finish;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!dbus_message_get_args(reply, &error,
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering DBUS_TYPE_STRING, &s,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DBUS_TYPE_INVALID)) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to parse reply: %s", bus_error_message(&error));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = -EIO;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen goto finish;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen tz.use_ntp =
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen streq(s, "enabled") ||
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen streq(s, "enabled-runtime");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen goto finish;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* NTP is not installed. */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering tz.use_ntp = 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_message_unref(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (reply)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_message_unref(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering strv_free(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_error_free(&error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int start_ntp(DBusConnection *bus, DBusError *error) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen DBusMessage *m = NULL, *reply = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *mode = "replace";
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen char **i, **l;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(bus);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(error);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering l = get_ntp_services();
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering STRV_FOREACH(i, l) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (m)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering dbus_message_unref(m);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering m = dbus_message_new_method_call(
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering "org.freedesktop.systemd1",
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering "/org/freedesktop/systemd1",
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering "org.freedesktop.systemd1.Manager",
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering tz.use_ntp ? "StartUnit" : "StopUnit");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (!m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Could not allocate message.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen goto finish;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!dbus_message_append_args(m,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_STRING, i,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_STRING, &mode,
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering DBUS_TYPE_INVALID)) {
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering log_error("Could not append arguments to message.");
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering r = -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering }
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (reply)
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering dbus_message_unref(reply);
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering if (!reply) {
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering streq(error->name, "org.freedesktop.systemd1.LoadFailed") ||
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) {
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering /* This implementation does not exist, try next one */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dbus_error_free(error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to issue method call: %s", bus_error_message(error));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -EIO;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering goto finish;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* No implementaiton available... */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = -ENOENT;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringfinish:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (m)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dbus_message_unref(m);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (reply)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dbus_message_unref(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering strv_free(l);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic int enable_ntp(DBusConnection *bus, DBusError *error) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering DBusMessage *m = NULL, *reply = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering int r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering DBusMessageIter iter;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_bool_t f = FALSE, t = TRUE;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char **i, **l;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(bus);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(error);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering l = get_ntp_services();
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering STRV_FOREACH(i, l) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char* k[2];
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (m)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_message_unref(m);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering m = dbus_message_new_method_call(
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt "org.freedesktop.systemd1",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "/org/freedesktop/systemd1",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "org.freedesktop.systemd1.Manager",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!m) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Could not allocate message.");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_message_iter_init_append(m, &iter);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k[0] = *i;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k[1] = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = bus_append_strv_iter(&iter, k);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (r < 0) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Failed to append unit files.");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering /* send runtime bool */
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error("Failed to append runtime boolean.");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (tz.use_ntp) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt /* send force bool */
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Failed to append force boolean.");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (reply)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_message_unref(reply);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!reply) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering /* This implementation does not exist, try next one */
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_error_free(error);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering continue;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Failed to issue method call: %s", bus_error_message(error));
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -EIO;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_message_unref(m);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering m = dbus_message_new_method_call(
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "org.freedesktop.systemd1",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "/org/freedesktop/systemd1",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "org.freedesktop.systemd1.Manager",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "Reload");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!m) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Could not allocate message.");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_message_unref(reply);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!reply) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_error("Failed to issue method call: %s", bus_error_message(error));
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = -EIO;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = 0;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering goto finish;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering r = -ENOENT;
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poetteringfinish:
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering if (m)
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering dbus_message_unref(m);
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering if (reply)
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering dbus_message_unref(reply);
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering strv_free(l);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic int property_append_ntp(DBusMessageIter *i, const char *property, void *data) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dbus_bool_t db;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(i);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(property);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering db = tz.use_ntp > 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringstatic const BusProperty bus_timedate_properties[] = {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt { "Timezone", bus_property_append_string, "s", offsetof(TZ, zone), true },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { "LocalRTC", bus_property_append_bool, "b", offsetof(TZ, local_rtc) },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { "NTP", property_append_ntp, "b", offsetof(TZ, use_ntp) },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { NULL, }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen};
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic const BusBoundProperties bps[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "org.freedesktop.timedate1", bus_timedate_properties, &tz },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { NULL, }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen};
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poetteringstatic DBusHandlerResult timedate_message_handler(
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering DBusConnection *connection,
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering DBusMessage *message,
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering void *userdata) {
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen DBusMessage *reply = NULL, *changed = NULL;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen DBusError error;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen int r;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(connection);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(message);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen dbus_error_init(&error);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTimezone")) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen const char *z;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen dbus_bool_t interactive;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (!dbus_message_get_args(
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen message,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen &error,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen DBUS_TYPE_STRING, &z,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen DBUS_TYPE_BOOLEAN, &interactive,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen DBUS_TYPE_INVALID))
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return bus_send_error_reply(connection, message, &error, -EINVAL);
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (!valid_timezone(z))
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return bus_send_error_reply(connection, message, NULL, -EINVAL);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (!streq_ptr(z, tz.zone)) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek char *t;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-timezone", interactive, NULL, &error);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (r < 0)
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek t = strdup(z);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (!t)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek goto oom;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering free(tz.zone);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek tz.zone = t;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek /* 1. Write new configuration file */
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering r = write_data_timezone();
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (r < 0) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek log_error("Failed to set timezone: %s", strerror(-r));
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return bus_send_error_reply(connection, message, NULL, r);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek }
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek /* 2. Tell the kernel our time zone */
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek hwclock_set_timezone(NULL);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (tz.local_rtc) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek struct timespec ts;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek struct tm *tm;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* 3. Sync RTC from system clock, with the new delta */
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert_se(tm = localtime(&ts.tv_sec));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen hwclock_set_time(tm);
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_struct(LOG_INFO,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(SD_MESSAGE_TIMEZONE_CHANGE),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "TIMEZONE=%s", tz.zone,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "MESSAGE=Changed timezone to '%s'.", tz.zone,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering changed = bus_properties_changed_new(
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "/org/freedesktop/timedate1",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering "org.freedesktop.timedate1",
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering "Timezone\0");
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering if (!changed)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering goto oom;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering }
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetLocalRTC")) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen dbus_bool_t lrtc;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen dbus_bool_t fix_system;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen dbus_bool_t interactive;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (!dbus_message_get_args(
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering message,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering &error,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering DBUS_TYPE_BOOLEAN, &lrtc,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering DBUS_TYPE_BOOLEAN, &fix_system,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering DBUS_TYPE_BOOLEAN, &interactive,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering DBUS_TYPE_INVALID))
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (lrtc != tz.local_rtc) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen struct timespec ts;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-local-rtc", interactive, NULL, &error);
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering if (r < 0)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering tz.local_rtc = lrtc;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering /* 1. Write new configuration file */
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = write_data_local_rtc();
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (r < 0) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen log_error("Failed to set RTC to local/UTC: %s", strerror(-r));
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return bus_send_error_reply(connection, message, NULL, r);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen }
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen /* 2. Tell the kernel our time zone */
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen hwclock_set_timezone(NULL);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen /* 3. Synchronize clocks */
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (fix_system) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering struct tm tm;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering /* Sync system clock from RTC; first,
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering * initialize the timezone fields of
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering * struct tm. */
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (tz.local_rtc)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering tm = *localtime(&ts.tv_sec);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering else
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering tm = *gmtime(&ts.tv_sec);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering /* Override the main fields of
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek * struct tm, but not the timezone
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * fields */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (hwclock_get_time(&tm) >= 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* And set the system clock
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * with this */
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (tz.local_rtc)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ts.tv_sec = mktime(&tm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ts.tv_sec = timegm(&tm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering clock_settime(CLOCK_REALTIME, &ts);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen } else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct tm *tm;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Sync RTC from system clock */
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering if (tz.local_rtc)
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering tm = localtime(&ts.tv_sec);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tm = gmtime(&ts.tv_sec);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering hwclock_set_time(tm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_info("RTC configured to %s time.", tz.local_rtc ? "local" : "UTC");
40a1eebde6be7ac3f1885147fc24e06ad1da260cDavid Herrmann
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering changed = bus_properties_changed_new(
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering "/org/freedesktop/timedate1",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "org.freedesktop.timedate1",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "LocalRTC\0");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!changed)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering goto oom;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTime")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int64_t utc;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_bool_t relative;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dbus_bool_t interactive;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!dbus_message_get_args(
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering message,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering &error,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_INT64, &utc,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_BOOLEAN, &relative,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_BOOLEAN, &interactive,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_INVALID))
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!relative && utc <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return bus_send_error_reply(connection, message, NULL, -EINVAL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!relative || utc != 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct timespec ts;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct tm* tm;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return bus_send_error_reply(connection, message, &error, r);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (relative)
a38d99451f2bf8026ec51aee91662292e823c6a8Lennart Poettering timespec_store(&ts, now(CLOCK_REALTIME) + utc);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering timespec_store(&ts, utc);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Set system clock */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to set local time: %m");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return bus_send_error_reply(connection, message, NULL, -errno);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* Sync down to RTC */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (tz.local_rtc)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering tm = localtime(&ts.tv_sec);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tm = gmtime(&ts.tv_sec);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering hwclock_set_time(tm);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_struct(LOG_INFO,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(SD_MESSAGE_TIME_CHANGE),
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering "REALTIME=%llu", (unsigned long long) timespec_load(&ts),
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering "MESSAGE=Changed local time to %s", ctime(&ts.tv_sec),
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering NULL);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetNTP")) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dbus_bool_t ntp;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dbus_bool_t interactive;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2a1288ff89322a2f49c79f6d1832c8164c14a05cLennart Poettering if (!dbus_message_get_args(
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering message,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering &error,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering DBUS_TYPE_BOOLEAN, &ntp,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBUS_TYPE_BOOLEAN, &interactive,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering DBUS_TYPE_INVALID))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (ntp != !!tz.use_ntp) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-ntp", interactive, NULL, &error);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return bus_send_error_reply(connection, message, &error, r);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering tz.use_ntp = !!ntp;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = enable_ntp(connection, &error);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return bus_send_error_reply(connection, message, &error, r);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = start_ntp(connection, &error);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return bus_send_error_reply(connection, message, &error, r);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_info("Set NTP to %s", tz.use_ntp ? "enabled" : "disabled");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering changed = bus_properties_changed_new(
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "/org/freedesktop/timedate1",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "org.freedesktop.timedate1",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "NTP\0");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!changed)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering goto oom;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!(reply = dbus_message_new_method_return(message)))
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering goto oom;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!dbus_connection_send(connection, reply, NULL))
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering goto oom;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_message_unref(reply);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering reply = NULL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (changed) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
a5f035960006556beab51c42e6948985635e261aLennart Poettering if (!dbus_connection_send(connection, changed, NULL))
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering goto oom;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dbus_message_unref(changed);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return DBUS_HANDLER_RESULT_HANDLED;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringoom:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (reply)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_message_unref(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (changed)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_message_unref(changed);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_error_free(&error);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return DBUS_HANDLER_RESULT_NEED_MEMORY;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstatic int connect_bus(DBusConnection **_bus) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering static const DBusObjectPathVTable timedate_vtable = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .message_function = timedate_message_handler
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering };
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering DBusError error;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering DBusConnection *bus = NULL;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int r;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(_bus);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dbus_error_init(&error);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!bus) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -ECONNREFUSED;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_connection_set_exit_on_disconnect(bus, FALSE);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL) ||
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dbus_bus_request_name(bus, "org.freedesktop.timedate1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (dbus_error_is_set(&error)) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to register name on bus: %s", bus_error_message(&error));
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = -EEXIST;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering goto fail;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_error("Failed to acquire name.");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = -EEXIST;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (_bus)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering *_bus = bus;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenfail:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dbus_connection_close(bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_connection_unref(bus);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dbus_error_free(&error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint main(int argc, char *argv[]) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DBusConnection *bus = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool exiting = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_set_target(LOG_TARGET_AUTO);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_parse_environment();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_open();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering umask(0022);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (argc == 2 && streq(argv[1], "--introspect")) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "<node>\n", stdout);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering fputs(timedate_interface, stdout);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen fputs("</node>\n", stdout);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (argc != 1) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_error("This program takes no arguments.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = read_data();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to read timezone data: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = connect_bus(&bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = read_ntp(bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to determine whether NTP is enabled: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (;;) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering exiting = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free_data();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (bus) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dbus_connection_flush(bus);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dbus_connection_close(bus);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dbus_connection_unref(bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen