timedatectl.c revision 546158bc6f46f8004cc11e81d19d223e0da56730
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/***
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen This file is part of systemd.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2012 Lennart Poettering
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is free software; you can redistribute it and/or modify it
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen under the terms of the GNU Lesser General Public License as published by
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (at your option) any later version.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is distributed in the hope that it will be useful, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Lesser General Public License for more details.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen You should have received a copy of the GNU Lesser General Public License
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen***/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <stdlib.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <stdbool.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <unistd.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <getopt.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <locale.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <sys/timex.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "dbus-common.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "spawn-polkit-agent.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "build.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "hwclock.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "pager.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "time-dst.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic bool arg_adjust_system_clock = false;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic bool arg_no_pager = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic enum transport {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen TRANSPORT_NORMAL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen TRANSPORT_SSH,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen TRANSPORT_POLKIT
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen} arg_transport = TRANSPORT_NORMAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic bool arg_ask_password = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic const char *arg_host = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic void pager_open_if_enabled(void) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (arg_no_pager)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pager_open(false);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic void polkit_agent_open_if_enabled(void) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Open the polkit agent as a child process if necessary */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!arg_ask_password)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen polkit_agent_open();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersentypedef struct StatusInfo {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *timezone;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool local_rtc;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool ntp;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool can_ntp;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen} StatusInfo;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic bool ntp_synced(void) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct timex txc = {};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (adjtimex(&txc) < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (txc.status & STA_UNSYNC)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic const char *jump_str(int delta_minutes, char *s, size_t size) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (delta_minutes == 60)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return "one hour forward";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (delta_minutes == -60)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return "one hour backwards";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (delta_minutes < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen snprintf(s, size, "%i minutes backwards", -delta_minutes);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return s;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (delta_minutes > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen snprintf(s, size, "%i minutes forward", delta_minutes);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return s;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return "";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic void print_status_info(StatusInfo *i) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen usec_t n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char a[FORMAT_TIMESTAMP_MAX];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char b[FORMAT_TIMESTAMP_MAX];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char s[32];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct tm tm;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen time_t sec;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *zc, *zn;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen time_t t, tc, tn;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int dn;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool is_dstc, is_dstn;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(i);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* enforce the values of /etc/localtime */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (getenv("TZ")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fprintf(stderr, "Warning: ignoring the TZ variable, reading the system's timezone setting only.\n\n");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unsetenv("TZ");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen n = now(CLOCK_REALTIME);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sec = (time_t) (n / USEC_PER_SEC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf(" Local time: %s\n", a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf(" Universal time: %s\n", a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = hwclock_get_time(&tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Calculcate the week-day */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen mktime(&tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S", &tm) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf(" RTC time: %s\n", a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf(" Timezone: %s (%s)\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " NTP enabled: %s\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "NTP synchronized: %s\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " RTC in local TZ: %s\n",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strna(i->timezone),
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i->can_ntp ? yes_no(i->ntp) : "n/a",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen yes_no(ntp_synced()),
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen yes_no(i->local_rtc));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = time_get_dst(sec, "/etc/localtime",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &tc, &zc, &is_dstc,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &tn, &dn, &zn, &is_dstn);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (r < 0)
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen printf(" DST active: n/a\n");
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen else {
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen printf(" DST active: %s\n", yes_no(is_dstc));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t = tc - 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen char_array_0(a);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen zero(tm);
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(b);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen printf(" Last DST change: DST %s at\n"
23446f01480e1d6f72a03d71f9c67cbf34ddaf3bMichal Schmidt " %s\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " %s\n",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen is_dstc ? "began" : "ended", a, b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t = tn - 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char_array_0(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zero(tm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen char_array_0(b);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen printf(" Next DST change: DST %s (the clock jumps %s) at\n"
52d629010db73a9466c359201916494bd55186d1Tom Gundersen " %s\n"
52d629010db73a9466c359201916494bd55186d1Tom Gundersen " %s\n",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(zc);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(zn);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
52d629010db73a9466c359201916494bd55186d1Tom Gundersen
52d629010db73a9466c359201916494bd55186d1Tom Gundersen if (i->local_rtc)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fputs("\n" ANSI_HIGHLIGHT_ON
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Warning: The RTC is configured to maintain time in the local time zone. This\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " mode is not fully supported and will create various problems with time\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " zone changes and daylight saving adjustments. If at all possible use\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " RTC in UTC, by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(iter);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen switch (dbus_message_iter_get_arg_type(iter)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case DBUS_TYPE_STRING: {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *s;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_get_basic(iter, &s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!isempty(s)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(name, "Timezone"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i->timezone = s;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case DBUS_TYPE_BOOLEAN: {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_bool_t b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_get_basic(iter, &b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(name, "LocalRTC"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i->local_rtc = b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (streq(name, "NTP"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i->ntp = b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (streq(name, "CanNTP"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i->can_ntp = b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int show_status(DBusConnection *bus, char **args, unsigned n) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *interface = "";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBusMessageIter iter, sub, sub2, sub3;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen StatusInfo info = {};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_method_call_with_reply(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.DBus.Properties",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "GetAll",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &reply,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_STRING, &interface,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INVALID);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!dbus_message_iter_init(reply, &iter) ||
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse reply.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_recurse(&iter, &sub);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse reply.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_recurse(&sub, &sub2);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse reply.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse reply.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_recurse(&sub2, &sub3);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = status_property(name, &sub3, &info);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse reply.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_message_iter_next(&sub);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers print_status_info(&info);
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers return 0;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers}
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers
a9ec9f29420623133c419ddc8864921a824751fbKay Sieversstatic int set_time(DBusConnection *bus, char **args, unsigned n) {
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers dbus_bool_t relative = false, interactive = arg_ask_password;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers usec_t t;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers dbus_int64_t u;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers int r;
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n == 2);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen polkit_agent_open_if_enabled();
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_timestamp(args[1], &t);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse time specification: %s", args[1]);
a9ec9f29420623133c419ddc8864921a824751fbKay Sievers return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen u = (dbus_uint64_t) t;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen return bus_method_call_with_reply(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "SetTime",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &reply,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INT64, &u,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &relative,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &interactive,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INVALID);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int set_timezone(DBusConnection *bus, char **args, unsigned n) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_bool_t interactive = arg_ask_password;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n == 2);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen polkit_agent_open_if_enabled();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return bus_method_call_with_reply(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "SetTimezone",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &reply,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_STRING, &args[1],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &interactive,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INVALID);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int set_local_rtc(DBusConnection *bus, char **args, unsigned n) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_bool_t interactive = arg_ask_password, b, q;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n == 2);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen polkit_agent_open_if_enabled();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_boolean(args[1]);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse local RTC setting: %s", args[1]);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b = r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen q = arg_adjust_system_clock;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return bus_method_call_with_reply(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "SetLocalRTC",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &reply,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &b,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &q,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &interactive,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INVALID);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int set_ntp(DBusConnection *bus, char **args, unsigned n) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_bool_t interactive = arg_ask_password, b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n == 2);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen polkit_agent_open_if_enabled();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_boolean(args[1]);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to parse NTP setting: %s", args[1]);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b = r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return bus_method_call_with_reply(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.timedate1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "SetNTP",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &reply,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &b,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_BOOLEAN, &interactive,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBUS_TYPE_INVALID);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int list_timezones(DBusConnection *bus, char **args, unsigned n) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_fclose_ FILE *f = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_strv_free_ char **zones = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t n_zones = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n == 1);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen f = fopen("/usr/share/zoneinfo/zone.tab", "re");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!f) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to open timezone database: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (;;) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char l[LINE_MAX], *p, **z, *w;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!fgets(l, sizeof(l), f)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (feof(f))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to read timezone database: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p = strstrip(l);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (isempty(p) || *p == '#')
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Skip over country code */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += strcspn(p, WHITESPACE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += strspn(p, WHITESPACE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Skip over coordinates */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += strcspn(p, WHITESPACE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += strspn(p, WHITESPACE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Found timezone name */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = strcspn(p, WHITESPACE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k <= 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen w = strndup(p, k);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!w)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen z = realloc(zones, sizeof(char*) * (n_zones + 2));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!z) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(w);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zones = z;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zones[n_zones++] = w;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (zones)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen zones[n_zones] = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pager_open_if_enabled();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strv_sort(zones);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strv_print(zones);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int help(void) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf("%s [OPTIONS...] COMMAND ...\n\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Query or change system time and date settings.\n\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " -h --help Show this help\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --version Show package version\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --adjust-system-clock\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " Adjust system clock when changing local RTC mode\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --no-pager Do not pipe output into a pager\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " -P --privileged Acquire privileges before execution\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --no-ask-password Do not prompt for password\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " -H --host=[USER@]HOST Operate on remote host\n\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Commands:\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " status Show current time settings\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " set-time TIME Set system time\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " set-timezone ZONE Set system timezone\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " list-timezones Show known timezones\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " set-local-rtc BOOL Control whether RTC is in local time\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " set-ntp BOOL Control whether NTP is enabled\n",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen program_invocation_short_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen return 0;
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int parse_argv(int argc, char *argv[]) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen enum {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_VERSION = 0x100,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_NO_PAGER,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_ADJUST_SYSTEM_CLOCK,
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen ARG_NO_ASK_PASSWORD
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen };
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen static const struct option options[] = {
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen { "help", no_argument, NULL, 'h' },
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen { "version", no_argument, NULL, ARG_VERSION },
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen { "no-pager", no_argument, NULL, ARG_NO_PAGER },
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering { "host", required_argument, NULL, 'H' },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "privileged", no_argument, NULL, 'P' },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "adjust-system-clock", no_argument, NULL, ARG_ADJUST_SYSTEM_CLOCK },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { NULL, 0, NULL, 0 }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int c;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argc >= 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argv);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen while ((c = getopt_long(argc, argv, "hH:P", options, NULL)) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen switch (c) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case 'h':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen help();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_VERSION:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen puts(PACKAGE_STRING);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen puts(SYSTEMD_FEATURES);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case 'P':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_transport = TRANSPORT_POLKIT;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case 'H':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_transport = TRANSPORT_SSH;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_host = optarg;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_NO_ASK_PASSWORD:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_ask_password = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_ADJUST_SYSTEM_CLOCK:
19c29853804f8806866695d743fd4e3586996dbbMichal Schmidt arg_adjust_system_clock = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_NO_PAGER:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_no_pager = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case '?':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen default:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Unknown option code %c", c);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
23446f01480e1d6f72a03d71f9c67cbf34ddaf3bMichal Schmidt }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int timedatectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen static const struct {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char* verb;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const enum {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen MORE,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen LESS,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen EQUAL
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } argc_cmp;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const int argc;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } verbs[] = {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "status", LESS, 1, show_status },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "set-time", EQUAL, 2, set_time },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "set-timezone", EQUAL, 2, set_timezone },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "list-timezones", EQUAL, 1, list_timezones },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "set-local-rtc", EQUAL, 2, set_local_rtc },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "set-ntp", EQUAL, 2, set_ntp, },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int left;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unsigned i;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argc >= 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argv);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen left = argc - optind;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (left <= 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Special rule: no arguments means "status" */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen i = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(argv[optind], "help")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen help();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (i = 0; i < ELEMENTSOF(verbs); i++)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(argv[optind], verbs[i].verb))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (i >= ELEMENTSOF(verbs)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Unknown operation %s", argv[optind]);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen switch (verbs[i].argc_cmp) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case EQUAL:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (left != verbs[i].argc) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Invalid number of arguments.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case MORE:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (left < verbs[i].argc) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Too few arguments.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case LESS:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (left > verbs[i].argc) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Too many arguments.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen default:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_not_reached("Unknown comparison operator.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!bus) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to get D-Bus connection: %s", error->message);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return verbs[i].dispatch(bus, argv + optind, left);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenint main(int argc, char *argv[]) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r, retval = EXIT_FAILURE;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBusConnection *bus = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen DBusError error;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_error_init(&error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen setlocale(LC_ALL, "");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_parse_environment();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_open();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_argv(argc, argv);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r == 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen retval = EXIT_SUCCESS;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (arg_transport == TRANSPORT_NORMAL)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (arg_transport == TRANSPORT_POLKIT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus_connect_system_polkit(&bus, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (arg_transport == TRANSPORT_SSH)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bus_connect_system_ssh(NULL, arg_host, &bus, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_not_reached("Uh, invalid transport...");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = timedatectl_main(bus, argc, argv, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen retval = r < 0 ? EXIT_FAILURE : r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenfinish:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (bus) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_connection_flush(bus);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_connection_close(bus);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_connection_unref(bus);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_error_free(&error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dbus_shutdown();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pager_close();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return retval;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen