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