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