timedatectl.c revision 266f3e269d173f104aa2a5e3ceac9b6979ea5039
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/***
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2012 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2013 Kay Sievers
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen***/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <getopt.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <locale.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <stdbool.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <stdlib.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "sd-bus.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "bus-error.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "bus-util.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "pager.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "spawn-polkit-agent.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "strv.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "terminal-util.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "util.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic bool arg_no_pager = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic bool arg_ask_password = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic char *arg_host = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic bool arg_adjust_system_clock = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void pager_open_if_enabled(void) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (arg_no_pager)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen pager_open(false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void polkit_agent_open_if_enabled(void) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Open the polkit agent as a child process if necessary */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!arg_ask_password)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (arg_transport != BUS_TRANSPORT_LOCAL)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen polkit_agent_open();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersentypedef struct StatusInfo {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t time;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *timezone;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t rtc_time;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool rtc_local;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool ntp_enabled;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool ntp_capable;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool ntp_synced;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen} StatusInfo;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void status_info_clear(StatusInfo *info) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (info) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(info->timezone);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen zero(*info);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void print_status_info(const StatusInfo *i) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char a[FORMAT_TIMESTAMP_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen struct tm tm;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen time_t sec;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool have_time = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *old_tz = NULL, *tz;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Save the old $TZ */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen tz = getenv("TZ");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (tz)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen old_tz = strdupa(tz);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Set the new $TZ */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (setenv("TZ", isempty(i->timezone) ? "UTC" : i->timezone, true) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen tzset();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (i->time != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sec = (time_t) (i->time / USEC_PER_SEC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen have_time = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sec = time(NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen have_time = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning("Could not get time from timedated and not operating locally, ignoring.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (have_time) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" Local time: %.*s\n", (int) sizeof(a), a);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" Universal time: %.*s\n", (int) sizeof(a), a);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl } else {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" Local time: %s\n", "n/a");
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" Universal time: %s\n", "n/a");
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt }
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt if (i->rtc_time > 0) {
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt time_t rtc_sec;
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
b7e7184634d573fb73143210962acce205f37f61Michael Biebl rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" RTC time: %.*s\n", (int) sizeof(a), a);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl } else
b7e7184634d573fb73143210962acce205f37f61Michael Biebl printf(" RTC time: %s\n", "n/a");
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (have_time)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl /* Restore the $TZ */
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (old_tz)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = setenv("TZ", old_tz, true);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl else
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unsetenv("TZ");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
91e7bad45dced1cb2dfaac79337bb08d6e2b74a9Andreas Henriksson tzset();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf(" Time zone: %s (%.*s)\n"
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen " Network time on: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "NTP synchronized: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " RTC in local TZ: %s\n",
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen yes_no(i->ntp_synced),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen yes_no(i->rtc_local));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (i->rtc_local)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fputs("\n" ANSI_HIGHLIGHT
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Warning: The system is configured to read the RTC time in the local time zone.\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " This mode can not be fully supported. It will create various problems\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " with time zone changes and daylight saving time adjustments. The RTC\n"
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen " time is never updated, it relies on external facilities to maintain it.\n"
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen " If at all possible, use RTC in UTC by calling\n"
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen " 'timedatectl set-local-rtc 0'." ANSI_NORMAL "\n", stdout);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int show_status(sd_bus *bus, char **args, unsigned n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(status_info_clear) StatusInfo info = {};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen static const struct bus_properties_map map[] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "Timezone", "s", NULL, offsetof(StatusInfo, timezone) },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "LocalRTC", "b", NULL, offsetof(StatusInfo, rtc_local) },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "NTP", "b", NULL, offsetof(StatusInfo, ntp_enabled) },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "CanNTP", "b", NULL, offsetof(StatusInfo, ntp_capable) },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt { "NTPSynchronized", "b", NULL, offsetof(StatusInfo, ntp_synced) },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt { "TimeUSec", "t", NULL, offsetof(StatusInfo, time) },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt { "RTCTimeUSec", "t", NULL, offsetof(StatusInfo, rtc_time) },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt {}
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt };
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt int r;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt assert(bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt r = bus_map_all_properties(bus,
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen map,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &info);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
aad0a2c80097926757d4385e5f5492082d47f006Zbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to query server: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen print_status_info(&info);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int set_time(sd_bus *bus, char **args, unsigned n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen bool relative = false, interactive = arg_ask_password;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen usec_t t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(args);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(n == 2);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen polkit_agent_open_if_enabled();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = parse_timestamp(args[1], &t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to parse time specification: %s", args[1]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call_method(bus,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen "/org/freedesktop/timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "SetTime",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &error,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "xbb", (int64_t)t, relative, interactive);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to set time: %s", bus_error_message(&error, -r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int set_timezone(sd_bus *bus, char **args, unsigned n) {
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(args);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(n == 2);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen polkit_agent_open_if_enabled();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call_method(bus,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "SetTimezone",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &error,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "sb", args[1], arg_ask_password);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to set time zone: %s", bus_error_message(&error, -r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int set_local_rtc(sd_bus *bus, char **args, unsigned n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r, b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(args);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(n == 2);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen polkit_agent_open_if_enabled();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = parse_boolean(args[1]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (b < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to parse local RTC setting: %s", args[1]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call_method(bus,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "SetLocalRTC",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &error,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "bbb", b, arg_adjust_system_clock, arg_ask_password);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to set local RTC: %s", bus_error_message(&error, -r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int set_ntp(sd_bus *bus, char **args, unsigned n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int b, r;
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(args);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(n == 2);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen polkit_agent_open_if_enabled();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = parse_boolean(args[1]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (b < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to parse NTP setting: %s", args[1]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call_method(bus,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.timedate1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "SetNTP",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &error,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "bb", b, arg_ask_password);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to set ntp: %s", bus_error_message(&error, -r));
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt return r;
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt}
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pittstatic int list_timezones(sd_bus *bus, char **args, unsigned n) {
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt _cleanup_strv_free_ char **zones = NULL;
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(args);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(n == 1);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = get_timezones(&zones);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_error_errno(r, "Failed to read list of time zones: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen pager_open_if_enabled();
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt strv_print(zones);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void help(void) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s [OPTIONS...] COMMAND ...\n\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Query or change system time and date settings.\n\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " -h --help Show this help message\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " --version Show package version\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " --no-pager Do not pipe output into a pager\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " --no-ask-password Do not prompt for password\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " -H --host=[USER@]HOST Operate on remote host\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " -M --machine=CONTAINER Operate on local container\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " --adjust-system-clock Adjust system clock when changing local RTC mode\n\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Commands:\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " status Show current time settings\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " set-time TIME Set system time\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " set-timezone ZONE Set system time zone\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " list-timezones Show known time zones\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " set-local-rtc BOOL Control whether RTC is in local time\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen " set-ntp BOOL Enable or disable network time synchronization\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen program_invocation_short_name);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int parse_argv(int argc, char *argv[]) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen enum {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ARG_VERSION = 0x100,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ARG_NO_PAGER,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ARG_ADJUST_SYSTEM_CLOCK,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ARG_NO_ASK_PASSWORD
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen };
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen static const struct option options[] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "help", no_argument, NULL, 'h' },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "version", no_argument, NULL, ARG_VERSION },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt { "no-pager", no_argument, NULL, ARG_NO_PAGER },
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt { "host", required_argument, NULL, 'H' },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "machine", required_argument, NULL, 'M' },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "adjust-system-clock", no_argument, NULL, ARG_ADJUST_SYSTEM_CLOCK },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen {}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen };
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int c;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(argc >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(argv);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (c) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case 'h':
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen help();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case ARG_VERSION:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return version();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case 'H':
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_transport = BUS_TRANSPORT_REMOTE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_host = optarg;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case 'M':
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_transport = BUS_TRANSPORT_MACHINE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_host = optarg;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case ARG_NO_ASK_PASSWORD:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_ask_password = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case ARG_ADJUST_SYSTEM_CLOCK:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_adjust_system_clock = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case ARG_NO_PAGER:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen arg_no_pager = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case '?':
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen default:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_not_reached("Unhandled option");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timedatectl_main(sd_bus *bus, int argc, char *argv[]) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen static const struct {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char* verb;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const enum {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MORE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LESS,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen EQUAL
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } argc_cmp;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const int argc;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } verbs[] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "status", LESS, 1, show_status },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "set-time", EQUAL, 2, set_time },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "set-timezone", EQUAL, 2, set_timezone },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "list-timezones", EQUAL, 1, list_timezones },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "set-local-rtc", EQUAL, 2, set_local_rtc },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen { "set-ntp", EQUAL, 2, set_ntp, },
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen };
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int left;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned i;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(argc >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(argv);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen left = argc - optind;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (left <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Special rule: no arguments means "status" */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen i = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (streq(argv[optind], "help")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen help();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < ELEMENTSOF(verbs); i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (streq(argv[optind], verbs[i].verb))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (i >= ELEMENTSOF(verbs)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Unknown operation %s", argv[optind]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (verbs[i].argc_cmp) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case EQUAL:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (left != verbs[i].argc) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid number of arguments.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case MORE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (left < verbs[i].argc) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Too few arguments.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case LESS:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (left > verbs[i].argc) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Too many arguments.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen default:
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek assert_not_reached("Unknown comparison operator.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return verbs[i].dispatch(bus, argv + optind, left);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint main(int argc, char *argv[]) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen setlocale(LC_ALL, "");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_parse_environment();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_open();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = parse_argv(argc, argv);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto finish;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = bus_connect_transport(arg_transport, arg_host, false, &bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl log_error_errno(r, "Failed to create bus connection: %m");
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt goto finish;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl }
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = timedatectl_main(bus, argc, argv);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfinish:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen pager_close();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen