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