timedatectl.c revision ab59f4123a6f9c32953e522cc9afc5fc610d59ca
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2012 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2013 Kay Sievers
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringstatic bool arg_no_pager = false;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringstatic bool arg_ask_password = true;
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mackstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mackstatic bool arg_adjust_system_clock = false;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringstatic void pager_open_if_enabled(void) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringstatic void polkit_agent_open_if_enabled(void) {
6f717d0817573a76c3e586eae02793d8b23a0581Lennart Poettering /* Open the polkit agent as a child process if necessary */
e0240c64b76ba8f0c9219feb23a5783f23100216Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringtypedef struct StatusInfo {
d15ad74251454d55b715958d8e6f50f45195904aLennart Poetteringstatic void status_info_clear(StatusInfo *info) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic void print_status_info(const StatusInfo *i) {
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering /* Save the old $TZ */
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering /* Set the new $TZ */
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering if (i->time != 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Could not get time from timedated and not operating locally, ignoring.");
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering printf(" Local time: %.*s\n", (int) sizeof(a), a);
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering printf(" Universal time: %.*s\n", (int) sizeof(a), a);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering printf(" RTC time: %.*s\n", (int) sizeof(a), a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Restore the $TZ */
c0eb11cfd016381fe02875a4ef29c1ade00c94e7Lennart Poettering log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " Network time on: %s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "NTP synchronized: %s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering " RTC in local TZ: %s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering "Warning: The system is configured to read the RTC time in the local time zone.\n"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering " This mode can not be fully supported. It will create various problems\n"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering " with time zone changes and daylight saving time adjustments. The RTC\n"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering " time is never updated, it relies on external facilities to maintain it.\n"
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek " If at all possible, use RTC in UTC by calling\n"
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek " 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmekstatic int show_status(sd_bus *bus, char **args, unsigned n) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek _cleanup_(status_info_clear) StatusInfo info = {};
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering static const struct bus_properties_map map[] = {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Timezone", "s", NULL, offsetof(StatusInfo, timezone) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "LocalRTC", "b", NULL, offsetof(StatusInfo, rtc_local) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "NTP", "b", NULL, offsetof(StatusInfo, ntp_enabled) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "CanNTP", "b", NULL, offsetof(StatusInfo, ntp_capable) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "NTPSynchronized", "b", NULL, offsetof(StatusInfo, ntp_synced) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "TimeUSec", "t", NULL, offsetof(StatusInfo, time) },
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "RTCTimeUSec", "t", NULL, offsetof(StatusInfo, rtc_time) },
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to query server: %m");
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmekstatic int set_time(sd_bus *bus, char **args, unsigned n) {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek bool relative = false, interactive = arg_ask_password;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek polkit_agent_open_if_enabled();
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek r = parse_timestamp(args[1], &t);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek log_error("Failed to parse time specification: %s", args[1]);
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering "xbb", (int64_t)t, relative, interactive);
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering log_error("Failed to set time: %s", bus_error_message(&error, -r));
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersenstatic int set_timezone(sd_bus *bus, char **args, unsigned n) {
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "SetTimezone",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Failed to set time zone: %s", bus_error_message(&error, -r));
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersenstatic int set_local_rtc(sd_bus *bus, char **args, unsigned n) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Failed to parse local RTC setting: %s", args[1]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SetLocalRTC",
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering "bbb", b, arg_adjust_system_clock, arg_ask_password);
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering log_error("Failed to set local RTC: %s", bus_error_message(&error, -r));
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poetteringstatic int set_ntp(sd_bus *bus, char **args, unsigned n) {
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
"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();