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