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