]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/sd-bus.c
tree-wide: invoke rlimit_nofile_safe() before various exec{v,ve,l}() invocations
[thirdparty/systemd.git] / src / libsystemd / sd-bus / sd-bus.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
de1c301e
LP
2
3#include <endian.h>
de1c301e 4#include <netdb.h>
0a6f50c0 5#include <poll.h>
45fbe937 6#include <pthread.h>
392cf1d0 7#include <signal.h>
cf0fbc49
TA
8#include <stdlib.h>
9#include <sys/mman.h>
392cf1d0 10#include <sys/wait.h>
cf0fbc49 11#include <unistd.h>
de1c301e 12
de1c301e 13#include "sd-bus.h"
07630cea 14
b5efdb8a 15#include "alloc-util.h"
07630cea
LP
16#include "bus-container.h"
17#include "bus-control.h"
de1c301e 18#include "bus-internal.h"
6629161f 19#include "bus-kernel.h"
07630cea
LP
20#include "bus-label.h"
21#include "bus-message.h"
992c052c 22#include "bus-objects.h"
0461f8cd 23#include "bus-protocol.h"
19befb2d 24#include "bus-slot.h"
07630cea
LP
25#include "bus-socket.h"
26#include "bus-track.h"
27#include "bus-type.h"
28#include "bus-util.h"
29#include "cgroup-util.h"
30#include "def.h"
3ffd4af2 31#include "fd-util.h"
cf0fbc49 32#include "hexdecoct.h"
07630cea
LP
33#include "hostname-util.h"
34#include "macro.h"
35#include "missing.h"
6bedfcbb 36#include "parse-util.h"
dccca82b 37#include "process-util.h"
07630cea
LP
38#include "string-util.h"
39#include "strv.h"
40#include "util.h"
de1c301e 41
b56c4604
LP
42#define log_debug_bus_message(m) \
43 do { \
44 sd_bus_message *_mm = (m); \
e32fd6b4 45 log_debug("Got message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", \
b56c4604
LP
46 bus_message_type_to_string(_mm->header->type), \
47 strna(sd_bus_message_get_sender(_mm)), \
48 strna(sd_bus_message_get_destination(_mm)), \
49 strna(sd_bus_message_get_path(_mm)), \
50 strna(sd_bus_message_get_interface(_mm)), \
51 strna(sd_bus_message_get_member(_mm)), \
52 BUS_MESSAGE_COOKIE(_mm), \
53 _mm->reply_cookie, \
e32fd6b4 54 strna(_mm->root_container.signature), \
e28d0865 55 strna(_mm->error.name), \
b56c4604
LP
56 strna(_mm->error.message)); \
57 } while (false)
f9f97ca6 58
e3017af9 59static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
8a5cd31e
LP
60static void bus_detach_io_events(sd_bus *b);
61static void bus_detach_inotify_event(sd_bus *b);
e3017af9 62
fa2f8973
LP
63static thread_local sd_bus *default_system_bus = NULL;
64static thread_local sd_bus *default_user_bus = NULL;
65static thread_local sd_bus *default_starter_bus = NULL;
66
45b1f410
NM
67static sd_bus **bus_choose_default(int (**bus_open)(sd_bus **)) {
68 const char *e;
69
70 /* Let's try our best to reuse another cached connection. If
71 * the starter bus type is set, connect via our normal
72 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
73 * we can share the connection with the user/system default
74 * bus. */
75
76 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
77 if (e) {
78 if (streq(e, "system")) {
79 if (bus_open)
80 *bus_open = sd_bus_open_system;
81 return &default_system_bus;
82 } else if (STR_IN_SET(e, "user", "session")) {
83 if (bus_open)
84 *bus_open = sd_bus_open_user;
85 return &default_user_bus;
86 }
87 }
88
89 /* No type is specified, so we have not other option than to
90 * use the starter address if it is set. */
91 e = secure_getenv("DBUS_STARTER_ADDRESS");
92 if (e) {
93 if (bus_open)
94 *bus_open = sd_bus_open;
95 return &default_starter_bus;
96 }
97
98 /* Finally, if nothing is set use the cached connection for
99 * the right scope */
100
101 if (cg_pid_get_owner_uid(0, NULL) >= 0) {
102 if (bus_open)
103 *bus_open = sd_bus_open_user;
104 return &default_user_bus;
105 } else {
106 if (bus_open)
107 *bus_open = sd_bus_open_system;
108 return &default_system_bus;
109 }
110}
111
112sd_bus *bus_resolve(sd_bus *bus) {
113 switch ((uintptr_t) bus) {
114 case (uintptr_t) SD_BUS_DEFAULT:
115 return *(bus_choose_default(NULL));
116 case (uintptr_t) SD_BUS_DEFAULT_USER:
117 return default_user_bus;
118 case (uintptr_t) SD_BUS_DEFAULT_SYSTEM:
119 return default_system_bus;
120 default:
121 return bus;
122 }
123}
124
8a5cd31e 125void bus_close_io_fds(sd_bus *b) {
f54514f3
LP
126 assert(b);
127
8a5cd31e 128 bus_detach_io_events(b);
1e05d493 129
0fd8d506 130 if (b->input_fd != b->output_fd)
03e334a1 131 safe_close(b->output_fd);
0fd8d506 132 b->output_fd = b->input_fd = safe_close(b->input_fd);
f54514f3
LP
133}
134
8a5cd31e
LP
135void bus_close_inotify_fd(sd_bus *b) {
136 assert(b);
137
138 bus_detach_inotify_event(b);
139
140 b->inotify_fd = safe_close(b->inotify_fd);
141 b->inotify_watches = mfree(b->inotify_watches);
142 b->n_inotify_watches = 0;
143}
144
0e586eae 145static void bus_reset_queues(sd_bus *b) {
0e586eae
LP
146 assert(b);
147
f389bf15
LP
148 while (b->rqueue_size > 0)
149 sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
150
253f96e5 151 b->rqueue = mfree(b->rqueue);
f389bf15 152 b->rqueue_allocated = 0;
0e586eae 153
f389bf15
LP
154 while (b->wqueue_size > 0)
155 sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
0e586eae 156
253f96e5 157 b->wqueue = mfree(b->wqueue);
f389bf15 158 b->wqueue_allocated = 0;
0e586eae
LP
159}
160
9df088f1 161static sd_bus* bus_free(sd_bus *b) {
19befb2d 162 sd_bus_slot *s;
de1c301e
LP
163
164 assert(b);
8f8f05a9 165 assert(!b->track_queue);
232f3677 166 assert(!b->tracks);
8f8f05a9 167
19befb2d
LP
168 b->state = BUS_CLOSED;
169
40ca29a1
LP
170 sd_bus_detach_event(b);
171
19befb2d
LP
172 while ((s = b->slots)) {
173 /* At this point only floating slots can still be
174 * around, because the non-floating ones keep a
175 * reference to the bus, and we thus couldn't be
176 * destructing right now... We forcibly disconnect the
177 * slots here, so that they still can be referenced by
178 * apps, but are dead. */
179
180 assert(s->floating);
2e7e8e34 181 bus_slot_disconnect(s, true);
19befb2d
LP
182 }
183
f4d140e9
LP
184 if (b->default_bus_ptr)
185 *b->default_bus_ptr = NULL;
186
8a5cd31e
LP
187 bus_close_io_fds(b);
188 bus_close_inotify_fd(b);
de1c301e 189
c4e6556c 190 free(b->label);
18ac4643 191 free(b->groups);
de1c301e 192 free(b->rbuffer);
89ffcd2a 193 free(b->unique_name);
2181a7f5 194 free(b->auth_buffer);
89ffcd2a 195 free(b->address);
a7893c6b 196 free(b->machine);
751bc6ac 197 free(b->cgroup_root);
455971c1 198 free(b->description);
48ef41a3 199 free(b->patch_sender);
89ffcd2a 200
2fd9ae2e
LP
201 free(b->exec_path);
202 strv_free(b->exec_argv);
203
2c93b4ef
LP
204 close_many(b->fds, b->n_fds);
205 free(b->fds);
206
0e586eae 207 bus_reset_queues(b);
de1c301e 208
c9fe4af7 209 ordered_hashmap_free_free(b->reply_callbacks);
e3017af9 210 prioq_free(b->reply_callbacks_prioq);
de1c301e 211
75a0da95 212 assert(b->match_callbacks.type == BUS_MATCH_ROOT);
392d5b37
LP
213 bus_match_free(&b->match_callbacks);
214
29ddb38f
LP
215 hashmap_free_free(b->vtable_methods);
216 hashmap_free_free(b->vtable_properties);
217
19befb2d 218 assert(hashmap_isempty(b->nodes));
29ddb38f
LP
219 hashmap_free(b->nodes);
220
a132bef0 221 bus_flush_memfd(b);
bc7fd8cd 222
45fbe937
LP
223 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
224
9df088f1 225 return mfree(b);
de1c301e
LP
226}
227
9df088f1
ZJS
228DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, bus_free);
229
d9f644e2 230_public_ int sd_bus_new(sd_bus **ret) {
01c4dcaf 231 _cleanup_free_ sd_bus *b = NULL;
de1c301e 232
d6888822 233 assert_return(ret, -EINVAL);
021a1e78 234
c4e48030 235 b = new(sd_bus, 1);
01c4dcaf 236 if (!b)
021a1e78 237 return -ENOMEM;
de1c301e 238
c4e48030
LP
239 *b = (sd_bus) {
240 .n_ref = REFCNT_INIT,
241 .input_fd = -1,
242 .output_fd = -1,
243 .inotify_fd = -1,
244 .message_version = 1,
245 .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
246 .accept_fd = true,
247 .original_pid = getpid_cached(),
248 .n_groups = (size_t) -1,
249 .close_on_exit = true,
250 };
01c4dcaf
ZJS
251
252 assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
253
254 /* We guarantee that wqueue always has space for at least one entry */
255 if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
021a1e78 256 return -ENOMEM;
de1c301e 257
01c4dcaf 258 *ret = TAKE_PTR(b);
021a1e78
LP
259 return 0;
260}
261
d9f644e2 262_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
d6888822 263 assert_return(bus, -EINVAL);
45b1f410 264 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
265 assert_return(bus->state == BUS_UNSET, -EPERM);
266 assert_return(address, -EINVAL);
267 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 268
1ab436e3 269 return free_and_strdup(&bus->address, address);
021a1e78
LP
270}
271
d9f644e2 272_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822 273 assert_return(bus, -EINVAL);
45b1f410 274 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 275 assert_return(bus->state == BUS_UNSET, -EPERM);
8ac43fee
LP
276 assert_return(input_fd >= 0, -EBADF);
277 assert_return(output_fd >= 0, -EBADF);
d6888822 278 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 279
e82c9509
LP
280 bus->input_fd = input_fd;
281 bus->output_fd = output_fd;
021a1e78
LP
282 return 0;
283}
284
d9f644e2 285_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
1ab436e3
YW
286 _cleanup_strv_free_ char **a = NULL;
287 int r;
2fd9ae2e 288
d6888822 289 assert_return(bus, -EINVAL);
45b1f410 290 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
291 assert_return(bus->state == BUS_UNSET, -EPERM);
292 assert_return(path, -EINVAL);
293 assert_return(!strv_isempty(argv), -EINVAL);
294 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e 295
2fd9ae2e 296 a = strv_copy(argv);
01c4dcaf 297 if (!a)
2fd9ae2e 298 return -ENOMEM;
2fd9ae2e 299
1ab436e3
YW
300 r = free_and_strdup(&bus->exec_path, path);
301 if (r < 0)
302 return r;
303
304 return strv_free_and_replace(bus->exec_argv, a);
2fd9ae2e
LP
305}
306
d9f644e2 307_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822 308 assert_return(bus, -EINVAL);
45b1f410 309 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 310 assert_return(bus->state == BUS_UNSET, -EPERM);
48ef41a3 311 assert_return(!bus->patch_sender, -EPERM);
d6888822 312 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 313
94bbf1ba 314 bus->bus_client = !!b;
021a1e78
LP
315 return 0;
316}
317
09365592
LP
318_public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
319 assert_return(bus, -EINVAL);
45b1f410 320 assert_return(bus = bus_resolve(bus), -ENOPKG);
09365592
LP
321 assert_return(bus->state == BUS_UNSET, -EPERM);
322 assert_return(!bus_pid_changed(bus), -ECHILD);
323
e5c8029e 324 bus->is_monitor = !!b;
09365592
LP
325 return 0;
326}
327
d9f644e2 328_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822 329 assert_return(bus, -EINVAL);
45b1f410 330 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
331 assert_return(bus->state == BUS_UNSET, -EPERM);
332 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 333
e5c8029e 334 bus->accept_fd = !!b;
264ad849
LP
335 return 0;
336}
337
4fc31988 338_public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
16be4368 339 assert_return(bus, -EINVAL);
45b1f410 340 assert_return(bus = bus_resolve(bus), -ENOPKG);
b5dae4c7 341 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
16be4368
KS
342 assert_return(!bus_pid_changed(bus), -ECHILD);
343
c7db1984
LP
344 /* This is not actually supported by any of our transports these days, but we do honour it for synthetic
345 * replies, and maybe one day classic D-Bus learns this too */
e5c8029e 346 bus->attach_timestamp = !!b;
b5dae4c7 347
16be4368
KS
348 return 0;
349}
350
b5dae4c7 351_public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
16be4368 352 assert_return(bus, -EINVAL);
45b1f410 353 assert_return(bus = bus_resolve(bus), -ENOPKG);
95c4fe82 354 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
b5dae4c7 355 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
16be4368
KS
356 assert_return(!bus_pid_changed(bus), -ECHILD);
357
5883ff60 358 SET_FLAG(bus->creds_mask, mask, b);
b5dae4c7 359
49b832c5 360 /* The well knowns we need unconditionally, so that matches can work */
b5dae4c7
LP
361 bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
362
b5dae4c7 363 return 0;
021a1e78 364}
de1c301e 365
d9f644e2 366_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
d6888822 367 assert_return(bus, -EINVAL);
45b1f410 368 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
369 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
370 assert_return(bus->state == BUS_UNSET, -EPERM);
371 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
372
373 bus->is_server = !!b;
98178d39 374 bus->server_id = server_id;
2181a7f5
LP
375 return 0;
376}
377
d9f644e2 378_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
d6888822 379 assert_return(bus, -EINVAL);
45b1f410 380 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
381 assert_return(bus->state == BUS_UNSET, -EPERM);
382 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
383
384 bus->anonymous_auth = !!b;
385 return 0;
386}
387
adacb957
LP
388_public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
389 assert_return(bus, -EINVAL);
45b1f410 390 assert_return(bus = bus_resolve(bus), -ENOPKG);
adacb957
LP
391 assert_return(bus->state == BUS_UNSET, -EPERM);
392 assert_return(!bus_pid_changed(bus), -ECHILD);
393
394 bus->trusted = !!b;
395 return 0;
396}
397
455971c1 398_public_ int sd_bus_set_description(sd_bus *bus, const char *description) {
5972fe95 399 assert_return(bus, -EINVAL);
45b1f410 400 assert_return(bus = bus_resolve(bus), -ENOPKG);
5972fe95
LP
401 assert_return(bus->state == BUS_UNSET, -EPERM);
402 assert_return(!bus_pid_changed(bus), -ECHILD);
403
d1b91c99 404 return free_and_strdup(&bus->description, description);
5972fe95
LP
405}
406
c0765ddb
LP
407_public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) {
408 assert_return(bus, -EINVAL);
45b1f410 409 assert_return(bus = bus_resolve(bus), -ENOPKG);
c0765ddb
LP
410 assert_return(!bus_pid_changed(bus), -ECHILD);
411
412 bus->allow_interactive_authorization = !!b;
413 return 0;
414}
415
416_public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) {
417 assert_return(bus, -EINVAL);
45b1f410 418 assert_return(bus = bus_resolve(bus), -ENOPKG);
c0765ddb
LP
419 assert_return(!bus_pid_changed(bus), -ECHILD);
420
421 return bus->allow_interactive_authorization;
422}
423
8a5cd31e
LP
424_public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) {
425 assert_return(bus, -EINVAL);
45b1f410 426 assert_return(bus = bus_resolve(bus), -ENOPKG);
8a5cd31e
LP
427 assert_return(bus->state == BUS_UNSET, -EPERM);
428 assert_return(!bus_pid_changed(bus), -ECHILD);
429
e5c8029e 430 bus->watch_bind = !!b;
8a5cd31e
LP
431 return 0;
432}
433
434_public_ int sd_bus_get_watch_bind(sd_bus *bus) {
435 assert_return(bus, -EINVAL);
45b1f410 436 assert_return(bus = bus_resolve(bus), -ENOPKG);
8a5cd31e
LP
437 assert_return(!bus_pid_changed(bus), -ECHILD);
438
439 return bus->watch_bind;
440}
441
b38cc8d5
LP
442_public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) {
443 assert_return(bus, -EINVAL);
45b1f410 444 assert_return(bus = bus_resolve(bus), -ENOPKG);
b38cc8d5
LP
445 assert_return(bus->state == BUS_UNSET, -EPERM);
446 assert_return(!bus_pid_changed(bus), -ECHILD);
447
e5c8029e 448 bus->connected_signal = !!b;
b38cc8d5
LP
449 return 0;
450}
451
452_public_ int sd_bus_get_connected_signal(sd_bus *bus) {
453 assert_return(bus, -EINVAL);
45b1f410 454 assert_return(bus = bus_resolve(bus), -ENOPKG);
b38cc8d5
LP
455 assert_return(!bus_pid_changed(bus), -ECHILD);
456
457 return bus->connected_signal;
458}
459
460static int synthesize_connected_signal(sd_bus *bus) {
461 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
462 int r;
463
464 assert(bus);
465
466 /* If enabled, synthesizes a local "Connected" signal mirroring the local "Disconnected" signal. This is called
467 * whenever we fully established a connection, i.e. after the authorization phase, and after receiving the
468 * Hello() reply. Or in other words, whenver we enter BUS_RUNNING state.
469 *
470 * This is useful so that clients can start doing stuff whenver the connection is fully established in a way
471 * that works independently from whether we connected to a full bus or just a direct connection. */
472
473 if (!bus->connected_signal)
474 return 0;
475
476 r = sd_bus_message_new_signal(
477 bus,
478 &m,
479 "/org/freedesktop/DBus/Local",
480 "org.freedesktop.DBus.Local",
481 "Connected");
482 if (r < 0)
483 return r;
484
485 bus_message_set_sender_local(bus, m);
486
487 r = bus_seal_synthetic_message(bus, m);
488 if (r < 0)
489 return r;
490
491 r = bus_rqueue_make_room(bus);
492 if (r < 0)
493 return r;
494
495 /* Insert at the very front */
496 memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size);
1cc6c93a 497 bus->rqueue[0] = TAKE_PTR(m);
b38cc8d5
LP
498 bus->rqueue_size++;
499
500 return 0;
501}
502
3e0e196e
LP
503void bus_set_state(sd_bus *bus, enum bus_state state) {
504
505 static const char * const table[_BUS_STATE_MAX] = {
506 [BUS_UNSET] = "UNSET",
507 [BUS_WATCH_BIND] = "WATCH_BIND",
508 [BUS_OPENING] = "OPENING",
509 [BUS_AUTHENTICATING] = "AUTHENTICATING",
510 [BUS_HELLO] = "HELLO",
511 [BUS_RUNNING] = "RUNNING",
512 [BUS_CLOSING] = "CLOSING",
513 [BUS_CLOSED] = "CLOSED",
514 };
515
516 assert(bus);
517 assert(state < _BUS_STATE_MAX);
518
519 if (state == bus->state)
520 return;
521
522 log_debug("Bus %s: changing state %s → %s", strna(bus->description), table[bus->state], table[state]);
523 bus->state = state;
524}
525
19070062 526static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
de1c301e 527 const char *s;
19070062 528 sd_bus *bus;
de1c301e
LP
529 int r;
530
19070062
LP
531 assert(reply);
532 bus = reply->bus;
de1c301e 533 assert(bus);
945c2931 534 assert(IN_SET(bus->state, BUS_HELLO, BUS_CLOSING));
de1c301e 535
40ca29a1 536 r = sd_bus_message_get_errno(reply);
40ca29a1
LP
537 if (r > 0)
538 return -r;
eb01ba5d 539
de1c301e
LP
540 r = sd_bus_message_read(reply, "s", &s);
541 if (r < 0)
542 return r;
543
dafb7591
LP
544 if (!service_name_is_valid(s) || s[0] != ':')
545 return -EBADMSG;
546
1ab436e3
YW
547 r = free_and_strdup(&bus->unique_name, s);
548 if (r < 0)
549 return r;
b4ca3f45 550
b38cc8d5 551 if (bus->state == BUS_HELLO) {
3e0e196e 552 bus_set_state(bus, BUS_RUNNING);
dafb7591 553
b38cc8d5
LP
554 r = synthesize_connected_signal(bus);
555 if (r < 0)
556 return r;
557 }
558
de1c301e
LP
559 return 1;
560}
561
562static int bus_send_hello(sd_bus *bus) {
4afd3348 563 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
de1c301e
LP
564 int r;
565
566 assert(bus);
567
a132bef0 568 if (!bus->bus_client)
021a1e78
LP
569 return 0;
570
de1c301e
LP
571 r = sd_bus_message_new_method_call(
572 bus,
151b9b96 573 &m,
de1c301e 574 "org.freedesktop.DBus",
a7639e37 575 "/org/freedesktop/DBus",
de1c301e 576 "org.freedesktop.DBus",
151b9b96 577 "Hello");
de1c301e
LP
578 if (r < 0)
579 return r;
580
19befb2d 581 return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
de1c301e
LP
582}
583
a7e3212d 584int bus_start_running(sd_bus *bus) {
ac8029fc
LP
585 struct reply_callback *c;
586 Iterator i;
587 usec_t n;
b38cc8d5 588 int r;
ac8029fc 589
de1c301e 590 assert(bus);
ac8029fc
LP
591 assert(bus->state < BUS_HELLO);
592
593 /* We start all method call timeouts when we enter BUS_HELLO or BUS_RUNNING mode. At this point let's convert
594 * all relative to absolute timestamps. Note that we do not reshuffle the reply callback priority queue since
595 * adding a fixed value to all entries should not alter the internal order. */
596
597 n = now(CLOCK_MONOTONIC);
598 ORDERED_HASHMAP_FOREACH(c, bus->reply_callbacks, i) {
599 if (c->timeout_usec == 0)
600 continue;
601
602 c->timeout_usec = usec_add(n, c->timeout_usec);
603 }
de1c301e 604
a132bef0 605 if (bus->bus_client) {
3e0e196e 606 bus_set_state(bus, BUS_HELLO);
e3017af9 607 return 1;
de1c301e
LP
608 }
609
3e0e196e 610 bus_set_state(bus, BUS_RUNNING);
b38cc8d5
LP
611
612 r = synthesize_connected_signal(bus);
613 if (r < 0)
614 return r;
615
e3017af9 616 return 1;
de1c301e
LP
617}
618
619static int parse_address_key(const char **p, const char *key, char **value) {
821e0756 620 size_t l, n = 0, allocated = 0;
cad4fb19 621 _cleanup_free_ char *r = NULL;
de1c301e 622 const char *a;
de1c301e
LP
623
624 assert(p);
625 assert(*p);
de1c301e
LP
626 assert(value);
627
2fd9ae2e
LP
628 if (key) {
629 l = strlen(key);
630 if (strncmp(*p, key, l) != 0)
631 return 0;
de1c301e 632
2fd9ae2e
LP
633 if ((*p)[l] != '=')
634 return 0;
de1c301e 635
2fd9ae2e
LP
636 if (*value)
637 return -EINVAL;
de1c301e 638
2fd9ae2e
LP
639 a = *p + l + 1;
640 } else
641 a = *p;
642
945c2931 643 while (!IN_SET(*a, ';', ',', 0)) {
821e0756 644 char c;
de1c301e
LP
645
646 if (*a == '%') {
647 int x, y;
648
649 x = unhexchar(a[1]);
cad4fb19 650 if (x < 0)
de1c301e 651 return x;
de1c301e
LP
652
653 y = unhexchar(a[2]);
cad4fb19 654 if (y < 0)
de1c301e 655 return y;
de1c301e 656
de1c301e 657 c = (char) ((x << 4) | y);
89ffcd2a
LP
658 a += 3;
659 } else {
de1c301e 660 c = *a;
89ffcd2a
LP
661 a++;
662 }
de1c301e 663
821e0756 664 if (!GREEDY_REALLOC(r, allocated, n + 2))
de1c301e 665 return -ENOMEM;
de1c301e 666
de1c301e
LP
667 r[n++] = c;
668 }
669
89ffcd2a
LP
670 if (!r) {
671 r = strdup("");
672 if (!r)
673 return -ENOMEM;
674 } else
675 r[n] = 0;
676
677 if (*a == ',')
678 a++;
679
de1c301e 680 *p = a;
2fd9ae2e 681
cad4fb19 682 free_and_replace(*value, r);
2fd9ae2e 683
de1c301e
LP
684 return 1;
685}
686
687static void skip_address_key(const char **p) {
688 assert(p);
689 assert(*p);
690
89ffcd2a
LP
691 *p += strcspn(*p, ",");
692
693 if (**p == ',')
313cefa1 694 (*p)++;
de1c301e
LP
695}
696
2fd9ae2e
LP
697static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
698 _cleanup_free_ char *path = NULL, *abstract = NULL;
699 size_t l;
de1c301e
LP
700 int r;
701
702 assert(b);
2fd9ae2e
LP
703 assert(p);
704 assert(*p);
705 assert(guid);
de1c301e 706
945c2931 707 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
708 r = parse_address_key(p, "guid", guid);
709 if (r < 0)
710 return r;
711 else if (r > 0)
712 continue;
de1c301e 713
2fd9ae2e
LP
714 r = parse_address_key(p, "path", &path);
715 if (r < 0)
716 return r;
717 else if (r > 0)
718 continue;
de1c301e 719
2fd9ae2e
LP
720 r = parse_address_key(p, "abstract", &abstract);
721 if (r < 0)
722 return r;
723 else if (r > 0)
724 continue;
de1c301e 725
2fd9ae2e
LP
726 skip_address_key(p);
727 }
de1c301e 728
2fd9ae2e
LP
729 if (!path && !abstract)
730 return -EINVAL;
de1c301e 731
2fd9ae2e
LP
732 if (path && abstract)
733 return -EINVAL;
734
735 if (path) {
736 l = strlen(path);
1d261418 737 if (l >= sizeof(b->sockaddr.un.sun_path)) /* We insist on NUL termination */
2fd9ae2e 738 return -E2BIG;
de1c301e 739
95cb14b0
LP
740 b->sockaddr.un = (struct sockaddr_un) {
741 .sun_family = AF_UNIX,
742 };
743
744 memcpy(b->sockaddr.un.sun_path, path, l);
745 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l + 1;
746
747 } else {
748 assert(abstract);
749
2fd9ae2e 750 l = strlen(abstract);
1d261418 751 if (l >= sizeof(b->sockaddr.un.sun_path) - 1) /* We insist on NUL termination */
2fd9ae2e
LP
752 return -E2BIG;
753
95cb14b0
LP
754 b->sockaddr.un = (struct sockaddr_un) {
755 .sun_family = AF_UNIX,
756 };
757
758 memcpy(b->sockaddr.un.sun_path+1, abstract, l);
2fd9ae2e
LP
759 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
760 }
761
694859b5
LP
762 b->is_local = true;
763
2fd9ae2e
LP
764 return 0;
765}
766
767static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
768 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 769 int r;
b92bea5d
ZJS
770 struct addrinfo *result, hints = {
771 .ai_socktype = SOCK_STREAM,
772 .ai_flags = AI_ADDRCONFIG,
773 };
2fd9ae2e
LP
774
775 assert(b);
776 assert(p);
777 assert(*p);
778 assert(guid);
779
945c2931 780 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
781 r = parse_address_key(p, "guid", guid);
782 if (r < 0)
783 return r;
784 else if (r > 0)
785 continue;
786
787 r = parse_address_key(p, "host", &host);
788 if (r < 0)
789 return r;
790 else if (r > 0)
791 continue;
792
793 r = parse_address_key(p, "port", &port);
794 if (r < 0)
795 return r;
796 else if (r > 0)
797 continue;
798
799 r = parse_address_key(p, "family", &family);
800 if (r < 0)
801 return r;
802 else if (r > 0)
803 continue;
804
805 skip_address_key(p);
806 }
807
808 if (!host || !port)
809 return -EINVAL;
810
2fd9ae2e
LP
811 if (family) {
812 if (streq(family, "ipv4"))
813 hints.ai_family = AF_INET;
814 else if (streq(family, "ipv6"))
815 hints.ai_family = AF_INET6;
816 else
817 return -EINVAL;
818 }
819
820 r = getaddrinfo(host, port, &hints, &result);
821 if (r == EAI_SYSTEM)
822 return -errno;
823 else if (r != 0)
824 return -EADDRNOTAVAIL;
825
826 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
827 b->sockaddr_size = result->ai_addrlen;
828
829 freeaddrinfo(result);
830
694859b5
LP
831 b->is_local = false;
832
2fd9ae2e
LP
833 return 0;
834}
835
836static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
837 char *path = NULL;
838 unsigned n_argv = 0, j;
839 char **argv = NULL;
821e0756 840 size_t allocated = 0;
2fd9ae2e
LP
841 int r;
842
843 assert(b);
844 assert(p);
845 assert(*p);
846 assert(guid);
847
945c2931 848 while (!IN_SET(**p, 0, ';')) {
2fd9ae2e
LP
849 r = parse_address_key(p, "guid", guid);
850 if (r < 0)
851 goto fail;
852 else if (r > 0)
853 continue;
854
855 r = parse_address_key(p, "path", &path);
856 if (r < 0)
857 goto fail;
858 else if (r > 0)
859 continue;
860
861 if (startswith(*p, "argv")) {
862 unsigned ul;
863
864 errno = 0;
865 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 866 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
867 r = -EINVAL;
868 goto fail;
869 }
870
313cefa1 871 (*p)++;
2fd9ae2e
LP
872
873 if (ul >= n_argv) {
821e0756 874 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
2fd9ae2e
LP
875 r = -ENOMEM;
876 goto fail;
877 }
878
2fd9ae2e
LP
879 n_argv = ul + 1;
880 }
881
882 r = parse_address_key(p, NULL, argv + ul);
de1c301e 883 if (r < 0)
2fd9ae2e 884 goto fail;
de1c301e 885
2fd9ae2e 886 continue;
de1c301e
LP
887 }
888
2fd9ae2e
LP
889 skip_address_key(p);
890 }
de1c301e 891
5a0f6033
LP
892 if (!path) {
893 r = -EINVAL;
2fd9ae2e 894 goto fail;
5a0f6033 895 }
de1c301e 896
2fd9ae2e
LP
897 /* Make sure there are no holes in the array, with the
898 * exception of argv[0] */
899 for (j = 1; j < n_argv; j++)
900 if (!argv[j]) {
901 r = -EINVAL;
902 goto fail;
903 }
904
905 if (argv && argv[0] == NULL) {
906 argv[0] = strdup(path);
907 if (!argv[0]) {
908 r = -ENOMEM;
909 goto fail;
910 }
911 }
de1c301e 912
2fd9ae2e
LP
913 b->exec_path = path;
914 b->exec_argv = argv;
694859b5
LP
915
916 b->is_local = false;
917
2fd9ae2e 918 return 0;
de1c301e 919
2fd9ae2e
LP
920fail:
921 for (j = 0; j < n_argv; j++)
922 free(argv[j]);
923
924 free(argv);
925 free(path);
926 return r;
927}
928
bc9fd78c 929static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
ee502e0c 930 _cleanup_free_ char *machine = NULL, *pid = NULL;
a7893c6b
LP
931 int r;
932
933 assert(b);
934 assert(p);
935 assert(*p);
936 assert(guid);
937
945c2931 938 while (!IN_SET(**p, 0, ';')) {
a7893c6b
LP
939 r = parse_address_key(p, "guid", guid);
940 if (r < 0)
941 return r;
942 else if (r > 0)
943 continue;
944
945 r = parse_address_key(p, "machine", &machine);
946 if (r < 0)
947 return r;
948 else if (r > 0)
949 continue;
950
ee502e0c
LP
951 r = parse_address_key(p, "pid", &pid);
952 if (r < 0)
953 return r;
954 else if (r > 0)
955 continue;
956
a7893c6b
LP
957 skip_address_key(p);
958 }
959
ee502e0c 960 if (!machine == !pid)
a7893c6b
LP
961 return -EINVAL;
962
ee502e0c 963 if (machine) {
1e5057b9 964 if (!streq(machine, ".host") && !machine_name_is_valid(machine))
ee502e0c 965 return -EINVAL;
b6741478 966
f9ecfd3b 967 free_and_replace(b->machine, machine);
ee502e0c 968 } else {
a1e58e8e 969 b->machine = mfree(b->machine);
ee502e0c
LP
970 }
971
972 if (pid) {
973 r = parse_pid(pid, &b->nspid);
974 if (r < 0)
975 return r;
976 } else
977 b->nspid = 0;
a7893c6b 978
44ed5214
LP
979 b->sockaddr.un = (struct sockaddr_un) {
980 .sun_family = AF_UNIX,
981 /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */
982 .sun_path = "/var/run/dbus/system_bus_socket",
983 };
fc2fffe7 984 b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
694859b5 985 b->is_local = false;
a7893c6b
LP
986
987 return 0;
988}
989
2fd9ae2e
LP
990static void bus_reset_parsed_address(sd_bus *b) {
991 assert(b);
992
993 zero(b->sockaddr);
994 b->sockaddr_size = 0;
ba243e51
NK
995 b->exec_argv = strv_free(b->exec_argv);
996 b->exec_path = mfree(b->exec_path);
98178d39 997 b->server_id = SD_ID128_NULL;
ba243e51 998 b->machine = mfree(b->machine);
ee502e0c 999 b->nspid = 0;
2fd9ae2e
LP
1000}
1001
1002static int bus_parse_next_address(sd_bus *b) {
1003 _cleanup_free_ char *guid = NULL;
1004 const char *a;
1005 int r;
1006
1007 assert(b);
1008
1009 if (!b->address)
1010 return 0;
1011 if (b->address[b->address_index] == 0)
1012 return 0;
1013
1014 bus_reset_parsed_address(b);
1015
1016 a = b->address + b->address_index;
de1c301e 1017
2fd9ae2e 1018 while (*a != 0) {
de1c301e 1019
2fd9ae2e
LP
1020 if (*a == ';') {
1021 a++;
1022 continue;
de1c301e
LP
1023 }
1024
2fd9ae2e
LP
1025 if (startswith(a, "unix:")) {
1026 a += 5;
de1c301e 1027
2fd9ae2e 1028 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
1029 if (r < 0)
1030 return r;
2fd9ae2e 1031 break;
de1c301e 1032
2fd9ae2e 1033 } else if (startswith(a, "tcp:")) {
de1c301e 1034
2fd9ae2e
LP
1035 a += 4;
1036 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
1037 if (r < 0)
1038 return r;
de1c301e 1039
2fd9ae2e
LP
1040 break;
1041
1042 } else if (startswith(a, "unixexec:")) {
1043
1044 a += 9;
1045 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
1046 if (r < 0)
1047 return r;
de1c301e 1048
2fd9ae2e 1049 break;
de1c301e 1050
de33fc62 1051 } else if (startswith(a, "x-machine-unix:")) {
bc9fd78c 1052
146d4773 1053 a += 15;
bc9fd78c
LP
1054 r = parse_container_unix_address(b, &a, &guid);
1055 if (r < 0)
1056 return r;
1057
6629161f 1058 break;
de1c301e
LP
1059 }
1060
2fd9ae2e
LP
1061 a = strchr(a, ';');
1062 if (!a)
1063 return 0;
de1c301e
LP
1064 }
1065
1066 if (guid) {
98178d39 1067 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
1068 if (r < 0)
1069 return r;
1070 }
1071
2fd9ae2e 1072 b->address_index = a - b->address;
de1c301e
LP
1073 return 1;
1074}
1075
392cf1d0
SL
1076static void bus_kill_exec(sd_bus *bus) {
1077 if (pid_is_valid(bus->busexec_pid) > 0) {
1078 sigterm_wait(bus->busexec_pid);
1079 bus->busexec_pid = 0;
1080 }
1081}
1082
a7e3212d 1083static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
1084 int r;
1085
1086 assert(b);
1087
1088 for (;;) {
8a5cd31e
LP
1089 bus_close_io_fds(b);
1090 bus_close_inotify_fd(b);
a7e3212d 1091
392cf1d0
SL
1092 bus_kill_exec(b);
1093
a132bef0
ZJS
1094 /* If you provide multiple different bus-addresses, we
1095 * try all of them in order and use the first one that
1096 * succeeds. */
15442912 1097
1e05d493 1098 if (b->exec_path)
a7893c6b 1099 r = bus_socket_exec(b);
a132bef0
ZJS
1100 else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
1101 r = bus_container_connect_socket(b);
a132bef0
ZJS
1102 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
1103 r = bus_socket_connect(b);
a132bef0
ZJS
1104 else
1105 goto next;
1106
1107 if (r >= 0) {
8a5cd31e
LP
1108 int q;
1109
1110 q = bus_attach_io_events(b);
1111 if (q < 0)
1112 return q;
1113
1114 q = bus_attach_inotify_event(b);
1115 if (q < 0)
1116 return q;
1117
1118 return r;
2fd9ae2e
LP
1119 }
1120
a132bef0
ZJS
1121 b->last_connect_error = -r;
1122
1123 next:
2fd9ae2e
LP
1124 r = bus_parse_next_address(b);
1125 if (r < 0)
1126 return r;
1127 if (r == 0)
a132bef0 1128 return b->last_connect_error > 0 ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
1129 }
1130}
1131
a7e3212d
LP
1132int bus_next_address(sd_bus *b) {
1133 assert(b);
1134
1135 bus_reset_parsed_address(b);
1136 return bus_start_address(b);
1137}
1138
021a1e78 1139static int bus_start_fd(sd_bus *b) {
6629161f 1140 struct stat st;
021a1e78
LP
1141 int r;
1142
1143 assert(b);
e82c9509
LP
1144 assert(b->input_fd >= 0);
1145 assert(b->output_fd >= 0);
021a1e78 1146
e82c9509 1147 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
1148 if (r < 0)
1149 return r;
1150
e82c9509 1151 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
1152 if (r < 0)
1153 return r;
1154
e82c9509
LP
1155 if (b->input_fd != b->output_fd) {
1156 r = fd_nonblock(b->output_fd, true);
1157 if (r < 0)
1158 return r;
1159
1160 r = fd_cloexec(b->output_fd, true);
1161 if (r < 0)
1162 return r;
1163 }
1164
6629161f
LP
1165 if (fstat(b->input_fd, &st) < 0)
1166 return -errno;
1167
a132bef0 1168 return bus_socket_take_fd(b);
021a1e78
LP
1169}
1170
d9f644e2 1171_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
1172 int r;
1173
d6888822 1174 assert_return(bus, -EINVAL);
45b1f410 1175 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
1176 assert_return(bus->state == BUS_UNSET, -EPERM);
1177 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 1178
3e0e196e 1179 bus_set_state(bus, BUS_OPENING);
021a1e78 1180
2181a7f5
LP
1181 if (bus->is_server && bus->bus_client)
1182 return -EINVAL;
1183
e82c9509 1184 if (bus->input_fd >= 0)
021a1e78 1185 r = bus_start_fd(bus);
a132bef0 1186 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->machine)
a7e3212d 1187 r = bus_start_address(bus);
021a1e78
LP
1188 else
1189 return -EINVAL;
1190
db9bb83f
LP
1191 if (r < 0) {
1192 sd_bus_close(bus);
021a1e78 1193 return r;
db9bb83f 1194 }
021a1e78
LP
1195
1196 return bus_send_hello(bus);
1197}
1198
56fbd718 1199_public_ int sd_bus_open_with_description(sd_bus **ret, const char *description) {
af08d2f9 1200 const char *e;
9df088f1 1201 _cleanup_(bus_freep) sd_bus *b = NULL;
af08d2f9
LP
1202 int r;
1203
1204 assert_return(ret, -EINVAL);
1205
1206 /* Let's connect to the starter bus if it is set, and
1207 * otherwise to the bus that is appropropriate for the scope
1208 * we are running in */
1209
1210 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
1211 if (e) {
1212 if (streq(e, "system"))
56fbd718 1213 return sd_bus_open_system_with_description(ret, description);
09365592 1214 else if (STR_IN_SET(e, "session", "user"))
56fbd718 1215 return sd_bus_open_user_with_description(ret, description);
af08d2f9
LP
1216 }
1217
1218 e = secure_getenv("DBUS_STARTER_ADDRESS");
1219 if (!e) {
1220 if (cg_pid_get_owner_uid(0, NULL) >= 0)
56fbd718 1221 return sd_bus_open_user_with_description(ret, description);
af08d2f9 1222 else
56fbd718 1223 return sd_bus_open_system_with_description(ret, description);
af08d2f9
LP
1224 }
1225
1226 r = sd_bus_new(&b);
1227 if (r < 0)
1228 return r;
1229
1230 r = sd_bus_set_address(b, e);
1231 if (r < 0)
9df088f1 1232 return r;
af08d2f9
LP
1233
1234 b->bus_client = true;
1235
1236 /* We don't know whether the bus is trusted or not, so better
1237 * be safe, and authenticate everything */
1238 b->trusted = false;
694859b5 1239 b->is_local = false;
cf226cfc 1240 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
af08d2f9
LP
1241
1242 r = sd_bus_start(b);
1243 if (r < 0)
9df088f1 1244 return r;
af08d2f9 1245
9df088f1 1246 *ret = TAKE_PTR(b);
af08d2f9 1247 return 0;
af08d2f9
LP
1248}
1249
56fbd718
ZJS
1250_public_ int sd_bus_open(sd_bus **ret) {
1251 return sd_bus_open_with_description(ret, NULL);
1252}
1253
09365592 1254int bus_set_address_system(sd_bus *b) {
de1c301e 1255 const char *e;
09365592
LP
1256 assert(b);
1257
1258 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1259 if (e)
1260 return sd_bus_set_address(b, e);
1261
057171ef 1262 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
09365592
LP
1263}
1264
56fbd718 1265_public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *description) {
9df088f1 1266 _cleanup_(bus_freep) sd_bus *b = NULL;
de1c301e
LP
1267 int r;
1268
d6888822 1269 assert_return(ret, -EINVAL);
de1c301e 1270
021a1e78
LP
1271 r = sd_bus_new(&b);
1272 if (r < 0)
1273 return r;
1274
56fbd718
ZJS
1275 if (description) {
1276 r = sd_bus_set_description(b, description);
1277 if (r < 0)
9df088f1 1278 return r;
56fbd718
ZJS
1279 }
1280
09365592 1281 r = bus_set_address_system(b);
e3dd987c 1282 if (r < 0)
9df088f1 1283 return r;
de1c301e 1284
94bbf1ba 1285 b->bus_client = true;
5972fe95 1286 b->is_system = true;
021a1e78 1287
adacb957
LP
1288 /* Let's do per-method access control on the system bus. We
1289 * need the caller's UID and capability set for that. */
1290 b->trusted = false;
cf226cfc 1291 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
694859b5 1292 b->is_local = true;
adacb957 1293
021a1e78
LP
1294 r = sd_bus_start(b);
1295 if (r < 0)
9df088f1 1296 return r;
de1c301e 1297
9df088f1 1298 *ret = TAKE_PTR(b);
de1c301e
LP
1299 return 0;
1300}
1301
56fbd718
ZJS
1302_public_ int sd_bus_open_system(sd_bus **ret) {
1303 return sd_bus_open_system_with_description(ret, NULL);
1304}
1305
09365592 1306int bus_set_address_user(sd_bus *b) {
de1c301e 1307 const char *e;
a132bef0 1308 _cleanup_free_ char *ee = NULL, *s = NULL;
de1c301e 1309
09365592 1310 assert(b);
021a1e78 1311
6c03089c 1312 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
09365592
LP
1313 if (e)
1314 return sd_bus_set_address(b, e);
1315
1316 e = secure_getenv("XDG_RUNTIME_DIR");
a132bef0
ZJS
1317 if (!e)
1318 return -ENOENT;
e3dd987c 1319
a132bef0
ZJS
1320 ee = bus_address_escape(e);
1321 if (!ee)
1322 return -ENOMEM;
de1c301e 1323
15ca0a42 1324 if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0)
09365592
LP
1325 return -ENOMEM;
1326
ae2a15bc 1327 b->address = TAKE_PTR(s);
a132bef0 1328
09365592
LP
1329 return 0;
1330}
1331
56fbd718 1332_public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *description) {
9df088f1 1333 _cleanup_(bus_freep) sd_bus *b = NULL;
09365592
LP
1334 int r;
1335
1336 assert_return(ret, -EINVAL);
1337
1338 r = sd_bus_new(&b);
1339 if (r < 0)
1340 return r;
1341
56fbd718
ZJS
1342 if (description) {
1343 r = sd_bus_set_description(b, description);
1344 if (r < 0)
9df088f1 1345 return r;
56fbd718
ZJS
1346 }
1347
09365592
LP
1348 r = bus_set_address_user(b);
1349 if (r < 0)
9df088f1 1350 return r;
09365592 1351
94bbf1ba 1352 b->bus_client = true;
5972fe95 1353 b->is_user = true;
de1c301e 1354
adacb957
LP
1355 /* We don't do any per-method access control on the user
1356 * bus. */
1357 b->trusted = true;
694859b5 1358 b->is_local = true;
adacb957 1359
021a1e78 1360 r = sd_bus_start(b);
2571ead1 1361 if (r < 0)
9df088f1 1362 return r;
de1c301e 1363
9df088f1 1364 *ret = TAKE_PTR(b);
de1c301e
LP
1365 return 0;
1366}
1367
56fbd718
ZJS
1368_public_ int sd_bus_open_user(sd_bus **ret) {
1369 return sd_bus_open_user_with_description(ret, NULL);
1370}
1371
09365592 1372int bus_set_address_system_remote(sd_bus *b, const char *host) {
0f8bd8de 1373 _cleanup_free_ char *e = NULL;
b85b4a70 1374 char *m = NULL, *c = NULL, *a, *rbracket = NULL, *p = NULL;
0f8bd8de 1375
09365592
LP
1376 assert(b);
1377 assert(host);
0f8bd8de 1378
b85b4a70
SL
1379 /* Skip ":"s in ipv6 addresses */
1380 if (*host == '[') {
1381 char *t;
7f0d207d 1382
b85b4a70
SL
1383 rbracket = strchr(host, ']');
1384 if (!rbracket)
1385 return -EINVAL;
1386 t = strndupa(host + 1, rbracket - host - 1);
1387 e = bus_address_escape(t);
1388 if (!e)
1389 return -ENOMEM;
6a555849 1390 } else if ((a = strchr(host, '@'))) {
b85b4a70
SL
1391 if (*(a + 1) == '[') {
1392 _cleanup_free_ char *t = NULL;
1393
1394 rbracket = strchr(a + 1, ']');
1395 if (!rbracket)
1396 return -EINVAL;
1397 t = new0(char, strlen(host));
1398 if (!t)
1399 return -ENOMEM;
1400 strncat(t, host, a - host + 1);
1401 strncat(t, a + 2, rbracket - a - 2);
7f0d207d
LP
1402 e = bus_address_escape(t);
1403 if (!e)
1404 return -ENOMEM;
6a555849
SL
1405 } else if (*(a + 1) == '\0' || strchr(a + 1, '@'))
1406 return -EINVAL;
1407 }
b85b4a70
SL
1408
1409 /* Let's see if a port was given */
1410 m = strchr(rbracket ? rbracket + 1 : host, ':');
1411 if (m) {
1412 char *t;
1413 bool got_forward_slash = false;
7f0d207d 1414
b85b4a70
SL
1415 p = m + 1;
1416
1417 t = strchr(p, '/');
1418 if (t) {
1419 p = strndupa(p, t - p);
1420 got_forward_slash = true;
1421 }
1422
6a555849 1423 if (!in_charset(p, "0123456789") || *p == '\0') {
b85b4a70
SL
1424 if (!machine_name_is_valid(p) || got_forward_slash)
1425 return -EINVAL;
490c5a37
LP
1426
1427 m = TAKE_PTR(p);
1428 goto interpret_port_as_machine_old_syntax;
7f0d207d
LP
1429 }
1430 }
1431
b85b4a70
SL
1432 /* Let's see if a machine was given */
1433 m = strchr(rbracket ? rbracket + 1 : host, '/');
1434 if (m) {
1435 m++;
1436interpret_port_as_machine_old_syntax:
1437 /* Let's make sure this is not a port of some kind,
1438 * and is a valid machine name. */
1439 if (!in_charset(m, "0123456789") && machine_name_is_valid(m))
1440 c = strjoina(",argv", p ? "7" : "5", "=--machine=", m);
1441 }
1442
7f0d207d 1443 if (!e) {
b85b4a70
SL
1444 char *t;
1445
1446 t = strndupa(host, strcspn(host, ":/"));
1447
1448 e = bus_address_escape(t);
7f0d207d
LP
1449 if (!e)
1450 return -ENOMEM;
1451 }
0f8bd8de 1452
b85b4a70
SL
1453 a = strjoin("unixexec:path=ssh,argv1=-xT", p ? ",argv2=-p,argv3=" : "", strempty(p),
1454 ",argv", p ? "4" : "2", "=--,argv", p ? "5" : "3", "=", e,
1455 ",argv", p ? "6" : "4", "=systemd-stdio-bridge", c);
b4ca3f45 1456 if (!a)
0f8bd8de 1457 return -ENOMEM;
a7893c6b 1458
0639f135
ZJS
1459 return free_and_replace(b->address, a);
1460}
09365592
LP
1461
1462_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
9df088f1 1463 _cleanup_(bus_freep) sd_bus *b = NULL;
09365592
LP
1464 int r;
1465
1466 assert_return(host, -EINVAL);
1467 assert_return(ret, -EINVAL);
1468
9df088f1 1469 r = sd_bus_new(&b);
09365592 1470 if (r < 0)
a7893c6b 1471 return r;
a7893c6b 1472
9df088f1 1473 r = bus_set_address_system_remote(b, host);
09365592 1474 if (r < 0)
9df088f1 1475 return r;
09365592 1476
9df088f1
ZJS
1477 b->bus_client = true;
1478 b->trusted = false;
1479 b->is_system = true;
1480 b->is_local = false;
a7893c6b 1481
9df088f1 1482 r = sd_bus_start(b);
09365592 1483 if (r < 0)
9df088f1 1484 return r;
a7893c6b 1485
9df088f1 1486 *ret = TAKE_PTR(b);
a7893c6b
LP
1487 return 0;
1488}
1489
de33fc62 1490int bus_set_address_system_machine(sd_bus *b, const char *machine) {
a7893c6b 1491 _cleanup_free_ char *e = NULL;
b4ca3f45 1492 char *a;
a7893c6b 1493
09365592
LP
1494 assert(b);
1495 assert(machine);
a7893c6b
LP
1496
1497 e = bus_address_escape(machine);
1498 if (!e)
1499 return -ENOMEM;
1500
b4ca3f45
YW
1501 a = strjoin("x-machine-unix:machine=", e);
1502 if (!a)
a7893c6b 1503 return -ENOMEM;
0f8bd8de 1504
0639f135 1505 return free_and_replace(b->address, a);
09365592
LP
1506}
1507
de33fc62 1508_public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
9df088f1 1509 _cleanup_(bus_freep) sd_bus *b = NULL;
09365592
LP
1510 int r;
1511
1512 assert_return(machine, -EINVAL);
1513 assert_return(ret, -EINVAL);
1e5057b9 1514 assert_return(streq(machine, ".host") || machine_name_is_valid(machine), -EINVAL);
09365592 1515
9df088f1 1516 r = sd_bus_new(&b);
09365592 1517 if (r < 0)
0f8bd8de 1518 return r;
0f8bd8de 1519
9df088f1 1520 r = bus_set_address_system_machine(b, machine);
09365592 1521 if (r < 0)
9df088f1 1522 return r;
09365592 1523
9df088f1
ZJS
1524 b->bus_client = true;
1525 b->trusted = false;
1526 b->is_system = true;
1527 b->is_local = false;
0f8bd8de 1528
9df088f1 1529 r = sd_bus_start(b);
09365592 1530 if (r < 0)
9df088f1 1531 return r;
0f8bd8de 1532
9df088f1 1533 *ret = TAKE_PTR(b);
0f8bd8de
LP
1534 return 0;
1535}
1536
d9f644e2 1537_public_ void sd_bus_close(sd_bus *bus) {
de1c301e
LP
1538 if (!bus)
1539 return;
d5a2b9a6
LP
1540 if (bus->state == BUS_CLOSED)
1541 return;
1542 if (bus_pid_changed(bus))
f54514f3
LP
1543 return;
1544
392cf1d0
SL
1545 /* Don't leave ssh hanging around */
1546 bus_kill_exec(bus);
1547
3e0e196e 1548 bus_set_state(bus, BUS_CLOSED);
e82c9509 1549
40ca29a1
LP
1550 sd_bus_detach_event(bus);
1551
0e586eae
LP
1552 /* Drop all queued messages so that they drop references to
1553 * the bus object and the bus may be freed */
1554 bus_reset_queues(bus);
1555
8a5cd31e
LP
1556 bus_close_io_fds(bus);
1557 bus_close_inotify_fd(bus);
de1c301e
LP
1558}
1559
03976f7b 1560_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
03976f7b
LP
1561 if (!bus)
1562 return NULL;
1563
392cf1d0
SL
1564 /* Have to do this before flush() to prevent hang */
1565 bus_kill_exec(bus);
1566
03976f7b
LP
1567 sd_bus_flush(bus);
1568 sd_bus_close(bus);
1569
1570 return sd_bus_unref(bus);
1571}
1572
98c5bbc8 1573void bus_enter_closing(sd_bus *bus) {
718db961
LP
1574 assert(bus);
1575
8a5cd31e 1576 if (!IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING))
718db961
LP
1577 return;
1578
3e0e196e 1579 bus_set_state(bus, BUS_CLOSING);
718db961
LP
1580}
1581
1c71f7f3 1582DEFINE_PUBLIC_ATOMIC_REF_UNREF_FUNC(sd_bus, sd_bus, bus_free);
de1c301e 1583
d9f644e2 1584_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822 1585 assert_return(bus, -EINVAL);
45b1f410 1586 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 1587 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1588
f54514f3 1589 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1590}
1591
bdbc8669
LP
1592_public_ int sd_bus_is_ready(sd_bus *bus) {
1593 assert_return(bus, -EINVAL);
45b1f410 1594 assert_return(bus = bus_resolve(bus), -ENOPKG);
bdbc8669
LP
1595 assert_return(!bus_pid_changed(bus), -ECHILD);
1596
1597 return bus->state == BUS_RUNNING;
1598}
1599
d9f644e2 1600_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1601 int r;
1602
d6888822 1603 assert_return(bus, -EINVAL);
45b1f410 1604 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
1605 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1606 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1607
c7db1984 1608 if (bus->is_monitor)
09365592
LP
1609 return 0;
1610
d728d708 1611 if (type == SD_BUS_TYPE_UNIX_FD) {
c7db1984 1612 if (!bus->accept_fd)
021a1e78
LP
1613 return 0;
1614
20902f3e 1615 r = bus_ensure_running(bus);
d728d708
LP
1616 if (r < 0)
1617 return r;
de1c301e 1618
d728d708
LP
1619 return bus->can_fds;
1620 }
1621
1622 return bus_type_is_valid(type);
de1c301e
LP
1623}
1624
5c302692 1625_public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
d728d708 1626 int r;
de1c301e 1627
d6888822 1628 assert_return(bus, -EINVAL);
45b1f410 1629 assert_return(bus = bus_resolve(bus), -ENOPKG);
f7fce345 1630 assert_return(id, -EINVAL);
d6888822 1631 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1632
20902f3e 1633 r = bus_ensure_running(bus);
d728d708
LP
1634 if (r < 0)
1635 return r;
de1c301e 1636
f7fce345 1637 *id = bus->server_id;
d728d708 1638 return 0;
de1c301e
LP
1639}
1640
3df7a7e6 1641static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
48ef41a3
LP
1642 int r;
1643
7adc46fc 1644 assert(b);
de1c301e
LP
1645 assert(m);
1646
aea93deb
LP
1647 if (m->sealed) {
1648 /* If we copy the same message to multiple
693eb9a2 1649 * destinations, avoid using the same cookie
aea93deb 1650 * numbers. */
693eb9a2 1651 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
de1c301e 1652 return 0;
aea93deb 1653 }
de1c301e 1654
385b2eb2
YW
1655 if (timeout == 0) {
1656 r = sd_bus_get_method_call_timeout(b, &timeout);
1657 if (r < 0)
1658 return r;
1659 }
3df7a7e6 1660
48ef41a3
LP
1661 if (!m->sender && b->patch_sender) {
1662 r = sd_bus_message_set_sender(m, b->patch_sender);
1663 if (r < 0)
1664 return r;
1665 }
1666
75bcbcf2 1667 return sd_bus_message_seal(m, ++b->cookie, timeout);
de1c301e
LP
1668}
1669
e1c433c6 1670static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
908b8a42
DH
1671 bool remarshal = false;
1672
e1c433c6
LP
1673 assert(b);
1674
908b8a42
DH
1675 /* wrong packet version */
1676 if (b->message_version != 0 && b->message_version != (*m)->header->version)
1677 remarshal = true;
1678
1679 /* wrong packet endianness */
1680 if (b->message_endian != 0 && b->message_endian != (*m)->header->endian)
1681 remarshal = true;
1682
908b8a42 1683 return remarshal ? bus_message_remarshal(b, m) : 0;
e1c433c6
LP
1684}
1685
7adc46fc
LP
1686int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1687 assert(b);
1688 assert(m);
1689
52cd5877
LP
1690 /* Fake some timestamps, if they were requested, and not
1691 * already initialized */
c7db1984 1692 if (b->attach_timestamp) {
52cd5877
LP
1693 if (m->realtime <= 0)
1694 m->realtime = now(CLOCK_REALTIME);
1695
1696 if (m->monotonic <= 0)
1697 m->monotonic = now(CLOCK_MONOTONIC);
1698 }
1699
7adc46fc
LP
1700 /* The bus specification says the serial number cannot be 0,
1701 * hence let's fill something in for synthetic messages. Since
1702 * synthetic messages might have a fake sender and we don't
1703 * want to interfere with the real sender's serial numbers we
6f285378 1704 * pick a fixed, artificial one. We use (uint32_t) -1 rather
7adc46fc
LP
1705 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1706 * even though kdbus can do 64bit. */
75bcbcf2 1707 return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
7adc46fc
LP
1708}
1709
66baf8c6 1710static int bus_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
2e3db52d
LP
1711 int r;
1712
718db961 1713 assert(bus);
2e3db52d 1714 assert(m);
718db961 1715
a132bef0 1716 r = bus_socket_write_message(bus, m, idx);
2e3db52d
LP
1717 if (r <= 0)
1718 return r;
1719
a132bef0 1720 if (*idx >= BUS_MESSAGE_SIZE(m))
e32fd6b4 1721 log_debug("Sent message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s",
2e3db52d
LP
1722 bus_message_type_to_string(m->header->type),
1723 strna(sd_bus_message_get_sender(m)),
1724 strna(sd_bus_message_get_destination(m)),
1725 strna(sd_bus_message_get_path(m)),
1726 strna(sd_bus_message_get_interface(m)),
1727 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
1728 BUS_MESSAGE_COOKIE(m),
1729 m->reply_cookie,
e32fd6b4 1730 strna(m->root_container.signature),
e28d0865 1731 strna(m->error.name),
2e3db52d
LP
1732 strna(m->error.message));
1733
1734 return r;
718db961
LP
1735}
1736
de1c301e 1737static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1738 int r, ret = 0;
de1c301e
LP
1739
1740 assert(bus);
945c2931 1741 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
de1c301e 1742
de1c301e
LP
1743 while (bus->wqueue_size > 0) {
1744
66baf8c6 1745 r = bus_write_message(bus, bus->wqueue[0], &bus->windex);
718db961 1746 if (r < 0)
de1c301e 1747 return r;
718db961 1748 else if (r == 0)
e3017af9
LP
1749 /* Didn't do anything this time */
1750 return ret;
a132bef0 1751 else if (bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1752 /* Fully written. Let's drop the entry from
1753 * the queue.
1754 *
1755 * This isn't particularly optimized, but
1756 * well, this is supposed to be our worst-case
1757 * buffer only, and the socket buffer is
1758 * supposed to be our primary buffer, and if
1759 * it got full, then all bets are off
1760 * anyway. */
1761
313cefa1 1762 bus->wqueue_size--;
c4e6e242 1763 sd_bus_message_unref(bus->wqueue[0]);
de1c301e
LP
1764 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1765 bus->windex = 0;
1766
e3017af9 1767 ret = 1;
de1c301e
LP
1768 }
1769 }
1770
e3017af9 1771 return ret;
de1c301e
LP
1772}
1773
766c5809 1774static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
7d22c717
LP
1775 assert(bus);
1776
a132bef0 1777 return bus_socket_read_message(bus);
7d22c717
LP
1778}
1779
7adc46fc 1780int bus_rqueue_make_room(sd_bus *bus) {
821e0756 1781 assert(bus);
7d22c717 1782
821e0756 1783 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
7d22c717
LP
1784 return -ENOBUFS;
1785
821e0756 1786 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
7d22c717
LP
1787 return -ENOMEM;
1788
7d22c717
LP
1789 return 0;
1790}
1791
766c5809 1792static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
e3017af9 1793 int r, ret = 0;
de1c301e
LP
1794
1795 assert(bus);
1796 assert(m);
945c2931 1797 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
de1c301e 1798
766c5809
LP
1799 /* Note that the priority logic is only available on kdbus,
1800 * where the rqueue is unused. We check the rqueue here
1801 * anyway, because it's simple... */
1802
7d22c717
LP
1803 for (;;) {
1804 if (bus->rqueue_size > 0) {
1805 /* Dispatch a queued message */
de1c301e 1806
7d22c717 1807 *m = bus->rqueue[0];
313cefa1 1808 bus->rqueue_size--;
7d22c717
LP
1809 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1810 return 1;
1811 }
de1c301e 1812
7d22c717 1813 /* Try to read a new message */
766c5809 1814 r = bus_read_message(bus, hint_priority, priority);
718db961 1815 if (r < 0)
e3017af9 1816 return r;
e3017af9
LP
1817 if (r == 0)
1818 return ret;
de1c301e 1819
2e8d788c 1820 ret = 1;
7d22c717 1821 }
de1c301e
LP
1822}
1823
66baf8c6 1824_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
4afd3348 1825 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e
LP
1826 int r;
1827
d6888822 1828 assert_return(m, -EINVAL);
9030ca46
LP
1829
1830 if (!bus)
1831 bus = m->bus;
1832
d6888822 1833 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 1834
a3d59cd1
LP
1835 if (!BUS_IS_OPEN(bus->state))
1836 return -ENOTCONN;
1837
021a1e78
LP
1838 if (m->n_fds > 0) {
1839 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1840 if (r < 0)
1841 return r;
1842 if (r == 0)
15411c0c 1843 return -EOPNOTSUPP;
021a1e78 1844 }
de1c301e 1845
693eb9a2 1846 /* If the cookie number isn't kept, then we know that no reply
29f6aadd 1847 * is expected */
693eb9a2 1848 if (!cookie && !m->sealed)
0461f8cd 1849 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1850
3df7a7e6 1851 r = bus_seal_message(bus, m, 0);
de1c301e
LP
1852 if (r < 0)
1853 return r;
1854
441d56a1 1855 /* Remarshall if we have to. This will possibly unref the
e1c433c6
LP
1856 * message and place a replacement in m */
1857 r = bus_remarshal_message(bus, &m);
1858 if (r < 0)
1859 return r;
1860
5407f2de
LP
1861 /* If this is a reply and no reply was requested, then let's
1862 * suppress this, if we can */
997eadb5
LP
1863 if (m->dont_send)
1864 goto finish;
5407f2de 1865
945c2931 1866 if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1867 size_t idx = 0;
1868
66baf8c6 1869 r = bus_write_message(bus, m, &idx);
32f46480 1870 if (r < 0) {
103a5027 1871 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 1872 bus_enter_closing(bus);
441d56a1
LP
1873 return -ECONNRESET;
1874 }
32f46480 1875
de1c301e 1876 return r;
997eadb5
LP
1877 }
1878
a132bef0 1879 if (idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1880 /* Wasn't fully written. So let's remember how
1881 * much was written. Note that the first entry
1882 * of the wqueue array is always allocated so
1883 * that we always can remember how much was
1884 * written. */
1885 bus->wqueue[0] = sd_bus_message_ref(m);
1886 bus->wqueue_size = 1;
1887 bus->windex = idx;
1888 }
997eadb5 1889
de1c301e 1890 } else {
de1c301e
LP
1891 /* Just append it to the queue. */
1892
25220239 1893 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1894 return -ENOBUFS;
1895
821e0756 1896 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
de1c301e
LP
1897 return -ENOMEM;
1898
313cefa1 1899 bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
de1c301e
LP
1900 }
1901
997eadb5 1902finish:
693eb9a2
LP
1903 if (cookie)
1904 *cookie = BUS_MESSAGE_COOKIE(m);
de1c301e 1905
7a37d625 1906 return 1;
de1c301e
LP
1907}
1908
693eb9a2 1909_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
911121a7
LP
1910 int r;
1911
911121a7 1912 assert_return(m, -EINVAL);
9030ca46
LP
1913
1914 if (!bus)
1915 bus = m->bus;
1916
911121a7
LP
1917 assert_return(!bus_pid_changed(bus), -ECHILD);
1918
a3d59cd1
LP
1919 if (!BUS_IS_OPEN(bus->state))
1920 return -ENOTCONN;
1921
911121a7
LP
1922 if (!streq_ptr(m->destination, destination)) {
1923
1924 if (!destination)
1925 return -EEXIST;
1926
1927 r = sd_bus_message_set_destination(m, destination);
1928 if (r < 0)
1929 return r;
1930 }
1931
693eb9a2 1932 return sd_bus_send(bus, m, cookie);
911121a7
LP
1933}
1934
ac8029fc
LP
1935static usec_t calc_elapse(sd_bus *bus, uint64_t usec) {
1936 assert(bus);
1937
de1c301e
LP
1938 if (usec == (uint64_t) -1)
1939 return 0;
1940
ac8029fc
LP
1941 /* We start all timeouts the instant we enter BUS_HELLO/BUS_RUNNING state, so that the don't run in parallel
1942 * with any connection setup states. Hence, if a method callback is started earlier than that we just store the
1943 * relative timestamp, and afterwards the absolute one. */
1944
1945 if (IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING))
1946 return usec;
1947 else
1948 return now(CLOCK_MONOTONIC) + usec;
de1c301e
LP
1949}
1950
e3017af9
LP
1951static int timeout_compare(const void *a, const void *b) {
1952 const struct reply_callback *x = a, *y = b;
1953
ac8029fc 1954 if (x->timeout_usec != 0 && y->timeout_usec == 0)
e3017af9
LP
1955 return -1;
1956
ac8029fc 1957 if (x->timeout_usec == 0 && y->timeout_usec != 0)
e3017af9
LP
1958 return 1;
1959
9c57a73b 1960 return CMP(x->timeout_usec, y->timeout_usec);
e3017af9
LP
1961}
1962
c49b30a2 1963_public_ int sd_bus_call_async(
de1c301e 1964 sd_bus *bus,
19befb2d 1965 sd_bus_slot **slot,
e1c433c6 1966 sd_bus_message *_m,
52f3ba91 1967 sd_bus_message_handler_t callback,
de1c301e 1968 void *userdata,
19befb2d 1969 uint64_t usec) {
de1c301e 1970
4afd3348
LP
1971 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1972 _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
de1c301e
LP
1973 int r;
1974
d6888822 1975 assert_return(m, -EINVAL);
40ca29a1 1976 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
dbc526f0 1977 assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL);
9030ca46
LP
1978
1979 if (!bus)
1980 bus = m->bus;
1981
d6888822 1982 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a 1983
a3d59cd1
LP
1984 if (!BUS_IS_OPEN(bus->state))
1985 return -ENOTCONN;
1986
dbc526f0
LP
1987 /* If no callback is specified and there's no interest in a slot, then there's no reason to ask for a reply */
1988 if (!callback && !slot && !m->sealed)
1989 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1990
c9fe4af7 1991 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
89ffcd2a
LP
1992 if (r < 0)
1993 return r;
de1c301e 1994
3df7a7e6
LP
1995 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1996 if (r < 0)
1997 return r;
e3017af9 1998
3df7a7e6 1999 r = bus_seal_message(bus, m, usec);
de1c301e
LP
2000 if (r < 0)
2001 return r;
2002
e1c433c6
LP
2003 r = bus_remarshal_message(bus, &m);
2004 if (r < 0)
2005 return r;
2006
dbc526f0
LP
2007 if (slot || callback) {
2008 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
2009 if (!s)
2010 return -ENOMEM;
de1c301e 2011
dbc526f0 2012 s->reply_callback.callback = callback;
de1c301e 2013
dbc526f0
LP
2014 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
2015 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
e3017af9 2016 if (r < 0) {
dbc526f0 2017 s->reply_callback.cookie = 0;
e3017af9
LP
2018 return r;
2019 }
dbc526f0
LP
2020
2021 s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout);
2022 if (s->reply_callback.timeout_usec != 0) {
2023 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
2024 if (r < 0) {
2025 s->reply_callback.timeout_usec = 0;
2026 return r;
2027 }
2028 }
e3017af9
LP
2029 }
2030
dbc526f0 2031 r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL);
19befb2d 2032 if (r < 0)
de1c301e 2033 return r;
de1c301e 2034
19befb2d
LP
2035 if (slot)
2036 *slot = s;
2037 s = NULL;
e3017af9 2038
19befb2d 2039 return r;
de1c301e
LP
2040}
2041
20902f3e 2042int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
2043 int r;
2044
2045 assert(bus);
2046
945c2931 2047 if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING))
021a1e78 2048 return -ENOTCONN;
d728d708
LP
2049 if (bus->state == BUS_RUNNING)
2050 return 1;
89ffcd2a
LP
2051
2052 for (;;) {
2053 r = sd_bus_process(bus, NULL);
2054 if (r < 0)
2055 return r;
d728d708
LP
2056 if (bus->state == BUS_RUNNING)
2057 return 1;
e3017af9
LP
2058 if (r > 0)
2059 continue;
89ffcd2a
LP
2060
2061 r = sd_bus_wait(bus, (uint64_t) -1);
2062 if (r < 0)
2063 return r;
2064 }
2065}
2066
97f82db3 2067_public_ int sd_bus_call(
de1c301e 2068 sd_bus *bus,
97f82db3 2069 sd_bus_message *_m,
de1c301e
LP
2070 uint64_t usec,
2071 sd_bus_error *error,
2072 sd_bus_message **reply) {
2073
4afd3348 2074 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e 2075 usec_t timeout;
693eb9a2 2076 uint64_t cookie;
7d22c717
LP
2077 unsigned i;
2078 int r;
de1c301e 2079
759e02e7
LP
2080 bus_assert_return(m, -EINVAL, error);
2081 bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
2082 bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
2083 bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
9030ca46
LP
2084
2085 if (!bus)
2086 bus = m->bus;
2087
759e02e7 2088 bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
97f82db3 2089
759e02e7
LP
2090 if (!BUS_IS_OPEN(bus->state)) {
2091 r = -ENOTCONN;
2092 goto fail;
2093 }
a3d59cd1 2094
97f82db3
KS
2095 r = bus_ensure_running(bus);
2096 if (r < 0)
759e02e7 2097 goto fail;
97f82db3 2098
a43b9ca3 2099 i = bus->rqueue_size;
97f82db3
KS
2100
2101 r = bus_seal_message(bus, m, usec);
2102 if (r < 0)
759e02e7 2103 goto fail;
97f82db3
KS
2104
2105 r = bus_remarshal_message(bus, &m);
2106 if (r < 0)
759e02e7 2107 goto fail;
97f82db3 2108
66baf8c6 2109 r = sd_bus_send(bus, m, &cookie);
de1c301e 2110 if (r < 0)
759e02e7 2111 goto fail;
de1c301e 2112
ac8029fc 2113 timeout = calc_elapse(bus, m->timeout);
de1c301e
LP
2114
2115 for (;;) {
2116 usec_t left;
de1c301e 2117
7d22c717
LP
2118 while (i < bus->rqueue_size) {
2119 sd_bus_message *incoming = NULL;
2120
2121 incoming = bus->rqueue[i];
89ffcd2a 2122
693eb9a2 2123 if (incoming->reply_cookie == cookie) {
de1c301e
LP
2124 /* Found a match! */
2125
7d22c717
LP
2126 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
2127 bus->rqueue_size--;
f9f97ca6 2128 log_debug_bus_message(incoming);
7d22c717 2129
40ca29a1 2130 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0 2131
c7db1984 2132 if (incoming->n_fds <= 0 || bus->accept_fd) {
2ce97e2b
LP
2133 if (reply)
2134 *reply = incoming;
2135 else
2136 sd_bus_message_unref(incoming);
2137
2138 return 1;
2139 }
2140
2141 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
759e02e7
LP
2142 sd_bus_message_unref(incoming);
2143 return r;
b7f247e0 2144
759e02e7 2145 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
de1c301e 2146 r = sd_bus_error_copy(error, &incoming->error);
759e02e7
LP
2147 sd_bus_message_unref(incoming);
2148 return r;
2149 } else {
a43b9ca3 2150 r = -EIO;
759e02e7
LP
2151 goto fail;
2152 }
a8a07f89 2153
693eb9a2 2154 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
a8a07f89
LP
2155 bus->unique_name &&
2156 incoming->sender &&
2157 streq(bus->unique_name, incoming->sender)) {
2158
7d22c717
LP
2159 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
2160 bus->rqueue_size--;
2161
a8a07f89
LP
2162 /* Our own message? Somebody is trying
2163 * to send its own client a message,
2164 * let's not dead-lock, let's fail
2165 * immediately. */
2166
2167 sd_bus_message_unref(incoming);
759e02e7
LP
2168 r = -ELOOP;
2169 goto fail;
de1c301e
LP
2170 }
2171
de1c301e 2172 /* Try to read more, right-away */
7d22c717 2173 i++;
de1c301e 2174 }
7d22c717 2175
766c5809 2176 r = bus_read_message(bus, false, 0);
32f46480 2177 if (r < 0) {
103a5027 2178 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 2179 bus_enter_closing(bus);
759e02e7 2180 r = -ECONNRESET;
441d56a1 2181 }
32f46480 2182
759e02e7 2183 goto fail;
32f46480 2184 }
7d22c717 2185 if (r > 0)
e3017af9 2186 continue;
de1c301e
LP
2187
2188 if (timeout > 0) {
2189 usec_t n;
2190
2191 n = now(CLOCK_MONOTONIC);
759e02e7
LP
2192 if (n >= timeout) {
2193 r = -ETIMEDOUT;
2194 goto fail;
2195 }
de1c301e
LP
2196
2197 left = timeout - n;
2198 } else
2199 left = (uint64_t) -1;
2200
e3017af9 2201 r = bus_poll(bus, true, left);
de1c301e 2202 if (r < 0)
759e02e7
LP
2203 goto fail;
2204 if (r == 0) {
2205 r = -ETIMEDOUT;
2206 goto fail;
2207 }
de1c301e
LP
2208
2209 r = dispatch_wqueue(bus);
32f46480 2210 if (r < 0) {
103a5027 2211 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 2212 bus_enter_closing(bus);
759e02e7 2213 r = -ECONNRESET;
441d56a1 2214 }
32f46480 2215
759e02e7 2216 goto fail;
32f46480 2217 }
de1c301e 2218 }
759e02e7
LP
2219
2220fail:
2221 return sd_bus_error_set_errno(error, r);
de1c301e
LP
2222}
2223
d9f644e2 2224_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
2225
2226 assert_return(bus, -EINVAL);
45b1f410 2227 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
2228 assert_return(bus->input_fd == bus->output_fd, -EPERM);
2229 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2230
8a5cd31e
LP
2231 if (bus->state == BUS_CLOSED)
2232 return -ENOTCONN;
2233
2234 if (bus->inotify_fd >= 0)
2235 return bus->inotify_fd;
2236
2237 if (bus->input_fd >= 0)
2238 return bus->input_fd;
2239
2240 return -ENOTCONN;
de1c301e
LP
2241}
2242
d9f644e2 2243_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
2244 int flags = 0;
2245
d6888822 2246 assert_return(bus, -EINVAL);
45b1f410 2247 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 2248 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2249
8a5cd31e
LP
2250 switch (bus->state) {
2251
2252 case BUS_UNSET:
2253 case BUS_CLOSED:
a3d59cd1
LP
2254 return -ENOTCONN;
2255
8a5cd31e
LP
2256 case BUS_WATCH_BIND:
2257 flags |= POLLIN;
2258 break;
2259
2260 case BUS_OPENING:
de1c301e 2261 flags |= POLLOUT;
8a5cd31e 2262 break;
89ffcd2a 2263
8a5cd31e 2264 case BUS_AUTHENTICATING:
2181a7f5 2265 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
2266 flags |= POLLOUT;
2267
2268 flags |= POLLIN;
8a5cd31e 2269 break;
89ffcd2a 2270
8a5cd31e
LP
2271 case BUS_RUNNING:
2272 case BUS_HELLO:
de1c301e
LP
2273 if (bus->rqueue_size <= 0)
2274 flags |= POLLIN;
2275 if (bus->wqueue_size > 0)
2276 flags |= POLLOUT;
8a5cd31e
LP
2277 break;
2278
2279 case BUS_CLOSING:
2280 break;
2281
2282 default:
2283 assert_not_reached("Unknown state");
de1c301e
LP
2284 }
2285
2286 return flags;
2287}
2288
d9f644e2 2289_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
2290 struct reply_callback *c;
2291
d6888822 2292 assert_return(bus, -EINVAL);
45b1f410 2293 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 2294 assert_return(timeout_usec, -EINVAL);
d6888822 2295 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 2296
a3d59cd1
LP
2297 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2298 return -ENOTCONN;
2299
8f8f05a9
LP
2300 if (bus->track_queue) {
2301 *timeout_usec = 0;
2302 return 1;
2303 }
2304
8a5cd31e 2305 switch (bus->state) {
718db961 2306
8a5cd31e 2307 case BUS_AUTHENTICATING:
e3017af9
LP
2308 *timeout_usec = bus->auth_timeout;
2309 return 1;
e3017af9 2310
8a5cd31e
LP
2311 case BUS_RUNNING:
2312 case BUS_HELLO:
2313 if (bus->rqueue_size > 0) {
2314 *timeout_usec = 0;
2315 return 1;
2316 }
2317
2318 c = prioq_peek(bus->reply_callbacks_prioq);
2319 if (!c) {
2320 *timeout_usec = (uint64_t) -1;
2321 return 0;
2322 }
2323
ac8029fc 2324 if (c->timeout_usec == 0) {
8a5cd31e
LP
2325 *timeout_usec = (uint64_t) -1;
2326 return 0;
2327 }
2328
ac8029fc 2329 *timeout_usec = c->timeout_usec;
8a5cd31e 2330 return 1;
e3017af9 2331
8a5cd31e 2332 case BUS_CLOSING:
8efd6381
LP
2333 *timeout_usec = 0;
2334 return 1;
8efd6381 2335
8a5cd31e
LP
2336 case BUS_WATCH_BIND:
2337 case BUS_OPENING:
adee69fa 2338 *timeout_usec = (uint64_t) -1;
e3017af9
LP
2339 return 0;
2340
8a5cd31e
LP
2341 default:
2342 assert_not_reached("Unknown or unexpected stat");
19befb2d 2343 }
e3017af9
LP
2344}
2345
2346static int process_timeout(sd_bus *bus) {
4afd3348
LP
2347 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2348 _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
e3017af9 2349 struct reply_callback *c;
1b64f838 2350 sd_bus_slot *slot;
b057498a 2351 bool is_hello;
e3017af9
LP
2352 usec_t n;
2353 int r;
2354
2355 assert(bus);
ac8029fc 2356 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
e3017af9
LP
2357
2358 c = prioq_peek(bus->reply_callbacks_prioq);
2359 if (!c)
2360 return 0;
2361
2362 n = now(CLOCK_MONOTONIC);
ac8029fc 2363 if (c->timeout_usec > n)
e3017af9
LP
2364 return 0;
2365
eb01ba5d
LP
2366 r = bus_message_new_synthetic_error(
2367 bus,
693eb9a2 2368 c->cookie,
14c24659 2369 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
2370 &m);
2371 if (r < 0)
2372 return r;
2373
7adc46fc 2374 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2375 if (r < 0)
2376 return r;
2377
e3017af9 2378 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
ac8029fc 2379 c->timeout_usec = 0;
19befb2d 2380
c9fe4af7 2381 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2382 c->cookie = 0;
2383
1b64f838 2384 slot = container_of(c, sd_bus_slot, reply_callback);
e3017af9 2385
313cefa1 2386 bus->iteration_counter++;
718db961 2387
b057498a
LP
2388 is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
2389
1b64f838
LP
2390 bus->current_message = m;
2391 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2392 bus->current_handler = c->callback;
2393 bus->current_userdata = slot->userdata;
19070062 2394 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2395 bus->current_userdata = NULL;
2396 bus->current_handler = NULL;
d974ad05 2397 bus->current_slot = NULL;
19befb2d 2398 bus->current_message = NULL;
718db961 2399
2e7e8e34
YW
2400 if (slot->floating)
2401 bus_slot_disconnect(slot, true);
1b64f838 2402
d974ad05
DH
2403 sd_bus_slot_unref(slot);
2404
8a5cd31e
LP
2405 /* When this is the hello message and it timed out, then make sure to propagate the error up, don't just log
2406 * and ignore the callback handler's return value. */
b057498a
LP
2407 if (is_hello)
2408 return r;
2409
1b64f838 2410 return bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
2411}
2412
9d373862
LP
2413static int process_hello(sd_bus *bus, sd_bus_message *m) {
2414 assert(bus);
2415 assert(m);
2416
2417 if (bus->state != BUS_HELLO)
2418 return 0;
2419
2420 /* Let's make sure the first message on the bus is the HELLO
2421 * reply. But note that we don't actually parse the message
2181a7f5
LP
2422 * here (we leave that to the usual handling), we just verify
2423 * we don't let any earlier msg through. */
9d373862 2424
945c2931 2425 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
9d373862
LP
2426 return -EIO;
2427
19befb2d 2428 if (m->reply_cookie != 1)
9d373862
LP
2429 return -EIO;
2430
2431 return 0;
2432}
2433
a652755d 2434static int process_reply(sd_bus *bus, sd_bus_message *m) {
4afd3348
LP
2435 _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL;
2436 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
19befb2d 2437 struct reply_callback *c;
1b64f838 2438 sd_bus_slot *slot;
b057498a 2439 bool is_hello;
a652755d
LP
2440 int r;
2441
2442 assert(bus);
2443 assert(m);
2444
945c2931 2445 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
a652755d
LP
2446 return 0;
2447
09365592
LP
2448 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2449 return 0;
2450
c9fe4af7 2451 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
a652755d
LP
2452 if (!c)
2453 return 0;
2454
19befb2d 2455 c->cookie = 0;
19befb2d 2456
1b64f838 2457 slot = container_of(c, sd_bus_slot, reply_callback);
a652755d 2458
c7db1984 2459 if (m->n_fds > 0 && !bus->accept_fd) {
2ce97e2b
LP
2460
2461 /* If the reply contained a file descriptor which we
2462 * didn't want we pass an error instead. */
2463
2464 r = bus_message_new_synthetic_error(
2465 bus,
2466 m->reply_cookie,
2467 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2468 &synthetic_reply);
2469 if (r < 0)
1b64f838 2470 return r;
2ce97e2b 2471
52cd5877
LP
2472 /* Copy over original timestamp */
2473 synthetic_reply->realtime = m->realtime;
2474 synthetic_reply->monotonic = m->monotonic;
2475 synthetic_reply->seqnum = m->seqnum;
2476
2ce97e2b
LP
2477 r = bus_seal_synthetic_message(bus, synthetic_reply);
2478 if (r < 0)
1b64f838 2479 return r;
2ce97e2b
LP
2480
2481 m = synthetic_reply;
2482 } else {
2483 r = sd_bus_message_rewind(m, true);
2484 if (r < 0)
1b64f838 2485 return r;
2ce97e2b 2486 }
88fe224c 2487
ac8029fc 2488 if (c->timeout_usec != 0) {
1b64f838 2489 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
ac8029fc 2490 c->timeout_usec = 0;
1b64f838 2491 }
19befb2d 2492
b057498a
LP
2493 is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
2494
1b64f838 2495 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2496 bus->current_handler = c->callback;
2497 bus->current_userdata = slot->userdata;
19070062 2498 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2499 bus->current_userdata = NULL;
2500 bus->current_handler = NULL;
d974ad05 2501 bus->current_slot = NULL;
a652755d 2502
2e7e8e34
YW
2503 if (slot->floating)
2504 bus_slot_disconnect(slot, true);
19befb2d 2505
d974ad05
DH
2506 sd_bus_slot_unref(slot);
2507
8a5cd31e
LP
2508 /* When this is the hello message and it failed, then make sure to propagate the error up, don't just log and
2509 * ignore the callback handler's return value. */
b057498a
LP
2510 if (is_hello)
2511 return r;
2512
1b64f838 2513 return bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
2514}
2515
2516static int process_filter(sd_bus *bus, sd_bus_message *m) {
4afd3348 2517 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
2518 struct filter_callback *l;
2519 int r;
2520
392d5b37
LP
2521 assert(bus);
2522 assert(m);
2523
7286037f
LP
2524 do {
2525 bus->filter_callbacks_modified = false;
2526
2527 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1b64f838 2528 sd_bus_slot *slot;
7286037f
LP
2529
2530 if (bus->filter_callbacks_modified)
2531 break;
2532
2533 /* Don't run this more than once per iteration */
2534 if (l->last_iteration == bus->iteration_counter)
2535 continue;
2536
2537 l->last_iteration = bus->iteration_counter;
2538
88fe224c
LP
2539 r = sd_bus_message_rewind(m, true);
2540 if (r < 0)
2541 return r;
2542
1b64f838
LP
2543 slot = container_of(l, sd_bus_slot, filter_callback);
2544
2545 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2546 bus->current_handler = l->callback;
2547 bus->current_userdata = slot->userdata;
19070062 2548 r = l->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2549 bus->current_userdata = NULL;
2550 bus->current_handler = NULL;
1b64f838 2551 bus->current_slot = sd_bus_slot_unref(slot);
19befb2d 2552
ebcf1f97 2553 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
2554 if (r != 0)
2555 return r;
2556
2557 }
2558
2559 } while (bus->filter_callbacks_modified);
a652755d
LP
2560
2561 return 0;
2562}
2563
392d5b37 2564static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
2565 int r;
2566
392d5b37
LP
2567 assert(bus);
2568 assert(m);
2569
7286037f
LP
2570 do {
2571 bus->match_callbacks_modified = false;
2572
eb01ba5d 2573 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
2574 if (r != 0)
2575 return r;
2576
2577 } while (bus->match_callbacks_modified);
2578
2579 return 0;
392d5b37
LP
2580}
2581
b9bf7e2b 2582static int process_builtin(sd_bus *bus, sd_bus_message *m) {
4afd3348 2583 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
b9bf7e2b
LP
2584 int r;
2585
2586 assert(bus);
2587 assert(m);
2588
c7db1984 2589 if (bus->is_monitor)
09365592
LP
2590 return 0;
2591
758bf0c7
LP
2592 if (bus->manual_peer_interface)
2593 return 0;
2594
40ca29a1 2595 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2596 return 0;
2597
2598 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2599 return 0;
2600
0461f8cd 2601 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2602 return 1;
2603
2604 if (streq_ptr(m->member, "Ping"))
df2d202e 2605 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2606 else if (streq_ptr(m->member, "GetMachineId")) {
2607 sd_id128_t id;
2608 char sid[33];
2609
2610 r = sd_id128_get_machine(&id);
2611 if (r < 0)
2612 return r;
2613
df2d202e 2614 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2615 if (r < 0)
2616 return r;
2617
2618 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2619 } else {
29ddb38f 2620 r = sd_bus_message_new_method_errorf(
df2d202e 2621 m, &reply,
40ca29a1 2622 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2623 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2624 }
2625
2626 if (r < 0)
2627 return r;
2628
2629 r = sd_bus_send(bus, reply, NULL);
2630 if (r < 0)
2631 return r;
2632
2633 return 1;
2634}
2635
2ce97e2b
LP
2636static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2637 assert(bus);
2638 assert(m);
2639
2640 /* If we got a message with a file descriptor which we didn't
2641 * want to accept, then let's drop it. How can this even
2642 * happen? For example, when the kernel queues a message into
2643 * an activatable names's queue which allows fds, and then is
2644 * delivered to us later even though we ourselves did not
2645 * negotiate it. */
2646
c7db1984 2647 if (bus->is_monitor)
09365592
LP
2648 return 0;
2649
2ce97e2b
LP
2650 if (m->n_fds <= 0)
2651 return 0;
2652
c7db1984 2653 if (bus->accept_fd)
2ce97e2b
LP
2654 return 0;
2655
2656 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2657 return 1; /* just eat it up */
2658
2659 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2660}
2661
992c052c 2662static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2663 int r;
2664
2665 assert(bus);
992c052c 2666 assert(m);
e3017af9 2667
19befb2d 2668 bus->current_message = m;
992c052c 2669 bus->iteration_counter++;
e3017af9 2670
f9f97ca6 2671 log_debug_bus_message(m);
40ca29a1 2672
992c052c
LP
2673 r = process_hello(bus, m);
2674 if (r != 0)
affff0b6 2675 goto finish;
a652755d 2676
992c052c
LP
2677 r = process_reply(bus, m);
2678 if (r != 0)
affff0b6 2679 goto finish;
e3017af9 2680
2ce97e2b
LP
2681 r = process_fd_check(bus, m);
2682 if (r != 0)
2683 goto finish;
2684
992c052c
LP
2685 r = process_filter(bus, m);
2686 if (r != 0)
affff0b6 2687 goto finish;
a652755d 2688
992c052c
LP
2689 r = process_match(bus, m);
2690 if (r != 0)
affff0b6 2691 goto finish;
a652755d 2692
992c052c
LP
2693 r = process_builtin(bus, m);
2694 if (r != 0)
affff0b6
LP
2695 goto finish;
2696
2697 r = bus_process_object(bus, m);
a652755d 2698
affff0b6 2699finish:
19befb2d 2700 bus->current_message = NULL;
affff0b6 2701 return r;
29ddb38f 2702}
88fe224c 2703
8f8f05a9
LP
2704static int dispatch_track(sd_bus *bus) {
2705 assert(bus);
2706
2707 if (!bus->track_queue)
2708 return 0;
2709
2710 bus_track_dispatch(bus->track_queue);
2711 return 1;
2712}
2713
766c5809 2714static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
4afd3348 2715 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
29ddb38f 2716 int r;
a652755d 2717
29ddb38f 2718 assert(bus);
945c2931 2719 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
7286037f 2720
992c052c
LP
2721 r = process_timeout(bus);
2722 if (r != 0)
2723 goto null_message;
7286037f 2724
992c052c
LP
2725 r = dispatch_wqueue(bus);
2726 if (r != 0)
2727 goto null_message;
7286037f 2728
8f8f05a9
LP
2729 r = dispatch_track(bus);
2730 if (r != 0)
2731 goto null_message;
2732
766c5809 2733 r = dispatch_rqueue(bus, hint_priority, priority, &m);
992c052c
LP
2734 if (r < 0)
2735 return r;
2736 if (!m)
2737 goto null_message;
7286037f 2738
992c052c
LP
2739 r = process_message(bus, m);
2740 if (r != 0)
2741 goto null_message;
7286037f 2742
992c052c
LP
2743 if (ret) {
2744 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2745 if (r < 0)
2746 return r;
e3017af9 2747
1cc6c93a
YW
2748 *ret = TAKE_PTR(m);
2749
992c052c
LP
2750 return 1;
2751 }
a652755d 2752
40ca29a1 2753 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2754
dc74ce9b
LP
2755 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2756 strna(sd_bus_message_get_sender(m)),
2757 strna(sd_bus_message_get_path(m)),
2758 strna(sd_bus_message_get_interface(m)),
2759 strna(sd_bus_message_get_member(m)));
2760
992c052c 2761 r = sd_bus_reply_method_errorf(
df2d202e 2762 m,
40ca29a1 2763 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2764 "Unknown object '%s'.", m->path);
29ddb38f
LP
2765 if (r < 0)
2766 return r;
2767 }
e3017af9 2768
992c052c 2769 return 1;
0a72c2bd 2770
992c052c
LP
2771null_message:
2772 if (r >= 0 && ret)
2773 *ret = NULL;
0a72c2bd 2774
992c052c 2775 return r;
29ddb38f 2776}
0a72c2bd 2777
fbb4603d
LP
2778static int bus_exit_now(sd_bus *bus) {
2779 assert(bus);
2780
2781 /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
2782 * sd_event_exit(), otherwise invokes libc exit(). */
2783
2784 if (bus->exited) /* did we already exit? */
2785 return 0;
2786 if (!bus->exit_triggered) /* was the exit condition triggered? */
2787 return 0;
2788 if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
2789 return 0;
2790
2791 bus->exited = true; /* never exit more than once */
2792
2793 log_debug("Bus connection disconnected, exiting.");
2794
2795 if (bus->event)
2796 return sd_event_exit(bus->event, EXIT_FAILURE);
2797 else
2798 exit(EXIT_FAILURE);
2799
2800 assert_not_reached("exit() didn't exit?");
2801}
2802
217fcc7e
LP
2803static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
2804 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
4afd3348 2805 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
217fcc7e 2806 sd_bus_slot *slot;
718db961
LP
2807 int r;
2808
2809 assert(bus);
217fcc7e 2810 assert(c);
718db961 2811
217fcc7e
LP
2812 r = bus_message_new_synthetic_error(
2813 bus,
2814 c->cookie,
2815 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
2816 &m);
2817 if (r < 0)
2818 return r;
ebcf1f97 2819
217fcc7e
LP
2820 r = bus_seal_synthetic_message(bus, m);
2821 if (r < 0)
2822 return r;
718db961 2823
ac8029fc 2824 if (c->timeout_usec != 0) {
217fcc7e 2825 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
ac8029fc 2826 c->timeout_usec = 0;
217fcc7e 2827 }
718db961 2828
217fcc7e
LP
2829 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2830 c->cookie = 0;
2831
2832 slot = container_of(c, sd_bus_slot, reply_callback);
718db961 2833
217fcc7e 2834 bus->iteration_counter++;
19befb2d 2835
217fcc7e
LP
2836 bus->current_message = m;
2837 bus->current_slot = sd_bus_slot_ref(slot);
2838 bus->current_handler = c->callback;
2839 bus->current_userdata = slot->userdata;
2840 r = c->callback(m, slot->userdata, &error_buffer);
2841 bus->current_userdata = NULL;
2842 bus->current_handler = NULL;
2843 bus->current_slot = NULL;
2844 bus->current_message = NULL;
718db961 2845
2e7e8e34
YW
2846 if (slot->floating)
2847 bus_slot_disconnect(slot, true);
718db961 2848
217fcc7e 2849 sd_bus_slot_unref(slot);
1b64f838 2850
217fcc7e
LP
2851 return bus_maybe_reply_error(m, r, &error_buffer);
2852}
718db961 2853
217fcc7e
LP
2854static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2855 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2856 struct reply_callback *c;
2857 int r;
d974ad05 2858
217fcc7e
LP
2859 assert(bus);
2860 assert(bus->state == BUS_CLOSING);
2861
2862 /* First, fail all outstanding method calls */
2863 c = ordered_hashmap_first(bus->reply_callbacks);
2864 if (c)
2865 return process_closing_reply_callback(bus, c);
718db961 2866
232f3677
LP
2867 /* Then, fake-drop all remaining bus tracking references */
2868 if (bus->tracks) {
2869 bus_track_close(bus->tracks);
2870 return 1;
2871 }
2872
718db961
LP
2873 /* Then, synthesize a Disconnected message */
2874 r = sd_bus_message_new_signal(
2875 bus,
151b9b96 2876 &m,
718db961
LP
2877 "/org/freedesktop/DBus/Local",
2878 "org.freedesktop.DBus.Local",
151b9b96 2879 "Disconnected");
718db961
LP
2880 if (r < 0)
2881 return r;
2882
fb6d9b77 2883 bus_message_set_sender_local(bus, m);
34a2c9e8 2884
7adc46fc 2885 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2886 if (r < 0)
2887 return r;
2888
2889 sd_bus_close(bus);
2890
19befb2d 2891 bus->current_message = m;
718db961
LP
2892 bus->iteration_counter++;
2893
2894 r = process_filter(bus, m);
2895 if (r != 0)
2896 goto finish;
2897
2898 r = process_match(bus, m);
2899 if (r != 0)
2900 goto finish;
2901
fbb4603d
LP
2902 /* Nothing else to do, exit now, if the condition holds */
2903 bus->exit_triggered = true;
2904 (void) bus_exit_now(bus);
2905
1cc6c93a
YW
2906 if (ret)
2907 *ret = TAKE_PTR(m);
718db961
LP
2908
2909 r = 1;
2910
2911finish:
19befb2d
LP
2912 bus->current_message = NULL;
2913
718db961
LP
2914 return r;
2915}
2916
766c5809 2917static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
29ddb38f 2918 int r;
0a72c2bd 2919
992c052c
LP
2920 /* Returns 0 when we didn't do anything. This should cause the
2921 * caller to invoke sd_bus_wait() before returning the next
2922 * time. Returns > 0 when we did something, which possibly
2923 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2924
d6888822 2925 assert_return(bus, -EINVAL);
45b1f410 2926 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 2927 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2928
992c052c 2929 /* We don't allow recursively invoking sd_bus_process(). */
19befb2d 2930 assert_return(!bus->current_message, -EBUSY);
6d77a30c 2931 assert(!bus->current_slot); /* This should be NULL whenever bus->current_message is */
0a72c2bd 2932
7ae8edcd
ZJS
2933 BUS_DONT_DESTROY(bus);
2934
992c052c 2935 switch (bus->state) {
0a72c2bd 2936
992c052c 2937 case BUS_UNSET:
992c052c 2938 return -ENOTCONN;
0a72c2bd 2939
6d6f4904
LP
2940 case BUS_CLOSED:
2941 return -ECONNRESET;
2942
8a5cd31e
LP
2943 case BUS_WATCH_BIND:
2944 r = bus_socket_process_watch_bind(bus);
2945 break;
2946
992c052c
LP
2947 case BUS_OPENING:
2948 r = bus_socket_process_opening(bus);
8a5cd31e 2949 break;
a652755d 2950
992c052c 2951 case BUS_AUTHENTICATING:
992c052c 2952 r = bus_socket_process_authenticating(bus);
8a5cd31e 2953 break;
a652755d 2954
992c052c
LP
2955 case BUS_RUNNING:
2956 case BUS_HELLO:
766c5809 2957 r = process_running(bus, hint_priority, priority, ret);
8a5cd31e
LP
2958 if (r >= 0)
2959 return r;
718db961 2960
8a5cd31e
LP
2961 /* This branch initializes *ret, hence we don't use the generic error checking below */
2962 break;
718db961
LP
2963
2964 case BUS_CLOSING:
2965 return process_closing(bus, ret);
8a5cd31e
LP
2966
2967 default:
2968 assert_not_reached("Unknown state");
992c052c 2969 }
43a43f50 2970
8a5cd31e
LP
2971 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2972 bus_enter_closing(bus);
2973 r = 1;
2974 } else if (r < 0)
2975 return r;
2976
2977 if (ret)
2978 *ret = NULL;
2979
2980 return r;
e3017af9
LP
2981}
2982
766c5809
LP
2983_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2984 return bus_process_internal(bus, false, 0, ret);
2985}
2986
2987_public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2988 return bus_process_internal(bus, true, priority, ret);
2989}
2990
992c052c
LP
2991static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2992 struct pollfd p[2] = {};
8a5cd31e 2993 int r, n;
992c052c 2994 struct timespec ts;
3a43da28 2995 usec_t m = USEC_INFINITY;
adcdb374
LP
2996
2997 assert(bus);
718db961
LP
2998
2999 if (bus->state == BUS_CLOSING)
3000 return 1;
3001
a3d59cd1
LP
3002 if (!BUS_IS_OPEN(bus->state))
3003 return -ENOTCONN;
adcdb374 3004
8a5cd31e
LP
3005 if (bus->state == BUS_WATCH_BIND) {
3006 assert(bus->inotify_fd >= 0);
adcdb374 3007
8a5cd31e
LP
3008 p[0].events = POLLIN;
3009 p[0].fd = bus->inotify_fd;
992c052c
LP
3010 n = 1;
3011 } else {
8a5cd31e
LP
3012 int e;
3013
3014 e = sd_bus_get_events(bus);
3015 if (e < 0)
3016 return e;
3017
3018 if (need_more)
3019 /* The caller really needs some more data, he doesn't
3020 * care about what's already read, or any timeouts
3021 * except its own. */
3022 e |= POLLIN;
3023 else {
3024 usec_t until;
3025 /* The caller wants to process if there's something to
3026 * process, but doesn't care otherwise */
3027
3028 r = sd_bus_get_timeout(bus, &until);
3029 if (r < 0)
3030 return r;
3031 if (r > 0)
3032 m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
3033 }
3034
3035 p[0].fd = bus->input_fd;
3036 if (bus->output_fd == bus->input_fd) {
3037 p[0].events = e;
3038 n = 1;
3039 } else {
3040 p[0].events = e & POLLIN;
3041 p[1].fd = bus->output_fd;
3042 p[1].events = e & POLLOUT;
3043 n = 2;
3044 }
adcdb374
LP
3045 }
3046
8a5cd31e
LP
3047 if (timeout_usec != (uint64_t) -1 && (m == USEC_INFINITY || timeout_usec < m))
3048 m = timeout_usec;
3049
3050 r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL);
adcdb374 3051 if (r < 0)
992c052c 3052 return -errno;
adcdb374 3053
992c052c 3054 return r > 0 ? 1 : 0;
adcdb374
LP
3055}
3056
d9f644e2 3057_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 3058
d6888822 3059 assert_return(bus, -EINVAL);
45b1f410 3060 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 3061 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 3062
718db961
LP
3063 if (bus->state == BUS_CLOSING)
3064 return 0;
3065
a3d59cd1
LP
3066 if (!BUS_IS_OPEN(bus->state))
3067 return -ENOTCONN;
718db961 3068
992c052c
LP
3069 if (bus->rqueue_size > 0)
3070 return 0;
9db76355 3071
992c052c
LP
3072 return bus_poll(bus, false, timeout_usec);
3073}
9db76355 3074
d9f644e2 3075_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 3076 int r;
9db76355 3077
d6888822 3078 assert_return(bus, -EINVAL);
45b1f410 3079 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822 3080 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 3081
718db961
LP
3082 if (bus->state == BUS_CLOSING)
3083 return 0;
3084
a3d59cd1
LP
3085 if (!BUS_IS_OPEN(bus->state))
3086 return -ENOTCONN;
718db961 3087
8a5cd31e
LP
3088 /* We never were connected? Don't hang in inotify for good, as there's no timeout set for it */
3089 if (bus->state == BUS_WATCH_BIND)
3090 return -EUNATCH;
3091
992c052c
LP
3092 r = bus_ensure_running(bus);
3093 if (r < 0)
3094 return r;
9db76355 3095
992c052c
LP
3096 if (bus->wqueue_size <= 0)
3097 return 0;
9db76355 3098
992c052c
LP
3099 for (;;) {
3100 r = dispatch_wqueue(bus);
32f46480 3101 if (r < 0) {
103a5027 3102 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
32f46480 3103 bus_enter_closing(bus);
441d56a1
LP
3104 return -ECONNRESET;
3105 }
32f46480 3106
9db76355 3107 return r;
32f46480 3108 }
9db76355 3109
992c052c
LP
3110 if (bus->wqueue_size <= 0)
3111 return 0;
9db76355 3112
992c052c 3113 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
3114 if (r < 0)
3115 return r;
9db76355 3116 }
9db76355
LP
3117}
3118
19befb2d
LP
3119_public_ int sd_bus_add_filter(
3120 sd_bus *bus,
3121 sd_bus_slot **slot,
3122 sd_bus_message_handler_t callback,
3123 void *userdata) {
d9f644e2 3124
19befb2d 3125 sd_bus_slot *s;
de1c301e 3126
d6888822 3127 assert_return(bus, -EINVAL);
45b1f410 3128 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
3129 assert_return(callback, -EINVAL);
3130 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 3131
19befb2d
LP
3132 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
3133 if (!s)
29ddb38f
LP
3134 return -ENOMEM;
3135
19befb2d 3136 s->filter_callback.callback = callback;
a652755d 3137
19befb2d
LP
3138 bus->filter_callbacks_modified = true;
3139 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
a652755d 3140
19befb2d
LP
3141 if (slot)
3142 *slot = s;
29ddb38f 3143
992c052c 3144 return 0;
a652755d 3145}
392d5b37 3146
7593c7a4
LP
3147static int add_match_callback(
3148 sd_bus_message *m,
3149 void *userdata,
3150 sd_bus_error *ret_error) {
3151
3152 sd_bus_slot *match_slot = userdata;
3153 bool failed = false;
3154 int r;
3155
3156 assert(m);
3157 assert(match_slot);
3158
3159 sd_bus_slot_ref(match_slot);
3160
3161 if (sd_bus_message_is_method_error(m, NULL)) {
3162 log_debug_errno(sd_bus_message_get_errno(m),
3163 "Unable to add match %s, failing connection: %s",
3164 match_slot->match_callback.match_string,
3165 sd_bus_message_get_error(m)->message);
3166
3167 failed = true;
3168 } else
3169 log_debug("Match %s successfully installed.", match_slot->match_callback.match_string);
3170
3171 if (match_slot->match_callback.install_callback) {
3172 sd_bus *bus;
3173
3174 bus = sd_bus_message_get_bus(m);
3175
3176 /* This function has been called as slot handler, and we want to call another slot handler. Let's
3177 * update the slot callback metadata temporarily with our own data, and then revert back to the old
3178 * values. */
3179
3180 assert(bus->current_slot == match_slot->match_callback.install_slot);
3181 assert(bus->current_handler == add_match_callback);
3182 assert(bus->current_userdata == userdata);
3183
3184 bus->current_slot = match_slot;
3185 bus->current_handler = match_slot->match_callback.install_callback;
3186 bus->current_userdata = match_slot->userdata;
3187
3188 r = match_slot->match_callback.install_callback(m, match_slot->userdata, ret_error);
3189
3190 bus->current_slot = match_slot->match_callback.install_slot;
3191 bus->current_handler = add_match_callback;
3192 bus->current_userdata = userdata;
3193
3194 match_slot->match_callback.install_slot = sd_bus_slot_unref(match_slot->match_callback.install_slot);
3195 } else {
3196 if (failed) /* Generic failure handling: destroy the connection */
3197 bus_enter_closing(sd_bus_message_get_bus(m));
3198
3199 r = 1;
3200 }
3201
2e7e8e34
YW
3202 if (failed && match_slot->floating)
3203 bus_slot_disconnect(match_slot, true);
7593c7a4
LP
3204
3205 sd_bus_slot_unref(match_slot);
3206
3207 return r;
3208}
3209
3210static int bus_add_match_full(
19befb2d
LP
3211 sd_bus *bus,
3212 sd_bus_slot **slot,
7593c7a4 3213 bool asynchronous,
19befb2d
LP
3214 const char *match,
3215 sd_bus_message_handler_t callback,
7593c7a4 3216 sd_bus_message_handler_t install_callback,
19befb2d 3217 void *userdata) {
d9f644e2 3218
992c052c
LP
3219 struct bus_match_component *components = NULL;
3220 unsigned n_components = 0;
2915234d 3221 sd_bus_slot *s = NULL;
992c052c 3222 int r = 0;
392d5b37 3223
d6888822 3224 assert_return(bus, -EINVAL);
45b1f410 3225 assert_return(bus = bus_resolve(bus), -ENOPKG);
d6888822
LP
3226 assert_return(match, -EINVAL);
3227 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 3228
992c052c
LP
3229 r = bus_match_parse(match, &components, &n_components);
3230 if (r < 0)
3231 goto finish;
29ddb38f 3232
19befb2d
LP
3233 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
3234 if (!s) {
3235 r = -ENOMEM;
3236 goto finish;
3237 }
3238
3239 s->match_callback.callback = callback;
7593c7a4 3240 s->match_callback.install_callback = install_callback;
19befb2d 3241
992c052c 3242 if (bus->bus_client) {
cc65fe5e 3243 enum bus_match_scope scope;
29ddb38f 3244
cc65fe5e 3245 scope = bus_match_get_scope(components, n_components);
19befb2d 3246
7593c7a4 3247 /* Do not install server-side matches for matches against the local service, interface or bus path. */
9ee7a50c 3248 if (scope != BUS_MATCH_LOCAL) {
cc65fe5e 3249
7593c7a4 3250 /* We store the original match string, so that we can use it to remove the match again. */
cc65fe5e 3251
a132bef0
ZJS
3252 s->match_callback.match_string = strdup(match);
3253 if (!s->match_callback.match_string) {
3254 r = -ENOMEM;
3255 goto finish;
19befb2d 3256 }
19befb2d 3257
fc2d4c89 3258 if (asynchronous) {
7593c7a4
LP
3259 r = bus_add_match_internal_async(bus,
3260 &s->match_callback.install_slot,
3261 s->match_callback.match_string,
3262 add_match_callback,
3263 s);
fc2d4c89
LP
3264
3265 if (r < 0)
3266 return r;
3267
3268 /* Make the slot of the match call floating now. We need the reference, but we don't
3269 * want that this match pins the bus object, hence we first create it non-floating, but
3270 * then make it floating. */
3271 r = sd_bus_slot_set_floating(s->match_callback.install_slot, true);
3272 } else
7593c7a4 3273 r = bus_add_match_internal(bus, s->match_callback.match_string);
cc65fe5e
LP
3274 if (r < 0)
3275 goto finish;
3276
3277 s->match_added = true;
3278 }
392d5b37
LP
3279 }
3280
992c052c 3281 bus->match_callbacks_modified = true;
19befb2d
LP
3282 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
3283 if (r < 0)
3284 goto finish;
3285
3286 if (slot)
3287 *slot = s;
3288 s = NULL;
917b5dc7 3289
992c052c
LP
3290finish:
3291 bus_match_parse_free(components, n_components);
19befb2d
LP
3292 sd_bus_slot_unref(s);
3293
992c052c 3294 return r;
917b5dc7
LP
3295}
3296
7593c7a4
LP
3297_public_ int sd_bus_add_match(
3298 sd_bus *bus,
3299 sd_bus_slot **slot,
3300 const char *match,
3301 sd_bus_message_handler_t callback,
3302 void *userdata) {
3303
3304 return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata);
3305}
3306
3307_public_ int sd_bus_add_match_async(
3308 sd_bus *bus,
3309 sd_bus_slot **slot,
3310 const char *match,
3311 sd_bus_message_handler_t callback,
3312 sd_bus_message_handler_t install_callback,
3313 void *userdata) {
3314
3315 return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata);
3316}
3317
992c052c
LP
3318bool bus_pid_changed(sd_bus *bus) {
3319 assert(bus);
f10dda3b 3320
992c052c
LP
3321 /* We don't support people creating a bus connection and
3322 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 3323
df0ff127 3324 return bus->original_pid != getpid_cached();
d5a2b9a6 3325}
40ca29a1
LP
3326
3327static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 3328 sd_bus *bus = userdata;
40ca29a1
LP
3329 int r;
3330
3331 assert(bus);
3332
8a5cd31e
LP
3333 /* Note that this is called both on input_fd, output_fd as well as inotify_fd events */
3334
40ca29a1 3335 r = sd_bus_process(bus, NULL);
5ae37ad8
LP
3336 if (r < 0) {
3337 log_debug_errno(r, "Processing of bus failed, closing down: %m");
3338 bus_enter_closing(bus);
3339 }
40ca29a1
LP
3340
3341 return 1;
3342}
3343
3344static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 3345 sd_bus *bus = userdata;
40ca29a1
LP
3346 int r;
3347
3348 assert(bus);
3349
3350 r = sd_bus_process(bus, NULL);
5ae37ad8
LP
3351 if (r < 0) {
3352 log_debug_errno(r, "Processing of bus failed, closing down: %m");
3353 bus_enter_closing(bus);
3354 }
40ca29a1
LP
3355
3356 return 1;
3357}
3358
3359static int prepare_callback(sd_event_source *s, void *userdata) {
3360 sd_bus *bus = userdata;
3361 int r, e;
3362 usec_t until;
3363
3364 assert(s);
3365 assert(bus);
3366
3367 e = sd_bus_get_events(bus);
5ae37ad8
LP
3368 if (e < 0) {
3369 r = e;
3370 goto fail;
3371 }
40ca29a1
LP
3372
3373 if (bus->output_fd != bus->input_fd) {
3374
3375 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
3376 if (r < 0)
5ae37ad8 3377 goto fail;
40ca29a1
LP
3378
3379 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
5ae37ad8 3380 } else
40ca29a1 3381 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
5ae37ad8
LP
3382 if (r < 0)
3383 goto fail;
40ca29a1
LP
3384
3385 r = sd_bus_get_timeout(bus, &until);
3386 if (r < 0)
5ae37ad8 3387 goto fail;
40ca29a1
LP
3388 if (r > 0) {
3389 int j;
3390
3391 j = sd_event_source_set_time(bus->time_event_source, until);
5ae37ad8
LP
3392 if (j < 0) {
3393 r = j;
3394 goto fail;
3395 }
40ca29a1
LP
3396 }
3397
3398 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3399 if (r < 0)
5ae37ad8
LP
3400 goto fail;
3401
3402 return 1;
3403
3404fail:
3405 log_debug_errno(r, "Preparing of bus events failed, closing down: %m");
3406 bus_enter_closing(bus);
40ca29a1
LP
3407
3408 return 1;
3409}
3410
abc5fe72
LP
3411static int quit_callback(sd_event_source *event, void *userdata) {
3412 sd_bus *bus = userdata;
3413
3414 assert(event);
3415
c4e48030
LP
3416 if (bus->close_on_exit) {
3417 sd_bus_flush(bus);
3418 sd_bus_close(bus);
3419 }
abc5fe72
LP
3420
3421 return 1;
3422}
3423
8a5cd31e 3424int bus_attach_io_events(sd_bus *bus) {
1e05d493
LP
3425 int r;
3426
3427 assert(bus);
3428
3429 if (bus->input_fd < 0)
3430 return 0;
3431
3432 if (!bus->event)
3433 return 0;
3434
3435 if (!bus->input_io_event_source) {
151b9b96 3436 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
1e05d493
LP
3437 if (r < 0)
3438 return r;
3439
3440 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3441 if (r < 0)
3442 return r;
3443
3444 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
9021bb9f
TG
3445 if (r < 0)
3446 return r;
3447
356779df 3448 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
1e05d493
LP
3449 } else
3450 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3451
3452 if (r < 0)
3453 return r;
3454
3455 if (bus->output_fd != bus->input_fd) {
3456 assert(bus->output_fd >= 0);
3457
3458 if (!bus->output_io_event_source) {
151b9b96 3459 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
1e05d493
LP
3460 if (r < 0)
3461 return r;
3462
3463 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
9021bb9f
TG
3464 if (r < 0)
3465 return r;
3466
356779df 3467 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
1e05d493
LP
3468 } else
3469 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3470
3471 if (r < 0)
3472 return r;
3473 }
3474
3475 return 0;
3476}
3477
8a5cd31e 3478static void bus_detach_io_events(sd_bus *bus) {
1e05d493
LP
3479 assert(bus);
3480
3481 if (bus->input_io_event_source) {
3482 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3483 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3484 }
3485
3486 if (bus->output_io_event_source) {
3487 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3488 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3489 }
3490}
3491
8a5cd31e
LP
3492int bus_attach_inotify_event(sd_bus *bus) {
3493 int r;
3494
3495 assert(bus);
3496
3497 if (bus->inotify_fd < 0)
3498 return 0;
3499
3500 if (!bus->event)
3501 return 0;
3502
3503 if (!bus->inotify_event_source) {
3504 r = sd_event_add_io(bus->event, &bus->inotify_event_source, bus->inotify_fd, EPOLLIN, io_callback, bus);
3505 if (r < 0)
3506 return r;
3507
3508 r = sd_event_source_set_priority(bus->inotify_event_source, bus->event_priority);
3509 if (r < 0)
3510 return r;
3511
3512 r = sd_event_source_set_description(bus->inotify_event_source, "bus-inotify");
3513 } else
3514 r = sd_event_source_set_io_fd(bus->inotify_event_source, bus->inotify_fd);
3515 if (r < 0)
3516 return r;
3517
3518 return 0;
3519}
3520
3521static void bus_detach_inotify_event(sd_bus *bus) {
3522 assert(bus);
3523
3524 if (bus->inotify_event_source) {
3525 sd_event_source_set_enabled(bus->inotify_event_source, SD_EVENT_OFF);
3526 bus->inotify_event_source = sd_event_source_unref(bus->inotify_event_source);
3527 }
3528}
3529
d9f644e2 3530_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
3531 int r;
3532
3533 assert_return(bus, -EINVAL);
45b1f410 3534 assert_return(bus = bus_resolve(bus), -ENOPKG);
40ca29a1
LP
3535 assert_return(!bus->event, -EBUSY);
3536
3537 assert(!bus->input_io_event_source);
3538 assert(!bus->output_io_event_source);
3539 assert(!bus->time_event_source);
3540
76b54375
LP
3541 if (event)
3542 bus->event = sd_event_ref(event);
3543 else {
3544 r = sd_event_default(&bus->event);
3545 if (r < 0)
3546 return r;
3547 }
40ca29a1 3548
1e05d493 3549 bus->event_priority = priority;
40ca29a1 3550
6a0f1f6d 3551 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
40ca29a1
LP
3552 if (r < 0)
3553 goto fail;
3554
3555 r = sd_event_source_set_priority(bus->time_event_source, priority);
3556 if (r < 0)
3557 goto fail;
3558
356779df 3559 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
9021bb9f
TG
3560 if (r < 0)
3561 goto fail;
3562
151b9b96 3563 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
abc5fe72
LP
3564 if (r < 0)
3565 goto fail;
3566
356779df 3567 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
9021bb9f
TG
3568 if (r < 0)
3569 goto fail;
3570
8a5cd31e
LP
3571 r = bus_attach_io_events(bus);
3572 if (r < 0)
3573 goto fail;
3574
3575 r = bus_attach_inotify_event(bus);
1e05d493
LP
3576 if (r < 0)
3577 goto fail;
3578
40ca29a1
LP
3579 return 0;
3580
3581fail:
3582 sd_bus_detach_event(bus);
3583 return r;
3584}
3585
d9f644e2 3586_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 3587 assert_return(bus, -EINVAL);
45b1f410 3588 assert_return(bus = bus_resolve(bus), -ENOPKG);
a82cafb9
LP
3589
3590 if (!bus->event)
3591 return 0;
40ca29a1 3592
8a5cd31e
LP
3593 bus_detach_io_events(bus);
3594 bus_detach_inotify_event(bus);
40ca29a1 3595
86befb40
LP
3596 if (bus->time_event_source) {
3597 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 3598 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 3599 }
40ca29a1 3600
86befb40
LP
3601 if (bus->quit_event_source) {
3602 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 3603 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 3604 }
abc5fe72 3605
93f1bcf4 3606 bus->event = sd_event_unref(bus->event);
a82cafb9 3607 return 1;
40ca29a1 3608}
affff0b6 3609
2be44176
LP
3610_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3611 assert_return(bus, NULL);
3612
3613 return bus->event;
3614}
3615
19befb2d
LP
3616_public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3617 assert_return(bus, NULL);
3618
3619 return bus->current_message;
3620}
3621
3622_public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
affff0b6
LP
3623 assert_return(bus, NULL);
3624
19befb2d 3625 return bus->current_slot;
affff0b6 3626}
76b54375 3627
caa82984
LP
3628_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3629 assert_return(bus, NULL);
3630
3631 return bus->current_handler;
3632}
3633
3634_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3635 assert_return(bus, NULL);
3636
3637 return bus->current_userdata;
3638}
3639
76b54375
LP
3640static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3641 sd_bus *b = NULL;
3642 int r;
3643
3644 assert(bus_open);
3645 assert(default_bus);
3646
3647 if (!ret)
3648 return !!*default_bus;
3649
3650 if (*default_bus) {
3651 *ret = sd_bus_ref(*default_bus);
3652 return 0;
3653 }
3654
3655 r = bus_open(&b);
3656 if (r < 0)
3657 return r;
3658
3659 b->default_bus_ptr = default_bus;
3660 b->tid = gettid();
3661 *default_bus = b;
3662
3663 *ret = b;
3664 return 1;
3665}
3666
3667_public_ int sd_bus_default_system(sd_bus **ret) {
76b54375
LP
3668 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3669}
3670
fa2f8973 3671_public_ int sd_bus_default_user(sd_bus **ret) {
76b54375
LP
3672 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3673}
3674
af08d2f9 3675_public_ int sd_bus_default(sd_bus **ret) {
45b1f410
NM
3676 int (*bus_open)(sd_bus **) = NULL;
3677 sd_bus **busp;
af08d2f9 3678
45b1f410
NM
3679 busp = bus_choose_default(&bus_open);
3680 return bus_default(bus_open, busp, ret);
af08d2f9
LP
3681}
3682
76b54375
LP
3683_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3684 assert_return(b, -EINVAL);
3685 assert_return(tid, -EINVAL);
3686 assert_return(!bus_pid_changed(b), -ECHILD);
3687
3688 if (b->tid != 0) {
3689 *tid = b->tid;
3690 return 0;
3691 }
3692
3693 if (b->event)
3694 return sd_event_get_tid(b->event, tid);
3695
3696 return -ENXIO;
3697}
28383ba1 3698
a6278b88
LP
3699_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3700 _cleanup_free_ char *e = NULL;
3701 char *ret;
3702
3703 assert_return(object_path_is_valid(prefix), -EINVAL);
3704 assert_return(external_id, -EINVAL);
3705 assert_return(ret_path, -EINVAL);
3706
3707 e = bus_label_escape(external_id);
3708 if (!e)
3709 return -ENOMEM;
3710
605405c6 3711 ret = strjoin(prefix, "/", e);
a6278b88
LP
3712 if (!ret)
3713 return -ENOMEM;
3714
3715 *ret_path = ret;
3716 return 0;
28383ba1
LP
3717}
3718
a6278b88
LP
3719_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3720 const char *e;
3721 char *ret;
3722
3723 assert_return(object_path_is_valid(path), -EINVAL);
3724 assert_return(object_path_is_valid(prefix), -EINVAL);
3725 assert_return(external_id, -EINVAL);
3726
3727 e = object_path_startswith(path, prefix);
3728 if (!e) {
3729 *external_id = NULL;
3730 return 0;
3731 }
3732
3733 ret = bus_label_unescape(e);
3734 if (!ret)
3735 return -ENOMEM;
3736
3737 *external_id = ret;
3738 return 1;
28383ba1 3739}
5b12334d 3740
dfb815c3
DH
3741_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
3742 _cleanup_strv_free_ char **labels = NULL;
3743 char *path, *path_pos, **label_pos;
3744 const char *sep, *template_pos;
3745 size_t path_length;
3746 va_list list;
3747 int r;
3748
3749 assert_return(out, -EINVAL);
3750 assert_return(path_template, -EINVAL);
3751
3752 path_length = strlen(path_template);
3753
19932084 3754 va_start(list, path_template);
dfb815c3
DH
3755 for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
3756 const char *arg;
3757 char *label;
3758
3759 arg = va_arg(list, const char *);
3760 if (!arg) {
3761 va_end(list);
3762 return -EINVAL;
3763 }
3764
3765 label = bus_label_escape(arg);
3766 if (!label) {
3767 va_end(list);
3768 return -ENOMEM;
3769 }
3770
3771 r = strv_consume(&labels, label);
3772 if (r < 0) {
3773 va_end(list);
3774 return r;
3775 }
3776
3777 /* add label length, but account for the format character */
3778 path_length += strlen(label) - 1;
3779 }
3780 va_end(list);
3781
3782 path = malloc(path_length + 1);
3783 if (!path)
3784 return -ENOMEM;
3785
3786 path_pos = path;
3787 label_pos = labels;
3788
3789 for (template_pos = path_template; *template_pos; ) {
3790 sep = strchrnul(template_pos, '%');
3791 path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
3792 if (!*sep)
3793 break;
3794
3795 path_pos = stpcpy(path_pos, *label_pos++);
3796 template_pos = sep + 1;
3797 }
3798
3799 *path_pos = 0;
3800 *out = path;
3801 return 0;
3802}
3803
3804_public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
3805 _cleanup_strv_free_ char **labels = NULL;
3806 const char *template_pos, *path_pos;
3807 char **label_pos;
3808 va_list list;
3809 int r;
3810
3811 /*
3812 * This decodes an object-path based on a template argument. The
3813 * template consists of a verbatim path, optionally including special
3814 * directives:
3815 *
3816 * - Each occurrence of '%' in the template matches an arbitrary
3817 * substring of a label in the given path. At most one such
3818 * directive is allowed per label. For each such directive, the
3819 * caller must provide an output parameter (char **) via va_arg. If
3820 * NULL is passed, the given label is verified, but not returned.
3821 * For each matched label, the *decoded* label is stored in the
3822 * passed output argument, and the caller is responsible to free
3823 * it. Note that the output arguments are only modified if the
3824 * actualy path matched the template. Otherwise, they're left
3825 * untouched.
3826 *
3827 * This function returns <0 on error, 0 if the path does not match the
3828 * template, 1 if it matched.
3829 */
3830
3831 assert_return(path, -EINVAL);
3832 assert_return(path_template, -EINVAL);
3833
3834 path_pos = path;
3835
3836 for (template_pos = path_template; *template_pos; ) {
3837 const char *sep;
3838 size_t length;
3839 char *label;
3840
3841 /* verify everything until the next '%' matches verbatim */
3842 sep = strchrnul(template_pos, '%');
3843 length = sep - template_pos;
3844 if (strncmp(path_pos, template_pos, length))
3845 return 0;
3846
3847 path_pos += length;
3848 template_pos += length;
3849
3850 if (!*template_pos)
3851 break;
3852
3853 /* We found the next '%' character. Everything up until here
3854 * matched. We now skip ahead to the end of this label and make
3855 * sure it matches the tail of the label in the path. Then we
3856 * decode the string in-between and save it for later use. */
3857
3858 ++template_pos; /* skip over '%' */
3859
3860 sep = strchrnul(template_pos, '/');
3861 length = sep - template_pos; /* length of suffix to match verbatim */
3862
3863 /* verify the suffixes match */
3864 sep = strchrnul(path_pos, '/');
3865 if (sep - path_pos < (ssize_t)length ||
3866 strncmp(sep - length, template_pos, length))
3867 return 0;
3868
3869 template_pos += length; /* skip over matched label */
3870 length = sep - path_pos - length; /* length of sub-label to decode */
3871
3872 /* store unescaped label for later use */
3873 label = bus_label_unescape_n(path_pos, length);
3874 if (!label)
3875 return -ENOMEM;
3876
3877 r = strv_consume(&labels, label);
3878 if (r < 0)
3879 return r;
3880
3881 path_pos = sep; /* skip decoded label and suffix */
3882 }
3883
3884 /* end of template must match end of path */
3885 if (*path_pos)
3886 return 0;
3887
3888 /* copy the labels over to the caller */
19932084 3889 va_start(list, path_template);
dfb815c3
DH
3890 for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
3891 char **arg;
3892
3893 arg = va_arg(list, char **);
3894 if (arg)
3895 *arg = *label_pos;
3896 else
3897 free(*label_pos);
3898 }
3899 va_end(list);
3900
86ed6d1b 3901 labels = mfree(labels);
dfb815c3
DH
3902 return 1;
3903}
3904
ae095f86 3905_public_ int sd_bus_try_close(sd_bus *bus) {
ae095f86 3906 assert_return(bus, -EINVAL);
45b1f410 3907 assert_return(bus = bus_resolve(bus), -ENOPKG);
ae095f86 3908 assert_return(!bus_pid_changed(bus), -ECHILD);
a3d59cd1 3909
a132bef0 3910 return -EOPNOTSUPP;
ae095f86 3911}
5972fe95 3912
455971c1 3913_public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
5972fe95 3914 assert_return(bus, -EINVAL);
45b1f410 3915 assert_return(bus = bus_resolve(bus), -ENOPKG);
455971c1 3916 assert_return(description, -EINVAL);
f4b2933e 3917 assert_return(bus->description, -ENXIO);
5972fe95
LP
3918 assert_return(!bus_pid_changed(bus), -ECHILD);
3919
201e419a
LP
3920 if (bus->description)
3921 *description = bus->description;
3922 else if (bus->is_system)
3923 *description = "system";
3924 else if (bus->is_user)
3925 *description = "user";
3926 else
3927 *description = NULL;
3928
5972fe95
LP
3929 return 0;
3930}
fe3f22d1
DK
3931
3932int bus_get_root_path(sd_bus *bus) {
3933 int r;
3934
3935 if (bus->cgroup_root)
3936 return 0;
3937
3938 r = cg_get_root_path(&bus->cgroup_root);
3939 if (r == -ENOENT) {
3940 bus->cgroup_root = strdup("/");
3941 if (!bus->cgroup_root)
3942 return -ENOMEM;
3943
3944 r = 0;
3945 }
3946
3947 return r;
3948}
3acc1daf
LP
3949
3950_public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
3acc1daf 3951 assert_return(bus, -EINVAL);
45b1f410 3952 assert_return(bus = bus_resolve(bus), -ENOPKG);
3acc1daf
LP
3953 assert_return(scope, -EINVAL);
3954 assert_return(!bus_pid_changed(bus), -ECHILD);
3955
3acc1daf
LP
3956 if (bus->is_user) {
3957 *scope = "user";
5b820358 3958 return 0;
3acc1daf
LP
3959 }
3960
3961 if (bus->is_system) {
3962 *scope = "system";
5b820358
LP
3963 return 0;
3964 }
3965
3966 return -ENODATA;
3967}
3968
3969_public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
3970
3971 assert_return(bus, -EINVAL);
45b1f410 3972 assert_return(bus = bus_resolve(bus), -ENOPKG);
5b820358
LP
3973 assert_return(address, -EINVAL);
3974 assert_return(!bus_pid_changed(bus), -ECHILD);
3975
3976 if (bus->address) {
3977 *address = bus->address;
3978 return 0;
3acc1daf
LP
3979 }
3980
3981 return -ENODATA;
3982}
224b3787 3983
882897af 3984_public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
224b3787 3985 assert_return(bus, -EINVAL);
45b1f410 3986 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
3987 assert_return(mask, -EINVAL);
3988 assert_return(!bus_pid_changed(bus), -ECHILD);
3989
3990 *mask = bus->creds_mask;
3991 return 0;
3992}
3993
882897af 3994_public_ int sd_bus_is_bus_client(sd_bus *bus) {
224b3787 3995 assert_return(bus, -EINVAL);
45b1f410 3996 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
3997 assert_return(!bus_pid_changed(bus), -ECHILD);
3998
3999 return bus->bus_client;
4000}
4001
882897af 4002_public_ int sd_bus_is_server(sd_bus *bus) {
224b3787 4003 assert_return(bus, -EINVAL);
45b1f410 4004 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
4005 assert_return(!bus_pid_changed(bus), -ECHILD);
4006
4007 return bus->is_server;
4008}
4009
882897af 4010_public_ int sd_bus_is_anonymous(sd_bus *bus) {
224b3787 4011 assert_return(bus, -EINVAL);
45b1f410 4012 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
4013 assert_return(!bus_pid_changed(bus), -ECHILD);
4014
4015 return bus->anonymous_auth;
4016}
4017
882897af 4018_public_ int sd_bus_is_trusted(sd_bus *bus) {
224b3787 4019 assert_return(bus, -EINVAL);
45b1f410 4020 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
4021 assert_return(!bus_pid_changed(bus), -ECHILD);
4022
4023 return bus->trusted;
4024}
4025
882897af 4026_public_ int sd_bus_is_monitor(sd_bus *bus) {
224b3787 4027 assert_return(bus, -EINVAL);
45b1f410 4028 assert_return(bus = bus_resolve(bus), -ENOPKG);
224b3787
LP
4029 assert_return(!bus_pid_changed(bus), -ECHILD);
4030
c7db1984 4031 return bus->is_monitor;
224b3787 4032}
fa2f8973
LP
4033
4034static void flush_close(sd_bus *bus) {
4035 if (!bus)
4036 return;
4037
4038 /* Flushes and closes the specified bus. We take a ref before,
4039 * to ensure the flushing does not cause the bus to be
4040 * unreferenced. */
4041
4042 sd_bus_flush_close_unref(sd_bus_ref(bus));
4043}
4044
4045_public_ void sd_bus_default_flush_close(void) {
4046 flush_close(default_starter_bus);
4047 flush_close(default_user_bus);
4048 flush_close(default_system_bus);
4049}
fbb4603d
LP
4050
4051_public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) {
4052 assert_return(bus, -EINVAL);
45b1f410 4053 assert_return(bus = bus_resolve(bus), -ENOPKG);
fbb4603d
LP
4054
4055 /* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already
4056 * disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never
4057 * from the client side. */
4058 bus->exit_on_disconnect = b;
4059
4060 /* If the exit condition was triggered already, exit immediately. */
4061 return bus_exit_now(bus);
4062}
4063
4064_public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) {
4065 assert_return(bus, -EINVAL);
45b1f410 4066 assert_return(bus = bus_resolve(bus), -ENOPKG);
fbb4603d
LP
4067
4068 return bus->exit_on_disconnect;
4069}
48ef41a3
LP
4070
4071_public_ int sd_bus_set_sender(sd_bus *bus, const char *sender) {
4072 assert_return(bus, -EINVAL);
45b1f410 4073 assert_return(bus = bus_resolve(bus), -ENOPKG);
48ef41a3
LP
4074 assert_return(!bus->bus_client, -EPERM);
4075 assert_return(!sender || service_name_is_valid(sender), -EINVAL);
4076
4077 return free_and_strdup(&bus->patch_sender, sender);
4078}
4079
4080_public_ int sd_bus_get_sender(sd_bus *bus, const char **ret) {
4081 assert_return(bus, -EINVAL);
45b1f410 4082 assert_return(bus = bus_resolve(bus), -ENOPKG);
48ef41a3
LP
4083 assert_return(ret, -EINVAL);
4084
4085 if (!bus->patch_sender)
4086 return -ENODATA;
4087
4088 *ret = bus->patch_sender;
4089 return 0;
4090}
2770da02
LP
4091
4092_public_ int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret) {
4093 assert_return(bus, -EINVAL);
4094 assert_return(bus = bus_resolve(bus), -ENOPKG);
4095 assert_return(!bus_pid_changed(bus), -ECHILD);
4096 assert_return(ret, -EINVAL);
4097
4098 *ret = bus->rqueue_size;
4099 return 0;
4100}
4101
4102_public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) {
4103 assert_return(bus, -EINVAL);
4104 assert_return(bus = bus_resolve(bus), -ENOPKG);
4105 assert_return(!bus_pid_changed(bus), -ECHILD);
4106 assert_return(ret, -EINVAL);
4107
4108 *ret = bus->wqueue_size;
4109 return 0;
4110}
385b2eb2
YW
4111
4112_public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) {
4113 assert_return(bus, -EINVAL);
4114 assert_return(bus = bus_resolve(bus), -ENOPKG);
4115
4116 bus->method_call_timeout = usec;
4117 return 0;
4118}
4119
4120_public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
4121 const char *e;
4122 usec_t usec;
4123
4124 assert_return(bus, -EINVAL);
4125 assert_return(bus = bus_resolve(bus), -ENOPKG);
4126 assert_return(ret, -EINVAL);
4127
4128 if (bus->method_call_timeout != 0) {
4129 *ret = bus->method_call_timeout;
4130 return 0;
4131 }
4132
4133 e = secure_getenv("SYSTEMD_BUS_TIMEOUT");
4134 if (e && parse_sec(e, &usec) >= 0 && usec != 0) {
4135 /* Save the parsed value to avoid multiple parsing. To change the timeout value,
4136 * use sd_bus_set_method_call_timeout() instead of setenv(). */
4137 *ret = bus->method_call_timeout = usec;
4138 return 0;
4139 }
4140
4141 *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
4142 return 0;
4143}
c4e48030
LP
4144
4145_public_ int sd_bus_set_close_on_exit(sd_bus *bus, int b) {
4146 assert_return(bus, -EINVAL);
4147 assert_return(bus = bus_resolve(bus), -ENOPKG);
4148
4149 bus->close_on_exit = b;
4150 return 0;
4151}
4152
4153_public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
4154 assert_return(bus, -EINVAL);
4155 assert_return(bus = bus_resolve(bus), -ENOPKG);
4156
4157 return bus->close_on_exit;
4158}