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