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