Bug Summary

File:build-scan/../src/timedate/timedated.c
Warning:line 75, column 17
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name timedated.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-timedated.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/timedate/timedated.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <errno(*__errno_location ()).h>
4#include <string.h>
5#include <unistd.h>
6
7#include "sd-bus.h"
8#include "sd-event.h"
9#include "sd-messages.h"
10
11#include "alloc-util.h"
12#include "bus-common-errors.h"
13#include "bus-error.h"
14#include "bus-util.h"
15#include "clock-util.h"
16#include "def.h"
17#include "fileio-label.h"
18#include "fs-util.h"
19#include "hashmap.h"
20#include "list.h"
21#include "path-util.h"
22#include "selinux-util.h"
23#include "string-util.h"
24#include "strv.h"
25#include "unit-def.h"
26#include "unit-name.h"
27#include "user-util.h"
28#include "util.h"
29
30#define NULL_ADJTIME_UTC"0.0 0 0\n0\nUTC\n" "0.0 0 0\n0\nUTC\n"
31#define NULL_ADJTIME_LOCAL"0.0 0 0\n0\nLOCAL\n" "0.0 0 0\n0\nLOCAL\n"
32
33typedef struct UnitStatusInfo {
34 char *name;
35 char *load_state;
36 char *unit_file_state;
37 char *active_state;
38
39 LIST_FIELDS(struct UnitStatusInfo, units)struct UnitStatusInfo *units_next, *units_prev;
40} UnitStatusInfo;
41
42typedef struct Context {
43 char *zone;
44 bool_Bool local_rtc;
45 Hashmap *polkit_registry;
46
47 LIST_HEAD(UnitStatusInfo, units)UnitStatusInfo *units;
48} Context;
49
50static void unit_status_info_clear(UnitStatusInfo *p) {
51 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/timedate/timedated.c", 51,
__PRETTY_FUNCTION__); } while (0)
;
52
53 p->load_state = mfree(p->load_state);
54 p->unit_file_state = mfree(p->unit_file_state);
55 p->active_state = mfree(p->active_state);
56}
57
58static void unit_status_info_free(UnitStatusInfo *p) {
59 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/timedate/timedated.c", 59,
__PRETTY_FUNCTION__); } while (0)
;
20
Taking false branch
21
Loop condition is false. Exiting loop
60
61 unit_status_info_clear(p);
62 free(p->name);
63 free(p);
22
Memory is released
64}
65
66static void context_free(Context *c) {
67 UnitStatusInfo *p;
68
69 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 69,
__PRETTY_FUNCTION__); } while (0)
;
9
Taking false branch
10
Loop condition is false. Exiting loop
70
71 free(c->zone);
72 bus_verify_polkit_async_registry_free(c->polkit_registry);
73
74 while ((p = c->units)) {
11
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
75 LIST_REMOVE(units, c->units, p)do { typeof(*(c->units)) **_head = &(c->units), *_item
= (p); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/timedate/timedated.c",
75, __PRETTY_FUNCTION__); } while (0); if (_item->units_next
) _item->units_next->units_prev = _item->units_prev;
if (_item->units_prev) _item->units_prev->units_next
= _item->units_next; else { do { if ((__builtin_expect(!!
(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/timedate/timedated.c", 75, __PRETTY_FUNCTION__
); } while (0); *_head = _item->units_next; } _item->units_next
= _item->units_prev = ((void*)0); } while (0)
;
12
Taking false branch
13
Loop condition is false. Exiting loop
14
Assuming field 'units_next' is null
15
Taking false branch
16
Assuming field 'units_prev' is non-null
17
Taking true branch
18
Loop condition is false. Exiting loop
25
Taking false branch
26
Loop condition is false. Exiting loop
27
Use of memory after it is freed
76 unit_status_info_free(p);
19
Calling 'unit_status_info_free'
23
Returning; memory was released via 1st parameter
77 }
78}
79
80static int context_add_ntp_service(Context *c, const char *s) {
81 UnitStatusInfo *u;
82
83 if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
84 return -EINVAL22;
85
86 /* Do not add this if it is already listed */
87 LIST_FOREACH(units, u, c->units)for ((u) = (c->units); (u); (u) = (u)->units_next)
88 if (streq(u->name, s)(strcmp((u->name),(s)) == 0))
89 return 0;
90
91 u = new0(UnitStatusInfo, 1)((UnitStatusInfo*) calloc((1), sizeof(UnitStatusInfo)));
92 if (!u)
93 return -ENOMEM12;
94
95 u->name = strdup(s);
96 if (!u->name) {
97 free(u);
98 return -ENOMEM12;
99 }
100
101 LIST_APPEND(units, c->units, u)do { typeof(*(c->units)) *_tail; do { typeof(*(c->units
)) *_item = (c->units); if (!_item) (_tail) = ((void*)0); else
{ while (_item->units_next) _item = _item->units_next;
(_tail) = _item; } } while (0); do { typeof(*(c->units)) *
*_head = &(c->units), *_a = (_tail), *_b = (u); do { if
((__builtin_expect(!!(!(_b)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("_b"), "../src/timedate/timedated.c", 101, __PRETTY_FUNCTION__
); } while (0); if (!_a) { if ((_b->units_next = *_head)) _b
->units_next->units_prev = _b; _b->units_prev = ((void
*)0); *_head = _b; } else { if ((_b->units_next = _a->units_next
)) _b->units_next->units_prev = _b; _b->units_prev =
_a; _a->units_next = _b; } } while (0); } while (0)
;
102
103 return 0;
104}
105
106static int context_parse_ntp_services(Context *c) {
107 const char *env, *p;
108 int r;
109
110 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 110
, __PRETTY_FUNCTION__); } while (0)
;
111
112 env = getenv("SYSTEMD_TIMEDATED_NTP_SERVICES");
113 if (!env) {
114 r = context_add_ntp_service(c, "systemd-timesyncd.service");
115 if (r < 0)
116 log_warning_errno(r, "Failed to add NTP service \"systemd-timesyncd.service\", ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 116, __func__, "Failed to add NTP service \"systemd-timesyncd.service\", ignoring: %m"
) : -abs(_e); })
;
117
118 return 0;
119 }
120
121 for (p = env;;) {
122 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
123
124 r = extract_first_word(&p, &word, ":", 0);
125 if (r == 0)
126 break;
127 if (r == -ENOMEM12)
128 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/timedate/timedated.c"
, 128, __func__)
;
129 if (r < 0) {
130 log_error("Invalid syntax, ignoring: %s", env)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 130, __func__, "Invalid syntax, ignoring: %s"
, env) : -abs(_e); })
;
131 break;
132 }
133
134 r = context_add_ntp_service(c, word);
135 if (r < 0)
136 log_warning_errno(r, "Failed to add NTP service \"%s\", ignoring: %m", word)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 136, __func__, "Failed to add NTP service \"%s\", ignoring: %m"
, word) : -abs(_e); })
;
137 }
138
139 return 0;
140}
141
142static int context_ntp_service_is_active(Context *c) {
143 UnitStatusInfo *info;
144 int count = 0;
145
146 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 146
, __PRETTY_FUNCTION__); } while (0)
;
147
148 /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */
149
150 LIST_FOREACH(units, info, c->units)for ((info) = (c->units); (info); (info) = (info)->units_next
)
151 count += streq_ptr(info->active_state, "active");
152
153 return count;
154}
155
156static int context_ntp_service_is_enabled(Context *c) {
157 UnitStatusInfo *info;
158 int count = 0;
159
160 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 160
, __PRETTY_FUNCTION__); } while (0)
;
161
162 /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */
163
164 LIST_FOREACH(units, info, c->units)for ((info) = (c->units); (info); (info) = (info)->units_next
)
165 count += STRPTR_IN_SET(info->unit_file_state, "enabled", "enabled-runtime")({ const char* _x = (info->unit_file_state); _x &&
(!!strv_find((((char**) ((const char*[]) { "enabled", "enabled-runtime"
, ((void*)0) }))), (_x))); })
;
166
167 return count;
168}
169
170static int context_ntp_service_exists(Context *c) {
171 UnitStatusInfo *info;
172 int count = 0;
173
174 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 174
, __PRETTY_FUNCTION__); } while (0)
;
175
176 /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */
177
178 LIST_FOREACH(units, info, c->units)for ((info) = (c->units); (info); (info) = (info)->units_next
)
179 count += streq_ptr(info->load_state, "loaded");
180
181 return count;
182}
183
184static int context_read_data(Context *c) {
185 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
186 int r;
187
188 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 188
, __PRETTY_FUNCTION__); } while (0)
;
189
190 r = get_timezone(&t);
191 if (r == -EINVAL22)
192 log_warning_errno(r, "/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 192, __func__, "/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/."
) : -abs(_e); })
;
193 else if (r < 0)
194 log_warning_errno(r, "Failed to get target of /etc/localtime: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 194, __func__, "Failed to get target of /etc/localtime: %m"
) : -abs(_e); })
;
195
196 free_and_replace(c->zone, t)({ free(c->zone); (c->zone) = (t); (t) = ((void*)0); 0;
})
;
197
198 c->local_rtc = clock_is_localtime(NULL((void*)0)) > 0;
199
200 return 0;
201}
202
203static int context_write_data_timezone(Context *c) {
204 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0);
205 int r = 0;
206
207 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 207
, __PRETTY_FUNCTION__); } while (0)
;
208
209 if (isempty(c->zone)) {
210 if (unlink("/etc/localtime") < 0 && errno(*__errno_location ()) != ENOENT2)
211 r = -errno(*__errno_location ());
212
213 return r;
214 }
215
216 p = strappend("../usr/share/zoneinfo/", c->zone);
217 if (!p)
218 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/timedate/timedated.c"
, 218, __func__)
;
219
220 r = symlink_atomic(p, "/etc/localtime");
221 if (r < 0)
222 return r;
223
224 return 0;
225}
226
227static int context_write_data_local_rtc(Context *c) {
228 int r;
229 _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0), *w = NULL((void*)0);
230
231 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 231
, __PRETTY_FUNCTION__); } while (0)
;
232
233 r = read_full_file("/etc/adjtime", &s, NULL((void*)0));
234 if (r < 0) {
235 if (r != -ENOENT2)
236 return r;
237
238 if (!c->local_rtc)
239 return 0;
240
241 w = strdup(NULL_ADJTIME_LOCAL"0.0 0 0\n0\nLOCAL\n");
242 if (!w)
243 return -ENOMEM12;
244 } else {
245 char *p;
246 const char *e = "\n"; /* default if there is less than 3 lines */
247 const char *prepend = "";
248 size_t a, b;
249
250 p = strchrnul(s, '\n');
251 if (*p == '\0')
252 /* only one line, no \n terminator */
253 prepend = "\n0\n";
254 else if (p[1] == '\0') {
255 /* only one line, with \n terminator */
256 ++p;
257 prepend = "0\n";
258 } else {
259 p = strchr(p+1, '\n');
260 if (!p) {
261 /* only two lines, no \n terminator */
262 prepend = "\n";
263 p = s + strlen(s);
264 } else {
265 char *end;
266 /* third line might have a \n terminator or not */
267 p++;
268 end = strchr(p, '\n');
269 /* if we actually have a fourth line, use that as suffix "e", otherwise the default \n */
270 if (end)
271 e = end;
272 }
273 }
274
275 a = p - s;
276 b = strlen(e);
277
278 w = new(char, a + (c->local_rtc ? 5 : 3) + strlen(prepend) + b + 1)((char*) malloc_multiply(sizeof(char), (a + (c->local_rtc ?
5 : 3) + strlen(prepend) + b + 1)))
;
279 if (!w)
280 return -ENOMEM12;
281
282 *(char*) mempcpy(stpcpy(stpcpy(mempcpy(w, s, a), prepend), c->local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
283
284 if (streq(w, NULL_ADJTIME_UTC)(strcmp((w),("0.0 0 0\n0\nUTC\n")) == 0)) {
285 if (unlink("/etc/adjtime") < 0)
286 if (errno(*__errno_location ()) != ENOENT2)
287 return -errno(*__errno_location ());
288
289 return 0;
290 }
291 }
292
293 mac_selinux_init();
294 return write_string_file_atomic_label("/etc/adjtime", w);
295}
296
297static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {
298 static const struct bus_properties_map map[] = {
299 { "LoadState", "s", NULL((void*)0), offsetof(UnitStatusInfo, load_state)__builtin_offsetof(UnitStatusInfo, load_state) },
300 { "ActiveState", "s", NULL((void*)0), offsetof(UnitStatusInfo, active_state)__builtin_offsetof(UnitStatusInfo, active_state) },
301 { "UnitFileState", "s", NULL((void*)0), offsetof(UnitStatusInfo, unit_file_state)__builtin_offsetof(UnitStatusInfo, unit_file_state) },
302 {}
303 };
304 static sd_bus_message *_m = NULL((void*)0);
305 UnitStatusInfo *u;
306 int r;
307
308 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 308
, __PRETTY_FUNCTION__); } while (0)
;
309 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 309
, __PRETTY_FUNCTION__); } while (0)
;
310
311 /* Suppress multiple call of context_update_ntp_status() within single DBus transaction. */
312 if (m && m == _m)
313 return 0;
314
315 _m = m;
316
317 LIST_FOREACH(units, u, c->units)for ((u) = (c->units); (u); (u) = (u)->units_next) {
318 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
319 _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0);
320
321 unit_status_info_clear(u);
322
323 path = unit_dbus_path_from_name(u->name);
324 if (!path)
325 return -ENOMEM12;
326
327 r = bus_map_all_properties(
328 bus,
329 "org.freedesktop.systemd1",
330 path,
331 map,
332 BUS_MAP_STRDUP,
333 &error,
334 NULL((void*)0),
335 u);
336 if (r < 0)
337 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 337, __func__, "Failed to get properties: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
338 }
339
340 return 0;
341}
342
343static int unit_start_or_stop(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool_Bool start) {
344 int r;
345
346 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/timedate/timedated.c", 346
, __PRETTY_FUNCTION__); } while (0)
;
347 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 347
, __PRETTY_FUNCTION__); } while (0)
;
348 assert(error)do { if ((__builtin_expect(!!(!(error)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("error"), "../src/timedate/timedated.c",
348, __PRETTY_FUNCTION__); } while (0)
;
349
350 /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */
351
352 if (streq(u->active_state, "active")(strcmp((u->active_state),("active")) == 0) == start)
353 return 0;
354
355 r = sd_bus_call_method(
356 bus,
357 "org.freedesktop.systemd1",
358 "/org/freedesktop/systemd1",
359 "org.freedesktop.systemd1.Manager",
360 start ? "StartUnit" : "StopUnit",
361 error,
362 NULL((void*)0),
363 "ss",
364 u->name,
365 "replace");
366 if (r < 0)
367 return r;
368
369 return 0;
370}
371
372static int unit_enable_or_disable(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *error, bool_Bool enable) {
373 int r;
374
375 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/timedate/timedated.c", 375
, __PRETTY_FUNCTION__); } while (0)
;
376 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 376
, __PRETTY_FUNCTION__); } while (0)
;
377 assert(error)do { if ((__builtin_expect(!!(!(error)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("error"), "../src/timedate/timedated.c",
377, __PRETTY_FUNCTION__); } while (0)
;
378
379 /* Call context_update_ntp_status() to update UnitStatusInfo before calling this. */
380
381 if (streq(u->unit_file_state, "enabled")(strcmp((u->unit_file_state),("enabled")) == 0) == enable)
382 return 0;
383
384 if (enable)
385 r = sd_bus_call_method(
386 bus,
387 "org.freedesktop.systemd1",
388 "/org/freedesktop/systemd1",
389 "org.freedesktop.systemd1.Manager",
390 "EnableUnitFiles",
391 error,
392 NULL((void*)0),
393 "asbb", 1,
394 u->name,
395 false0, true1);
396 else
397 r = sd_bus_call_method(
398 bus,
399 "org.freedesktop.systemd1",
400 "/org/freedesktop/systemd1",
401 "org.freedesktop.systemd1.Manager",
402 "DisableUnitFiles",
403 error,
404 NULL((void*)0),
405 "asb", 1,
406 u->name,
407 false0);
408 if (r < 0)
409 return r;
410
411 r = sd_bus_call_method(
412 bus,
413 "org.freedesktop.systemd1",
414 "/org/freedesktop/systemd1",
415 "org.freedesktop.systemd1.Manager",
416 "Reload",
417 error,
418 NULL((void*)0),
419 NULL((void*)0));
420 if (r < 0)
421 return r;
422 return 0;
423}
424
425static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_time, "t", now(CLOCK_REALTIME))int property_get_time(sd_bus *bus, const char *path, const char
*interface, const char *property, sd_bus_message *reply, void
*userdata, sd_bus_error *error) { do { if ((__builtin_expect
(!!(!(bus)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"bus"), "../src/timedate/timedated.c", 425, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/timedate/timedated.c",
425, __PRETTY_FUNCTION__); } while (0); return sd_bus_message_append
(reply, "t", now(0)); }
;
426static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_ntp_sync, "b", ntp_synced())int property_get_ntp_sync(sd_bus *bus, const char *path, const
char *interface, const char *property, sd_bus_message *reply
, void *userdata, sd_bus_error *error) { do { if ((__builtin_expect
(!!(!(bus)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"bus"), "../src/timedate/timedated.c", 426, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/timedate/timedated.c",
426, __PRETTY_FUNCTION__); } while (0); return sd_bus_message_append
(reply, "b", ntp_synced()); }
;
427
428static int property_get_rtc_time(
429 sd_bus *bus,
430 const char *path,
431 const char *interface,
432 const char *property,
433 sd_bus_message *reply,
434 void *userdata,
435 sd_bus_error *error) {
436
437 struct tm tm;
438 usec_t t;
439 int r;
440
441 zero(tm)(({ size_t _l_ = (sizeof(tm)); void *_x_ = (&(tm)); _l_ ==
0 ? _x_ : memset(_x_, 0, _l_); }))
;
442 r = clock_get_hwclock(&tm);
443 if (r == -EBUSY16) {
444 log_warning("/dev/rtc is busy. Is somebody keeping it open continuously? That's not a good idea... Returning a bogus RTC timestamp.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 444, __func__, "/dev/rtc is busy. Is somebody keeping it open continuously? That's not a good idea... Returning a bogus RTC timestamp."
) : -abs(_e); })
;
445 t = 0;
446 } else if (r == -ENOENT2) {
447 log_debug("/dev/rtc not found.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 447, __func__, "/dev/rtc not found."
) : -abs(_e); })
;
448 t = 0; /* no RTC found */
449 } else if (r < 0)
450 return sd_bus_error_set_errnof(error, r, "Failed to read RTC: %m");
451 else
452 t = (usec_t) timegm(&tm) * USEC_PER_SEC((usec_t) 1000000ULL);
453
454 return sd_bus_message_append(reply, "t", t);
455}
456
457static int property_get_can_ntp(
458 sd_bus *bus,
459 const char *path,
460 const char *interface,
461 const char *property,
462 sd_bus_message *reply,
463 void *userdata,
464 sd_bus_error *error) {
465
466 Context *c = userdata;
467 int r;
468
469 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 469
, __PRETTY_FUNCTION__); } while (0)
;
470 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 470
, __PRETTY_FUNCTION__); } while (0)
;
471 assert(property)do { if ((__builtin_expect(!!(!(property)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("property"), "../src/timedate/timedated.c"
, 471, __PRETTY_FUNCTION__); } while (0)
;
472 assert(reply)do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/timedate/timedated.c",
472, __PRETTY_FUNCTION__); } while (0)
;
473 assert(error)do { if ((__builtin_expect(!!(!(error)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("error"), "../src/timedate/timedated.c",
473, __PRETTY_FUNCTION__); } while (0)
;
474
475 r = context_update_ntp_status(c, bus, reply);
476 if (r < 0)
477 return r;
478
479 return sd_bus_message_append(reply, "b", context_ntp_service_exists(c) > 0);
480}
481
482static int property_get_ntp(
483 sd_bus *bus,
484 const char *path,
485 const char *interface,
486 const char *property,
487 sd_bus_message *reply,
488 void *userdata,
489 sd_bus_error *error) {
490
491 Context *c = userdata;
492 int r;
493
494 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 494
, __PRETTY_FUNCTION__); } while (0)
;
495 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 495
, __PRETTY_FUNCTION__); } while (0)
;
496 assert(property)do { if ((__builtin_expect(!!(!(property)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("property"), "../src/timedate/timedated.c"
, 496, __PRETTY_FUNCTION__); } while (0)
;
497 assert(reply)do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/timedate/timedated.c",
497, __PRETTY_FUNCTION__); } while (0)
;
498 assert(error)do { if ((__builtin_expect(!!(!(error)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("error"), "../src/timedate/timedated.c",
498, __PRETTY_FUNCTION__); } while (0)
;
499
500 r = context_update_ntp_status(c, bus, reply);
501 if (r < 0)
502 return r;
503
504 return sd_bus_message_append(reply, "b", context_ntp_service_is_active(c) > 0);
505}
506
507static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *error) {
508 Context *c = userdata;
509 int interactive, r;
510 const char *z;
511
512 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/timedate/timedated.c", 512
, __PRETTY_FUNCTION__); } while (0)
;
513 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 513
, __PRETTY_FUNCTION__); } while (0)
;
514
515 r = sd_bus_message_read(m, "sb", &z, &interactive);
516 if (r < 0)
517 return r;
518
519 if (!timezone_is_valid(z, LOG_DEBUG7))
520 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Invalid time zone '%s'", z);
521
522 if (streq_ptr(z, c->zone))
523 return sd_bus_reply_method_return(m, NULL((void*)0));
524
525 r = bus_verify_polkit_async(
526 m,
527 CAP_SYS_TIME25,
528 "org.freedesktop.timedate1.set-timezone",
529 NULL((void*)0),
530 interactive,
531 UID_INVALID((uid_t) -1),
532 &c->polkit_registry,
533 error);
534 if (r < 0)
535 return r;
536 if (r == 0)
537 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
538
539 r = free_and_strdup(&c->zone, z);
540 if (r < 0)
541 return r;
542
543 /* 1. Write new configuration file */
544 r = context_write_data_timezone(c);
545 if (r < 0) {
546 log_error_errno(r, "Failed to set time zone: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 546, __func__, "Failed to set time zone: %m"
) : -abs(_e); })
;
547 return sd_bus_error_set_errnof(error, r, "Failed to set time zone: %m");
548 }
549
550 /* 2. Make glibc notice the new timezone */
551 tzset();
552
553 /* 3. Tell the kernel our timezone */
554 r = clock_set_timezone(NULL((void*)0));
555 if (r < 0)
556 log_debug_errno(r, "Failed to tell kernel about timezone, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 556, __func__, "Failed to tell kernel about timezone, ignoring: %m"
) : -abs(_e); })
;
557
558 if (c->local_rtc) {
559 struct timespec ts;
560 struct tm *tm;
561
562 /* 4. Sync RTC from system clock, with the new delta */
563 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0)do { if ((__builtin_expect(!!(!(clock_gettime(0, &ts) == 0
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("clock_gettime(CLOCK_REALTIME, &ts) == 0"
), "../src/timedate/timedated.c", 563, __PRETTY_FUNCTION__); }
while (0)
;
564 assert_se(tm = localtime(&ts.tv_sec))do { if ((__builtin_expect(!!(!(tm = localtime(&ts.tv_sec
))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("tm = localtime(&ts.tv_sec)"
), "../src/timedate/timedated.c", 564, __PRETTY_FUNCTION__); }
while (0)
;
565
566 r = clock_set_hwclock(tm);
567 if (r < 0)
568 log_debug_errno(r, "Failed to sync time to hardware clock, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 568, __func__, "Failed to sync time to hardware clock, ignoring: %m"
) : -abs(_e); })
;
569 }
570
571 log_struct(LOG_INFO,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
572 "MESSAGE_ID=" SD_MESSAGE_TIMEZONE_CHANGE_STR,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
573 "TIMEZONE=%s", c->zone,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
574 "TIMEZONE_SHORTNAME=%s", tzname[daylight],log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
575 "DAYLIGHT=%i", daylight,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
576 LOG_MESSAGE("Changed time zone to '%s' (%s).", c->zone, tzname[daylight]))log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 576, __func__, "MESSAGE_ID="
"45" "f8" "2f" "4a" "ef" "7a" "4b" "bf" "94" "2c" "e8" "61" "d1"
"f2" "09" "90", "TIMEZONE=%s", c->zone, "TIMEZONE_SHORTNAME=%s"
, tzname[daylight], "DAYLIGHT=%i", daylight, "MESSAGE=" "Changed time zone to '%s' (%s)."
, c->zone, tzname[daylight], ((void*)0))
;
577
578 (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "Timezone", NULL((void*)0));
579
580 return sd_bus_reply_method_return(m, NULL((void*)0));
581}
582
583static int method_set_local_rtc(sd_bus_message *m, void *userdata, sd_bus_error *error) {
584 int lrtc, fix_system, interactive;
585 Context *c = userdata;
586 struct timespec ts;
587 int r;
588
589 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/timedate/timedated.c", 589
, __PRETTY_FUNCTION__); } while (0)
;
590 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 590
, __PRETTY_FUNCTION__); } while (0)
;
591
592 r = sd_bus_message_read(m, "bbb", &lrtc, &fix_system, &interactive);
593 if (r < 0)
594 return r;
595
596 if (lrtc == c->local_rtc)
597 return sd_bus_reply_method_return(m, NULL((void*)0));
598
599 r = bus_verify_polkit_async(
600 m,
601 CAP_SYS_TIME25,
602 "org.freedesktop.timedate1.set-local-rtc",
603 NULL((void*)0),
604 interactive,
605 UID_INVALID((uid_t) -1),
606 &c->polkit_registry,
607 error);
608 if (r < 0)
609 return r;
610 if (r == 0)
611 return 1;
612
613 c->local_rtc = lrtc;
614
615 /* 1. Write new configuration file */
616 r = context_write_data_local_rtc(c);
617 if (r < 0) {
618 log_error_errno(r, "Failed to set RTC to local/UTC: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 618, __func__, "Failed to set RTC to local/UTC: %m"
) : -abs(_e); })
;
619 return sd_bus_error_set_errnof(error, r, "Failed to set RTC to local/UTC: %m");
620 }
621
622 /* 2. Tell the kernel our timezone */
623 r = clock_set_timezone(NULL((void*)0));
624 if (r < 0)
625 log_debug_errno(r, "Failed to tell kernel about timezone, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 625, __func__, "Failed to tell kernel about timezone, ignoring: %m"
) : -abs(_e); })
;
626
627 /* 3. Synchronize clocks */
628 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0)do { if ((__builtin_expect(!!(!(clock_gettime(0, &ts) == 0
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("clock_gettime(CLOCK_REALTIME, &ts) == 0"
), "../src/timedate/timedated.c", 628, __PRETTY_FUNCTION__); }
while (0)
;
629
630 if (fix_system) {
631 struct tm tm;
632
633 /* Sync system clock from RTC; first, initialize the timezone fields of struct tm. */
634 if (c->local_rtc)
635 tm = *localtime(&ts.tv_sec);
636 else
637 tm = *gmtime(&ts.tv_sec);
638
639 /* Override the main fields of struct tm, but not the timezone fields */
640 r = clock_get_hwclock(&tm);
641 if (r < 0)
642 log_debug_errno(r, "Failed to get hardware clock, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 642, __func__, "Failed to get hardware clock, ignoring: %m"
) : -abs(_e); })
;
643 else {
644 /* And set the system clock with this */
645 if (c->local_rtc)
646 ts.tv_sec = mktime(&tm);
647 else
648 ts.tv_sec = timegm(&tm);
649
650 if (clock_settime(CLOCK_REALTIME0, &ts) < 0)
651 log_debug_errno(errno, "Failed to update system clock, ignoring: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/timedate/timedated.c", 651, __func__
, "Failed to update system clock, ignoring: %m") : -abs(_e); }
)
;
652 }
653
654 } else {
655 struct tm *tm;
656
657 /* Sync RTC from system clock */
658 if (c->local_rtc)
659 tm = localtime(&ts.tv_sec);
660 else
661 tm = gmtime(&ts.tv_sec);
662
663 r = clock_set_hwclock(tm);
664 if (r < 0)
665 log_debug_errno(r, "Failed to sync time to hardware clock, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 665, __func__, "Failed to sync time to hardware clock, ignoring: %m"
) : -abs(_e); })
;
666 }
667
668 log_info("RTC configured to %s time.", c->local_rtc ? "local" : "UTC")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 668, __func__, "RTC configured to %s time."
, c->local_rtc ? "local" : "UTC") : -abs(_e); })
;
669
670 (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "LocalRTC", NULL((void*)0));
671
672 return sd_bus_reply_method_return(m, NULL((void*)0));
673}
674
675static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *error) {
676 sd_bus *bus = sd_bus_message_get_bus(m);
677 int relative, interactive, r;
678 Context *c = userdata;
679 int64_t utc;
680 struct timespec ts;
681 usec_t start;
682 struct tm* tm;
683
684 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/timedate/timedated.c", 684
, __PRETTY_FUNCTION__); } while (0)
;
685 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 685
, __PRETTY_FUNCTION__); } while (0)
;
686
687 r = context_update_ntp_status(c, bus, m);
688 if (r < 0)
689 return sd_bus_error_set_errnof(error, r, "Failed to update context: %m");
690
691 if (context_ntp_service_is_active(c) > 0)
692 return sd_bus_error_set(error, BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED"org.freedesktop.timedate1.AutomaticTimeSyncEnabled", "Automatic time synchronization is enabled");
693
694 /* this only gets used if dbus does not provide a timestamp */
695 start = now(CLOCK_MONOTONIC1);
696
697 r = sd_bus_message_read(m, "xbb", &utc, &relative, &interactive);
698 if (r < 0)
699 return r;
700
701 if (!relative && utc <= 0)
702 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Invalid absolute time");
703
704 if (relative && utc == 0)
705 return sd_bus_reply_method_return(m, NULL((void*)0));
706
707 if (relative) {
708 usec_t n, x;
709
710 n = now(CLOCK_REALTIME0);
711 x = n + utc;
712
713 if ((utc > 0 && x < n) ||
714 (utc < 0 && x > n))
715 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Time value overflow");
716
717 timespec_store(&ts, x);
718 } else
719 timespec_store(&ts, (usec_t) utc);
720
721 r = bus_verify_polkit_async(
722 m,
723 CAP_SYS_TIME25,
724 "org.freedesktop.timedate1.set-time",
725 NULL((void*)0),
726 interactive,
727 UID_INVALID((uid_t) -1),
728 &c->polkit_registry,
729 error);
730 if (r < 0)
731 return r;
732 if (r == 0)
733 return 1;
734
735 /* adjust ts for time spent in program */
736 r = sd_bus_message_get_monotonic_usec(m, &start);
737 /* when sd_bus_message_get_monotonic_usec() returns -ENODATA it does not modify &start */
738 if (r < 0 && r != -ENODATA61)
739 return r;
740
741 timespec_store(&ts, timespec_load(&ts) + (now(CLOCK_MONOTONIC1) - start));
742
743 /* Set system clock */
744 if (clock_settime(CLOCK_REALTIME0, &ts) < 0) {
745 log_error_errno(errno, "Failed to set local time: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/timedate/timedated.c", 745, __func__
, "Failed to set local time: %m") : -abs(_e); })
;
746 return sd_bus_error_set_errnof(error, errno(*__errno_location ()), "Failed to set local time: %m");
747 }
748
749 /* Sync down to RTC */
750 if (c->local_rtc)
751 tm = localtime(&ts.tv_sec);
752 else
753 tm = gmtime(&ts.tv_sec);
754
755 r = clock_set_hwclock(tm);
756 if (r < 0)
757 log_debug_errno(r, "Failed to update hardware clock, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 757, __func__, "Failed to update hardware clock, ignoring: %m"
) : -abs(_e); })
;
758
759 log_struct(LOG_INFO,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 762, __func__, "MESSAGE_ID="
"c7" "a7" "87" "07" "9b" "35" "4e" "aa" "a9" "e7" "7b" "37" "18"
"93" "cd" "27", "REALTIME=""%" "l" "u", timespec_load(&ts
), "MESSAGE=" "Changed local time to %s", ctime(&ts.tv_sec
), ((void*)0))
760 "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 762, __func__, "MESSAGE_ID="
"c7" "a7" "87" "07" "9b" "35" "4e" "aa" "a9" "e7" "7b" "37" "18"
"93" "cd" "27", "REALTIME=""%" "l" "u", timespec_load(&ts
), "MESSAGE=" "Changed local time to %s", ctime(&ts.tv_sec
), ((void*)0))
761 "REALTIME="USEC_FMT, timespec_load(&ts),log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 762, __func__, "MESSAGE_ID="
"c7" "a7" "87" "07" "9b" "35" "4e" "aa" "a9" "e7" "7b" "37" "18"
"93" "cd" "27", "REALTIME=""%" "l" "u", timespec_load(&ts
), "MESSAGE=" "Changed local time to %s", ctime(&ts.tv_sec
), ((void*)0))
762 LOG_MESSAGE("Changed local time to %s", ctime(&ts.tv_sec)))log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0
, "../src/timedate/timedated.c", 762, __func__, "MESSAGE_ID="
"c7" "a7" "87" "07" "9b" "35" "4e" "aa" "a9" "e7" "7b" "37" "18"
"93" "cd" "27", "REALTIME=""%" "l" "u", timespec_load(&ts
), "MESSAGE=" "Changed local time to %s", ctime(&ts.tv_sec
), ((void*)0))
;
763
764 return sd_bus_reply_method_return(m, NULL((void*)0));
765}
766
767static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error) {
768 sd_bus *bus = sd_bus_message_get_bus(m);
769 Context *c = userdata;
770 UnitStatusInfo *u;
771 int enable, interactive, q, r;
772
773 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/timedate/timedated.c", 773
, __PRETTY_FUNCTION__); } while (0)
;
774 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/timedate/timedated.c", 774
, __PRETTY_FUNCTION__); } while (0)
;
775 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 775
, __PRETTY_FUNCTION__); } while (0)
;
776
777 r = sd_bus_message_read(m, "bb", &enable, &interactive);
778 if (r < 0)
779 return r;
780
781 r = context_update_ntp_status(c, bus, m);
782 if (r < 0)
783 return r;
784
785 if (context_ntp_service_exists(c) <= 0)
786 return sd_bus_error_set(error, BUS_ERROR_NO_NTP_SUPPORT"org.freedesktop.timedate1.NoNTPSupport", "NTP not supported");
787
788 r = bus_verify_polkit_async(
789 m,
790 CAP_SYS_TIME25,
791 "org.freedesktop.timedate1.set-ntp",
792 NULL((void*)0),
793 interactive,
794 UID_INVALID((uid_t) -1),
795 &c->polkit_registry,
796 error);
797 if (r < 0)
798 return r;
799 if (r == 0)
800 return 1;
801
802 if (!enable)
803 LIST_FOREACH(units, u, c->units)for ((u) = (c->units); (u); (u) = (u)->units_next) {
804 if (!streq(u->load_state, "loaded")(strcmp((u->load_state),("loaded")) == 0))
805 continue;
806
807 q = unit_enable_or_disable(u, bus, error, enable);
808 if (q < 0)
809 r = q;
810
811 q = unit_start_or_stop(u, bus, error, enable);
812 if (q < 0)
813 r = q;
814 }
815
816 else if (context_ntp_service_is_enabled(c) <= 0)
817 LIST_FOREACH(units, u, c->units)for ((u) = (c->units); (u); (u) = (u)->units_next) {
818 if (!streq(u->load_state, "loaded")(strcmp((u->load_state),("loaded")) == 0))
819 continue;
820
821 r = unit_enable_or_disable(u, bus, error, enable);
822 if (r < 0)
823 continue;
824
825 r = unit_start_or_stop(u, bus, error, enable);
826 break;
827 }
828
829 else if (context_ntp_service_is_active(c) <= 0)
830 LIST_FOREACH(units, u, c->units)for ((u) = (c->units); (u); (u) = (u)->units_next) {
831 if (!streq(u->load_state, "loaded")(strcmp((u->load_state),("loaded")) == 0) ||
832 !streq(u->unit_file_state, "enabled")(strcmp((u->unit_file_state),("enabled")) == 0))
833 continue;
834
835 r = unit_start_or_stop(u, bus, error, enable);
836 break;
837 }
838
839 if (r < 0)
840 return r;
841
842 log_info("Set NTP to %sd", enable_disable(enable))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 842, __func__, "Set NTP to %sd"
, enable_disable(enable)) : -abs(_e); })
;
843
844 (void) sd_bus_emit_properties_changed(bus, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL((void*)0));
845
846 return sd_bus_reply_method_return(m, NULL((void*)0));
847}
848
849static const sd_bus_vtable timedate_vtable[] = {
850 SD_BUS_VTABLE_START(0){ .type = _SD_BUS_VTABLE_START, .flags = 0, .x = { .start = {
.element_size = sizeof(sd_bus_vtable) }, }, }
,
851 SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
, .x = { .property = { .member = "Timezone", .signature = "s"
, .get = ((void*)0), .set = ((void*)0), .offset = __builtin_offsetof
(Context, zone), }, }, }
,
852 SD_BUS_PROPERTY("LocalRTC", "b", bus_property_get_bool, offsetof(Context, local_rtc), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
, .x = { .property = { .member = "LocalRTC", .signature = "b"
, .get = bus_property_get_bool, .set = ((void*)0), .offset = __builtin_offsetof
(Context, local_rtc), }, }, }
,
853 SD_BUS_PROPERTY("CanNTP", "b", property_get_can_ntp, 0, 0){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = 0, .x = { .property
= { .member = "CanNTP", .signature = "b", .get = property_get_can_ntp
, .set = ((void*)0), .offset = 0, }, }, }
,
854 SD_BUS_PROPERTY("NTP", "b", property_get_ntp, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
, .x = { .property = { .member = "NTP", .signature = "b", .get
= property_get_ntp, .set = ((void*)0), .offset = 0, }, }, }
,
855 SD_BUS_PROPERTY("NTPSynchronized", "b", property_get_ntp_sync, 0, 0){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = 0, .x = { .property
= { .member = "NTPSynchronized", .signature = "b", .get = property_get_ntp_sync
, .set = ((void*)0), .offset = 0, }, }, }
,
856 SD_BUS_PROPERTY("TimeUSec", "t", property_get_time, 0, 0){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = 0, .x = { .property
= { .member = "TimeUSec", .signature = "t", .get = property_get_time
, .set = ((void*)0), .offset = 0, }, }, }
,
857 SD_BUS_PROPERTY("RTCTimeUSec", "t", property_get_rtc_time, 0, 0){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = 0, .x = { .property
= { .member = "RTCTimeUSec", .signature = "t", .get = property_get_rtc_time
, .set = ((void*)0), .offset = 0, }, }, }
,
858 SD_BUS_METHOD("SetTime", "xbb", NULL, method_set_time, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "SetTime", .signature = "xbb",
.result = ((void*)0), .handler = method_set_time, .offset = 0
, }, }, }
,
859 SD_BUS_METHOD("SetTimezone", "sb", NULL, method_set_timezone, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "SetTimezone", .signature = "sb"
, .result = ((void*)0), .handler = method_set_timezone, .offset
= 0, }, }, }
,
860 SD_BUS_METHOD("SetLocalRTC", "bbb", NULL, method_set_local_rtc, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "SetLocalRTC", .signature = "bbb"
, .result = ((void*)0), .handler = method_set_local_rtc, .offset
= 0, }, }, }
,
861 SD_BUS_METHOD("SetNTP", "bb", NULL, method_set_ntp, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "SetNTP", .signature = "bb", .
result = ((void*)0), .handler = method_set_ntp, .offset = 0, }
, }, }
,
862 SD_BUS_VTABLE_END{ .type = _SD_BUS_VTABLE_END, .flags = 0, .x = { { 0 } }, },
863};
864
865static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
866 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
867 int r;
868
869 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/timedate/timedated.c", 869
, __PRETTY_FUNCTION__); } while (0)
;
870 assert(event)do { if ((__builtin_expect(!!(!(event)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("event"), "../src/timedate/timedated.c",
870, __PRETTY_FUNCTION__); } while (0)
;
871 assert(_bus)do { if ((__builtin_expect(!!(!(_bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_bus"), "../src/timedate/timedated.c", 871
, __PRETTY_FUNCTION__); } while (0)
;
872
873 r = sd_bus_default_system(&bus);
874 if (r < 0)
875 return log_error_errno(r, "Failed to get system bus connection: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 875, __func__, "Failed to get system bus connection: %m"
) : -abs(_e); })
;
876
877 r = sd_bus_add_object_vtable(bus, NULL((void*)0), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c);
878 if (r < 0)
879 return log_error_errno(r, "Failed to register object: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 879, __func__, "Failed to register object: %m"
) : -abs(_e); })
;
880
881 r = sd_bus_request_name_async(bus, NULL((void*)0), "org.freedesktop.timedate1", 0, NULL((void*)0), NULL((void*)0));
882 if (r < 0)
883 return log_error_errno(r, "Failed to request name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 883, __func__, "Failed to request name: %m"
) : -abs(_e); })
;
884
885 r = sd_bus_attach_event(bus, event, 0);
886 if (r < 0)
887 return log_error_errno(r, "Failed to attach bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 887, __func__, "Failed to attach bus to event loop: %m"
) : -abs(_e); })
;
888
889 *_bus = TAKE_PTR(bus)({ typeof(bus) _ptr_ = (bus); (bus) = ((void*)0); _ptr_; });
890
891 return 0;
892}
893
894int main(int argc, char *argv[]) {
895 Context context = {};
896 _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *event = NULL((void*)0);
897 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
898 int r;
899
900 log_set_target(LOG_TARGET_AUTO);
901 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
902 log_open();
903
904 umask(0022);
905
906 if (argc != 1) {
1
Assuming 'argc' is equal to 1
2
Taking false branch
907 log_error("This program takes no arguments.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 907, __func__, "This program takes no arguments."
) : -abs(_e); })
;
908 r = -EINVAL22;
909 goto finish;
910 }
911
912 r = sd_event_default(&event);
913 if (r < 0) {
3
Assuming 'r' is >= 0
4
Taking false branch
914 log_error_errno(r, "Failed to allocate event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 914, __func__, "Failed to allocate event loop: %m"
) : -abs(_e); })
;
915 goto finish;
916 }
917
918 sd_event_set_watchdog(event, true1);
919
920 r = connect_bus(&context, event, &bus);
921 if (r < 0)
5
Assuming 'r' is < 0
6
Taking true branch
922 goto finish;
7
Control jumps to line 943
923
924 (void) sd_bus_negotiate_timestamp(bus, true1);
925
926 r = context_read_data(&context);
927 if (r < 0) {
928 log_error_errno(r, "Failed to read time zone data: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 928, __func__, "Failed to read time zone data: %m"
) : -abs(_e); })
;
929 goto finish;
930 }
931
932 r = context_parse_ntp_services(&context);
933 if (r < 0)
934 goto finish;
935
936 r = bus_event_loop_with_idle(event, bus, "org.freedesktop.timedate1", DEFAULT_EXIT_USEC(30*((usec_t) 1000000ULL)), NULL((void*)0), NULL((void*)0));
937 if (r < 0) {
938 log_error_errno(r, "Failed to run event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/timedate/timedated.c", 938, __func__, "Failed to run event loop: %m"
) : -abs(_e); })
;
939 goto finish;
940 }
941
942finish:
943 context_free(&context);
8
Calling 'context_free'
944
945 return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0;
946}