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