timedatectl.c revision 3e5e74d5b7f6fcbeff7b6e4e06abd931aab14c48
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering This file is part of systemd.
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering Copyright 2012 Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering Copyright 2013 Kay Sievers
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering systemd is free software; you can redistribute it and/or modify it
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering under the terms of the GNU Lesser General Public License as published by
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering (at your option) any later version.
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering systemd is distributed in the hope that it will be useful, but
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering Lesser General Public License for more details.
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering You should have received a copy of the GNU Lesser General Public License
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic bool arg_no_pager = false;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic bool arg_ask_password = true;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic bool arg_adjust_system_clock = false;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic void pager_open_if_enabled(void) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic void polkit_agent_open_if_enabled(void) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Open the polkit agent as a child process if necessary */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringtypedef struct StatusInfo {
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poetteringstatic const char *jump_str(int delta_minutes, char *s, size_t size) {
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering return "one hour forward";
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering return "one hour backwards";
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering snprintf(s, size, "%i minutes backwards", -delta_minutes);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering snprintf(s, size, "%i minutes forward", delta_minutes);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic void print_status_info(const StatusInfo *i) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_free_ char *zc = NULL, *zn = NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Enforce the values of /etc/localtime */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(stderr, "Warning: Ignoring the TZ variable.\n\n");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error_errno(errno, "Failed to set TZ environment variable: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (i->time != 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else if (IN_SET(arg_transport, BUS_TRANSPORT_REMOTE, BUS_TRANSPORT_MACHINE)) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering printf(" Local time: %.*s\n", (int) sizeof(a), a);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering printf(" Universal time: %.*s\n", (int) sizeof(a), a);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering rtc_sec = (time_t)(i->rtc_time / USEC_PER_SEC);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering printf(" RTC time: %.*s\n", (int) sizeof(a), a);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering " NTP enabled: %s\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "NTP synchronized: %s\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering " RTC in local TZ: %s\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering printf(" DST active: %s\n", yes_no(is_dstc));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering (int) sizeof(a), a,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering (int) sizeof(b), b);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering printf(" Next DST change: DST %s (the clock jumps %s) at\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering (int) sizeof(a), a,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering (int) sizeof(b), b);
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering printf(" DST active: %s\n", yes_no(is_dstc));
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering "Warning: The system is configured to read the RTC time in the local time zone. This\n"
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering " mode can not be fully supported. It will create various problems with time\n"
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering " zone changes and daylight saving time adjustments. The RTC time is never updated,\n"
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering " it relies on external facilities to maintain it. If at all possible, use\n"
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering " RTC in UTC by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poetteringstatic int show_status(sd_bus *bus, char **args, unsigned n) {
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering static const struct bus_properties_map map[] = {
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "Timezone", "s", NULL, offsetof(StatusInfo, timezone) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "LocalRTC", "b", NULL, offsetof(StatusInfo, rtc_local) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "NTP", "b", NULL, offsetof(StatusInfo, ntp_enabled) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "CanNTP", "b", NULL, offsetof(StatusInfo, ntp_capable) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "NTPSynchronized", "b", NULL, offsetof(StatusInfo, ntp_synced) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "TimeUSec", "t", NULL, offsetof(StatusInfo, time) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering { "RTCTimeUSec", "t", NULL, offsetof(StatusInfo, rtc_time) },
1086182d83d4c02a75f96f0184d5e8e5d3af6528Lennart Poettering log_error_errno(r, "Failed to query server: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic int set_time(sd_bus *bus, char **args, unsigned n) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering bool relative = false, interactive = arg_ask_password;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Failed to parse time specification: %s", args[1]);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "xbb", (int64_t)t, relative, interactive);
34b9656f0b2890743eee6a746ef08d817abfd5e9Lennart Poettering log_error("Failed to set time: %s", bus_error_message(&error, -r));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic int set_timezone(sd_bus *bus, char **args, unsigned n) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering "SetTimezone",
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering log_error("Failed to set time zone: %s", bus_error_message(&error, -r));
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poetteringstatic int set_local_rtc(sd_bus *bus, char **args, unsigned n) {
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering log_error("Failed to parse local RTC setting: %s", args[1]);
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering "SetLocalRTC",
b914e211f3a40f507b3cdc572838ec7f3fd5e4cfLennart Poettering "bbb", b, arg_adjust_system_clock, arg_ask_password);
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
&error,
NULL,
static void help(void) {
help();
case ARG_VERSION:
case ARG_NO_ASK_PASSWORD:
arg_ask_password = false;
case ARG_ADJUST_SYSTEM_CLOCK:
arg_adjust_system_clock = true;
case ARG_NO_PAGER:
arg_no_pager = true;
return -EINVAL;
const char* verb;
MORE,
LESS,
} argc_cmp;
const int argc;
} verbs[] = {
int left;
if (left <= 0)
help();
return -EINVAL;
case EQUAL:
return -EINVAL;
case MORE:
return -EINVAL;
case LESS:
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();