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