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