]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/sd-bus.c
Merge pull request #115 from whot/master
[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(m, -EINVAL);
9030ca46
LP
1699
1700 if (!bus)
1701 bus = m->bus;
1702
d6888822 1703 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1704 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
021a1e78 1705
a3d59cd1
LP
1706 if (!BUS_IS_OPEN(bus->state))
1707 return -ENOTCONN;
1708
021a1e78
LP
1709 if (m->n_fds > 0) {
1710 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1711 if (r < 0)
1712 return r;
1713 if (r == 0)
15411c0c 1714 return -EOPNOTSUPP;
021a1e78 1715 }
de1c301e 1716
693eb9a2 1717 /* If the cookie number isn't kept, then we know that no reply
29f6aadd 1718 * is expected */
693eb9a2 1719 if (!cookie && !m->sealed)
0461f8cd 1720 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1721
3df7a7e6 1722 r = bus_seal_message(bus, m, 0);
de1c301e
LP
1723 if (r < 0)
1724 return r;
1725
441d56a1 1726 /* Remarshall if we have to. This will possibly unref the
e1c433c6
LP
1727 * message and place a replacement in m */
1728 r = bus_remarshal_message(bus, &m);
1729 if (r < 0)
1730 return r;
1731
5407f2de
LP
1732 /* If this is a reply and no reply was requested, then let's
1733 * suppress this, if we can */
997eadb5
LP
1734 if (m->dont_send)
1735 goto finish;
5407f2de 1736
89ffcd2a 1737 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1738 size_t idx = 0;
1739
069f5e61 1740 r = bus_write_message(bus, m, hint_sync_call, &idx);
32f46480 1741 if (r < 0) {
441d56a1 1742 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1743 bus_enter_closing(bus);
441d56a1
LP
1744 return -ECONNRESET;
1745 }
32f46480 1746
de1c301e 1747 return r;
997eadb5
LP
1748 }
1749
1750 if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1751 /* Wasn't fully written. So let's remember how
1752 * much was written. Note that the first entry
1753 * of the wqueue array is always allocated so
1754 * that we always can remember how much was
1755 * written. */
1756 bus->wqueue[0] = sd_bus_message_ref(m);
1757 bus->wqueue_size = 1;
1758 bus->windex = idx;
1759 }
997eadb5 1760
de1c301e 1761 } else {
de1c301e
LP
1762 /* Just append it to the queue. */
1763
25220239 1764 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1765 return -ENOBUFS;
1766
821e0756 1767 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
de1c301e
LP
1768 return -ENOMEM;
1769
821e0756 1770 bus->wqueue[bus->wqueue_size ++] = sd_bus_message_ref(m);
de1c301e
LP
1771 }
1772
997eadb5 1773finish:
693eb9a2
LP
1774 if (cookie)
1775 *cookie = BUS_MESSAGE_COOKIE(m);
de1c301e 1776
7a37d625 1777 return 1;
de1c301e
LP
1778}
1779
069f5e61
LP
1780_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) {
1781 return bus_send_internal(bus, m, cookie, false);
1782}
1783
693eb9a2 1784_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
911121a7
LP
1785 int r;
1786
911121a7 1787 assert_return(m, -EINVAL);
9030ca46
LP
1788
1789 if (!bus)
1790 bus = m->bus;
1791
911121a7
LP
1792 assert_return(!bus_pid_changed(bus), -ECHILD);
1793
a3d59cd1
LP
1794 if (!BUS_IS_OPEN(bus->state))
1795 return -ENOTCONN;
1796
911121a7
LP
1797 if (!streq_ptr(m->destination, destination)) {
1798
1799 if (!destination)
1800 return -EEXIST;
1801
1802 r = sd_bus_message_set_destination(m, destination);
1803 if (r < 0)
1804 return r;
1805 }
1806
693eb9a2 1807 return sd_bus_send(bus, m, cookie);
911121a7
LP
1808}
1809
de1c301e
LP
1810static usec_t calc_elapse(uint64_t usec) {
1811 if (usec == (uint64_t) -1)
1812 return 0;
1813
de1c301e
LP
1814 return now(CLOCK_MONOTONIC) + usec;
1815}
1816
e3017af9
LP
1817static int timeout_compare(const void *a, const void *b) {
1818 const struct reply_callback *x = a, *y = b;
1819
1820 if (x->timeout != 0 && y->timeout == 0)
1821 return -1;
1822
1823 if (x->timeout == 0 && y->timeout != 0)
1824 return 1;
1825
1826 if (x->timeout < y->timeout)
1827 return -1;
1828
1829 if (x->timeout > y->timeout)
1830 return 1;
1831
1832 return 0;
1833}
1834
c49b30a2 1835_public_ int sd_bus_call_async(
de1c301e 1836 sd_bus *bus,
19befb2d 1837 sd_bus_slot **slot,
e1c433c6 1838 sd_bus_message *_m,
52f3ba91 1839 sd_bus_message_handler_t callback,
de1c301e 1840 void *userdata,
19befb2d 1841 uint64_t usec) {
de1c301e 1842
e1c433c6 1843 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
19befb2d 1844 _cleanup_bus_slot_unref_ sd_bus_slot *s = NULL;
de1c301e
LP
1845 int r;
1846
d6888822 1847 assert_return(m, -EINVAL);
40ca29a1 1848 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
0461f8cd 1849 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
d6888822 1850 assert_return(callback, -EINVAL);
9030ca46
LP
1851
1852 if (!bus)
1853 bus = m->bus;
1854
d6888822 1855 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1856 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
89ffcd2a 1857
a3d59cd1
LP
1858 if (!BUS_IS_OPEN(bus->state))
1859 return -ENOTCONN;
1860
c9fe4af7 1861 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
89ffcd2a
LP
1862 if (r < 0)
1863 return r;
de1c301e 1864
3df7a7e6
LP
1865 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1866 if (r < 0)
1867 return r;
e3017af9 1868
3df7a7e6 1869 r = bus_seal_message(bus, m, usec);
de1c301e
LP
1870 if (r < 0)
1871 return r;
1872
e1c433c6
LP
1873 r = bus_remarshal_message(bus, &m);
1874 if (r < 0)
1875 return r;
1876
19befb2d
LP
1877 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
1878 if (!s)
de1c301e
LP
1879 return -ENOMEM;
1880
19befb2d 1881 s->reply_callback.callback = callback;
de1c301e 1882
19befb2d 1883 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
c9fe4af7 1884 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
de1c301e 1885 if (r < 0) {
19befb2d 1886 s->reply_callback.cookie = 0;
de1c301e
LP
1887 return r;
1888 }
1889
19befb2d
LP
1890 s->reply_callback.timeout = calc_elapse(m->timeout);
1891 if (s->reply_callback.timeout != 0) {
1892 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
e3017af9 1893 if (r < 0) {
19befb2d 1894 s->reply_callback.timeout = 0;
e3017af9
LP
1895 return r;
1896 }
1897 }
1898
19befb2d
LP
1899 r = sd_bus_send(bus, m, &s->reply_callback.cookie);
1900 if (r < 0)
de1c301e 1901 return r;
de1c301e 1902
19befb2d
LP
1903 if (slot)
1904 *slot = s;
1905 s = NULL;
e3017af9 1906
19befb2d 1907 return r;
de1c301e
LP
1908}
1909
20902f3e 1910int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1911 int r;
1912
1913 assert(bus);
1914
718db961 1915 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED || bus->state == BUS_CLOSING)
021a1e78 1916 return -ENOTCONN;
d728d708
LP
1917 if (bus->state == BUS_RUNNING)
1918 return 1;
89ffcd2a
LP
1919
1920 for (;;) {
1921 r = sd_bus_process(bus, NULL);
1922 if (r < 0)
1923 return r;
d728d708
LP
1924 if (bus->state == BUS_RUNNING)
1925 return 1;
e3017af9
LP
1926 if (r > 0)
1927 continue;
89ffcd2a
LP
1928
1929 r = sd_bus_wait(bus, (uint64_t) -1);
1930 if (r < 0)
1931 return r;
1932 }
1933}
1934
97f82db3 1935_public_ int sd_bus_call(
de1c301e 1936 sd_bus *bus,
97f82db3 1937 sd_bus_message *_m,
de1c301e
LP
1938 uint64_t usec,
1939 sd_bus_error *error,
1940 sd_bus_message **reply) {
1941
97f82db3 1942 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e 1943 usec_t timeout;
693eb9a2 1944 uint64_t cookie;
7d22c717
LP
1945 unsigned i;
1946 int r;
de1c301e 1947
97f82db3
KS
1948 assert_return(m, -EINVAL);
1949 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
1950 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1951 assert_return(!bus_error_is_dirty(error), -EINVAL);
9030ca46
LP
1952
1953 if (!bus)
1954 bus = m->bus;
1955
97f82db3 1956 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1957 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
97f82db3 1958
a3d59cd1
LP
1959 if (!BUS_IS_OPEN(bus->state))
1960 return -ENOTCONN;
1961
97f82db3
KS
1962 r = bus_ensure_running(bus);
1963 if (r < 0)
1964 return r;
1965
a43b9ca3 1966 i = bus->rqueue_size;
97f82db3
KS
1967
1968 r = bus_seal_message(bus, m, usec);
1969 if (r < 0)
1970 return r;
1971
1972 r = bus_remarshal_message(bus, &m);
1973 if (r < 0)
1974 return r;
1975
069f5e61 1976 r = bus_send_internal(bus, m, &cookie, true);
de1c301e
LP
1977 if (r < 0)
1978 return r;
1979
3df7a7e6 1980 timeout = calc_elapse(m->timeout);
de1c301e
LP
1981
1982 for (;;) {
1983 usec_t left;
de1c301e 1984
7d22c717
LP
1985 while (i < bus->rqueue_size) {
1986 sd_bus_message *incoming = NULL;
1987
1988 incoming = bus->rqueue[i];
89ffcd2a 1989
693eb9a2 1990 if (incoming->reply_cookie == cookie) {
de1c301e
LP
1991 /* Found a match! */
1992
7d22c717
LP
1993 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1994 bus->rqueue_size--;
1995
40ca29a1 1996 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0 1997
2ce97e2b
LP
1998 if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
1999 if (reply)
2000 *reply = incoming;
2001 else
2002 sd_bus_message_unref(incoming);
2003
2004 return 1;
2005 }
2006
2007 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
b7f247e0 2008
a43b9ca3 2009 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
de1c301e 2010 r = sd_bus_error_copy(error, &incoming->error);
a43b9ca3
LP
2011 else
2012 r = -EIO;
de1c301e
LP
2013
2014 sd_bus_message_unref(incoming);
a43b9ca3 2015 return r;
a8a07f89 2016
693eb9a2 2017 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
a8a07f89
LP
2018 bus->unique_name &&
2019 incoming->sender &&
2020 streq(bus->unique_name, incoming->sender)) {
2021
7d22c717
LP
2022 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
2023 bus->rqueue_size--;
2024
a8a07f89
LP
2025 /* Our own message? Somebody is trying
2026 * to send its own client a message,
2027 * let's not dead-lock, let's fail
2028 * immediately. */
2029
2030 sd_bus_message_unref(incoming);
2031 return -ELOOP;
de1c301e
LP
2032 }
2033
de1c301e 2034 /* Try to read more, right-away */
7d22c717 2035 i++;
de1c301e 2036 }
7d22c717 2037
766c5809 2038 r = bus_read_message(bus, false, 0);
32f46480 2039 if (r < 0) {
441d56a1 2040 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2041 bus_enter_closing(bus);
441d56a1
LP
2042 return -ECONNRESET;
2043 }
32f46480 2044
a43b9ca3 2045 return r;
32f46480 2046 }
7d22c717 2047 if (r > 0)
e3017af9 2048 continue;
de1c301e
LP
2049
2050 if (timeout > 0) {
2051 usec_t n;
2052
2053 n = now(CLOCK_MONOTONIC);
2054 if (n >= timeout)
2055 return -ETIMEDOUT;
2056
2057 left = timeout - n;
2058 } else
2059 left = (uint64_t) -1;
2060
e3017af9 2061 r = bus_poll(bus, true, left);
de1c301e
LP
2062 if (r < 0)
2063 return r;
f8e11cda
LP
2064 if (r == 0)
2065 return -ETIMEDOUT;
de1c301e
LP
2066
2067 r = dispatch_wqueue(bus);
32f46480 2068 if (r < 0) {
441d56a1 2069 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2070 bus_enter_closing(bus);
441d56a1
LP
2071 return -ECONNRESET;
2072 }
32f46480 2073
de1c301e 2074 return r;
32f46480 2075 }
de1c301e
LP
2076 }
2077}
2078
d9f644e2 2079_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
2080
2081 assert_return(bus, -EINVAL);
d6888822
LP
2082 assert_return(bus->input_fd == bus->output_fd, -EPERM);
2083 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2084
e82c9509 2085 return bus->input_fd;
de1c301e
LP
2086}
2087
d9f644e2 2088_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
2089 int flags = 0;
2090
d6888822 2091 assert_return(bus, -EINVAL);
d6888822 2092 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2093
a3d59cd1
LP
2094 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2095 return -ENOTCONN;
2096
de1c301e
LP
2097 if (bus->state == BUS_OPENING)
2098 flags |= POLLOUT;
89ffcd2a
LP
2099 else if (bus->state == BUS_AUTHENTICATING) {
2100
2181a7f5 2101 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
2102 flags |= POLLOUT;
2103
2104 flags |= POLLIN;
2105
2106 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
2107 if (bus->rqueue_size <= 0)
2108 flags |= POLLIN;
2109 if (bus->wqueue_size > 0)
2110 flags |= POLLOUT;
2111 }
2112
2113 return flags;
2114}
2115
d9f644e2 2116_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
2117 struct reply_callback *c;
2118
d6888822
LP
2119 assert_return(bus, -EINVAL);
2120 assert_return(timeout_usec, -EINVAL);
d6888822 2121 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 2122
a3d59cd1
LP
2123 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2124 return -ENOTCONN;
2125
8f8f05a9
LP
2126 if (bus->track_queue) {
2127 *timeout_usec = 0;
2128 return 1;
2129 }
2130
718db961
LP
2131 if (bus->state == BUS_CLOSING) {
2132 *timeout_usec = 0;
2133 return 1;
2134 }
2135
e3017af9
LP
2136 if (bus->state == BUS_AUTHENTICATING) {
2137 *timeout_usec = bus->auth_timeout;
2138 return 1;
2139 }
2140
adee69fa
LP
2141 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
2142 *timeout_usec = (uint64_t) -1;
e3017af9 2143 return 0;
adee69fa 2144 }
e3017af9 2145
8efd6381
LP
2146 if (bus->rqueue_size > 0) {
2147 *timeout_usec = 0;
2148 return 1;
2149 }
2150
e3017af9 2151 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
2152 if (!c) {
2153 *timeout_usec = (uint64_t) -1;
e3017af9 2154 return 0;
adee69fa 2155 }
e3017af9 2156
19befb2d
LP
2157 if (c->timeout == 0) {
2158 *timeout_usec = (uint64_t) -1;
2159 return 0;
2160 }
2161
e3017af9
LP
2162 *timeout_usec = c->timeout;
2163 return 1;
2164}
2165
2166static int process_timeout(sd_bus *bus) {
ebcf1f97 2167 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
eb01ba5d 2168 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9 2169 struct reply_callback *c;
1b64f838 2170 sd_bus_slot *slot;
e3017af9
LP
2171 usec_t n;
2172 int r;
2173
2174 assert(bus);
2175
2176 c = prioq_peek(bus->reply_callbacks_prioq);
2177 if (!c)
2178 return 0;
2179
2180 n = now(CLOCK_MONOTONIC);
2181 if (c->timeout > n)
2182 return 0;
2183
eb01ba5d
LP
2184 r = bus_message_new_synthetic_error(
2185 bus,
693eb9a2 2186 c->cookie,
14c24659 2187 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
2188 &m);
2189 if (r < 0)
2190 return r;
2191
7adc46fc 2192 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2193 if (r < 0)
2194 return r;
2195
e3017af9 2196 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
19befb2d
LP
2197 c->timeout = 0;
2198
c9fe4af7 2199 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2200 c->cookie = 0;
2201
1b64f838 2202 slot = container_of(c, sd_bus_slot, reply_callback);
e3017af9 2203
718db961
LP
2204 bus->iteration_counter ++;
2205
1b64f838
LP
2206 bus->current_message = m;
2207 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2208 bus->current_handler = c->callback;
2209 bus->current_userdata = slot->userdata;
19070062 2210 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2211 bus->current_userdata = NULL;
2212 bus->current_handler = NULL;
d974ad05 2213 bus->current_slot = NULL;
19befb2d 2214 bus->current_message = NULL;
718db961 2215
1b64f838
LP
2216 if (slot->floating) {
2217 bus_slot_disconnect(slot);
2218 sd_bus_slot_unref(slot);
2219 }
2220
d974ad05
DH
2221 sd_bus_slot_unref(slot);
2222
1b64f838 2223 return bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
2224}
2225
9d373862
LP
2226static int process_hello(sd_bus *bus, sd_bus_message *m) {
2227 assert(bus);
2228 assert(m);
2229
2230 if (bus->state != BUS_HELLO)
2231 return 0;
2232
2233 /* Let's make sure the first message on the bus is the HELLO
2234 * reply. But note that we don't actually parse the message
2181a7f5
LP
2235 * here (we leave that to the usual handling), we just verify
2236 * we don't let any earlier msg through. */
9d373862 2237
40ca29a1
LP
2238 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2239 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
2240 return -EIO;
2241
19befb2d 2242 if (m->reply_cookie != 1)
9d373862
LP
2243 return -EIO;
2244
2245 return 0;
2246}
2247
a652755d 2248static int process_reply(sd_bus *bus, sd_bus_message *m) {
2ce97e2b 2249 _cleanup_bus_message_unref_ sd_bus_message *synthetic_reply = NULL;
ebcf1f97 2250 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
19befb2d 2251 struct reply_callback *c;
1b64f838 2252 sd_bus_slot *slot;
a652755d
LP
2253 int r;
2254
2255 assert(bus);
2256 assert(m);
2257
40ca29a1
LP
2258 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2259 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
2260 return 0;
2261
09365592
LP
2262 if (bus->is_kernel && (bus->hello_flags & KDBUS_HELLO_MONITOR))
2263 return 0;
2264
2265 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2266 return 0;
2267
c9fe4af7 2268 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
a652755d
LP
2269 if (!c)
2270 return 0;
2271
19befb2d 2272 c->cookie = 0;
19befb2d 2273
1b64f838 2274 slot = container_of(c, sd_bus_slot, reply_callback);
a652755d 2275
2ce97e2b
LP
2276 if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
2277
2278 /* If the reply contained a file descriptor which we
2279 * didn't want we pass an error instead. */
2280
2281 r = bus_message_new_synthetic_error(
2282 bus,
2283 m->reply_cookie,
2284 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2285 &synthetic_reply);
2286 if (r < 0)
1b64f838 2287 return r;
2ce97e2b 2288
52cd5877
LP
2289 /* Copy over original timestamp */
2290 synthetic_reply->realtime = m->realtime;
2291 synthetic_reply->monotonic = m->monotonic;
2292 synthetic_reply->seqnum = m->seqnum;
2293
2ce97e2b
LP
2294 r = bus_seal_synthetic_message(bus, synthetic_reply);
2295 if (r < 0)
1b64f838 2296 return r;
2ce97e2b
LP
2297
2298 m = synthetic_reply;
2299 } else {
2300 r = sd_bus_message_rewind(m, true);
2301 if (r < 0)
1b64f838 2302 return r;
2ce97e2b 2303 }
88fe224c 2304
1b64f838
LP
2305 if (c->timeout != 0) {
2306 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2307 c->timeout = 0;
2308 }
19befb2d 2309
1b64f838 2310 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2311 bus->current_handler = c->callback;
2312 bus->current_userdata = slot->userdata;
19070062 2313 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2314 bus->current_userdata = NULL;
2315 bus->current_handler = NULL;
d974ad05 2316 bus->current_slot = NULL;
a652755d 2317
19befb2d
LP
2318 if (slot->floating) {
2319 bus_slot_disconnect(slot);
2320 sd_bus_slot_unref(slot);
2321 }
2322
d974ad05
DH
2323 sd_bus_slot_unref(slot);
2324
1b64f838 2325 return bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
2326}
2327
2328static int process_filter(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 2329 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
2330 struct filter_callback *l;
2331 int r;
2332
392d5b37
LP
2333 assert(bus);
2334 assert(m);
2335
7286037f
LP
2336 do {
2337 bus->filter_callbacks_modified = false;
2338
2339 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1b64f838 2340 sd_bus_slot *slot;
7286037f
LP
2341
2342 if (bus->filter_callbacks_modified)
2343 break;
2344
2345 /* Don't run this more than once per iteration */
2346 if (l->last_iteration == bus->iteration_counter)
2347 continue;
2348
2349 l->last_iteration = bus->iteration_counter;
2350
88fe224c
LP
2351 r = sd_bus_message_rewind(m, true);
2352 if (r < 0)
2353 return r;
2354
1b64f838
LP
2355 slot = container_of(l, sd_bus_slot, filter_callback);
2356
2357 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2358 bus->current_handler = l->callback;
2359 bus->current_userdata = slot->userdata;
19070062 2360 r = l->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2361 bus->current_userdata = NULL;
2362 bus->current_handler = NULL;
1b64f838 2363 bus->current_slot = sd_bus_slot_unref(slot);
19befb2d 2364
ebcf1f97 2365 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
2366 if (r != 0)
2367 return r;
2368
2369 }
2370
2371 } while (bus->filter_callbacks_modified);
a652755d
LP
2372
2373 return 0;
2374}
2375
392d5b37 2376static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
2377 int r;
2378
392d5b37
LP
2379 assert(bus);
2380 assert(m);
2381
7286037f
LP
2382 do {
2383 bus->match_callbacks_modified = false;
2384
eb01ba5d 2385 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
2386 if (r != 0)
2387 return r;
2388
2389 } while (bus->match_callbacks_modified);
2390
2391 return 0;
392d5b37
LP
2392}
2393
b9bf7e2b
LP
2394static int process_builtin(sd_bus *bus, sd_bus_message *m) {
2395 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2396 int r;
2397
2398 assert(bus);
2399 assert(m);
2400
09365592
LP
2401 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2402 return 0;
2403
758bf0c7
LP
2404 if (bus->manual_peer_interface)
2405 return 0;
2406
40ca29a1 2407 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2408 return 0;
2409
2410 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2411 return 0;
2412
0461f8cd 2413 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2414 return 1;
2415
2416 if (streq_ptr(m->member, "Ping"))
df2d202e 2417 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2418 else if (streq_ptr(m->member, "GetMachineId")) {
2419 sd_id128_t id;
2420 char sid[33];
2421
2422 r = sd_id128_get_machine(&id);
2423 if (r < 0)
2424 return r;
2425
df2d202e 2426 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2427 if (r < 0)
2428 return r;
2429
2430 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2431 } else {
29ddb38f 2432 r = sd_bus_message_new_method_errorf(
df2d202e 2433 m, &reply,
40ca29a1 2434 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2435 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2436 }
2437
2438 if (r < 0)
2439 return r;
2440
2441 r = sd_bus_send(bus, reply, NULL);
2442 if (r < 0)
2443 return r;
2444
2445 return 1;
2446}
2447
2ce97e2b
LP
2448static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2449 assert(bus);
2450 assert(m);
2451
2452 /* If we got a message with a file descriptor which we didn't
2453 * want to accept, then let's drop it. How can this even
2454 * happen? For example, when the kernel queues a message into
2455 * an activatable names's queue which allows fds, and then is
2456 * delivered to us later even though we ourselves did not
2457 * negotiate it. */
2458
09365592
LP
2459 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2460 return 0;
2461
2ce97e2b
LP
2462 if (m->n_fds <= 0)
2463 return 0;
2464
2465 if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2466 return 0;
2467
2468 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2469 return 1; /* just eat it up */
2470
2471 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2472}
2473
992c052c 2474static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2475 int r;
2476
2477 assert(bus);
992c052c 2478 assert(m);
e3017af9 2479
19befb2d 2480 bus->current_message = m;
992c052c 2481 bus->iteration_counter++;
e3017af9 2482
42c4ebcb 2483 log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
4cdf0751 2484 bus_message_type_to_string(m->header->type),
40ca29a1 2485 strna(sd_bus_message_get_sender(m)),
4cdf0751 2486 strna(sd_bus_message_get_destination(m)),
40ca29a1
LP
2487 strna(sd_bus_message_get_path(m)),
2488 strna(sd_bus_message_get_interface(m)),
4cdf0751 2489 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
2490 BUS_MESSAGE_COOKIE(m),
2491 m->reply_cookie,
4cdf0751 2492 strna(m->error.message));
40ca29a1 2493
992c052c
LP
2494 r = process_hello(bus, m);
2495 if (r != 0)
affff0b6 2496 goto finish;
a652755d 2497
992c052c
LP
2498 r = process_reply(bus, m);
2499 if (r != 0)
affff0b6 2500 goto finish;
e3017af9 2501
2ce97e2b
LP
2502 r = process_fd_check(bus, m);
2503 if (r != 0)
2504 goto finish;
2505
992c052c
LP
2506 r = process_filter(bus, m);
2507 if (r != 0)
affff0b6 2508 goto finish;
a652755d 2509
992c052c
LP
2510 r = process_match(bus, m);
2511 if (r != 0)
affff0b6 2512 goto finish;
a652755d 2513
992c052c
LP
2514 r = process_builtin(bus, m);
2515 if (r != 0)
affff0b6
LP
2516 goto finish;
2517
2518 r = bus_process_object(bus, m);
a652755d 2519
affff0b6 2520finish:
19befb2d 2521 bus->current_message = NULL;
affff0b6 2522 return r;
29ddb38f 2523}
88fe224c 2524
8f8f05a9
LP
2525static int dispatch_track(sd_bus *bus) {
2526 assert(bus);
2527
2528 if (!bus->track_queue)
2529 return 0;
2530
2531 bus_track_dispatch(bus->track_queue);
2532 return 1;
2533}
2534
766c5809 2535static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
992c052c 2536 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 2537 int r;
a652755d 2538
29ddb38f 2539 assert(bus);
992c052c 2540 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 2541
992c052c
LP
2542 r = process_timeout(bus);
2543 if (r != 0)
2544 goto null_message;
7286037f 2545
992c052c
LP
2546 r = dispatch_wqueue(bus);
2547 if (r != 0)
2548 goto null_message;
7286037f 2549
8f8f05a9
LP
2550 r = dispatch_track(bus);
2551 if (r != 0)
2552 goto null_message;
2553
766c5809 2554 r = dispatch_rqueue(bus, hint_priority, priority, &m);
992c052c
LP
2555 if (r < 0)
2556 return r;
2557 if (!m)
2558 goto null_message;
7286037f 2559
992c052c
LP
2560 r = process_message(bus, m);
2561 if (r != 0)
2562 goto null_message;
7286037f 2563
992c052c
LP
2564 if (ret) {
2565 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2566 if (r < 0)
2567 return r;
e3017af9 2568
992c052c
LP
2569 *ret = m;
2570 m = NULL;
2571 return 1;
2572 }
a652755d 2573
40ca29a1 2574 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2575
dc74ce9b
LP
2576 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2577 strna(sd_bus_message_get_sender(m)),
2578 strna(sd_bus_message_get_path(m)),
2579 strna(sd_bus_message_get_interface(m)),
2580 strna(sd_bus_message_get_member(m)));
2581
992c052c 2582 r = sd_bus_reply_method_errorf(
df2d202e 2583 m,
40ca29a1 2584 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2585 "Unknown object '%s'.", m->path);
29ddb38f
LP
2586 if (r < 0)
2587 return r;
2588 }
e3017af9 2589
992c052c 2590 return 1;
0a72c2bd 2591
992c052c
LP
2592null_message:
2593 if (r >= 0 && ret)
2594 *ret = NULL;
0a72c2bd 2595
992c052c 2596 return r;
29ddb38f 2597}
0a72c2bd 2598
718db961
LP
2599static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2600 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2601 struct reply_callback *c;
2602 int r;
2603
2604 assert(bus);
2605 assert(bus->state == BUS_CLOSING);
2606
c9fe4af7 2607 c = ordered_hashmap_first(bus->reply_callbacks);
718db961 2608 if (c) {
ebcf1f97 2609 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
1b64f838 2610 sd_bus_slot *slot;
ebcf1f97 2611
718db961
LP
2612 /* First, fail all outstanding method calls */
2613 r = bus_message_new_synthetic_error(
2614 bus,
693eb9a2 2615 c->cookie,
14c24659 2616 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
718db961
LP
2617 &m);
2618 if (r < 0)
2619 return r;
2620
7adc46fc 2621 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2622 if (r < 0)
2623 return r;
2624
19befb2d 2625 if (c->timeout != 0) {
718db961 2626 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
19befb2d
LP
2627 c->timeout = 0;
2628 }
718db961 2629
c9fe4af7 2630 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
19befb2d
LP
2631 c->cookie = 0;
2632
1b64f838 2633 slot = container_of(c, sd_bus_slot, reply_callback);
718db961 2634
718db961
LP
2635 bus->iteration_counter++;
2636
1b64f838
LP
2637 bus->current_message = m;
2638 bus->current_slot = sd_bus_slot_ref(slot);
caa82984
LP
2639 bus->current_handler = c->callback;
2640 bus->current_userdata = slot->userdata;
19070062 2641 r = c->callback(m, slot->userdata, &error_buffer);
caa82984
LP
2642 bus->current_userdata = NULL;
2643 bus->current_handler = NULL;
d974ad05 2644 bus->current_slot = NULL;
1b64f838
LP
2645 bus->current_message = NULL;
2646
2647 if (slot->floating) {
2648 bus_slot_disconnect(slot);
2649 sd_bus_slot_unref(slot);
2650 }
718db961 2651
d974ad05
DH
2652 sd_bus_slot_unref(slot);
2653
1b64f838 2654 return bus_maybe_reply_error(m, r, &error_buffer);
718db961
LP
2655 }
2656
2657 /* Then, synthesize a Disconnected message */
2658 r = sd_bus_message_new_signal(
2659 bus,
151b9b96 2660 &m,
718db961
LP
2661 "/org/freedesktop/DBus/Local",
2662 "org.freedesktop.DBus.Local",
151b9b96 2663 "Disconnected");
718db961
LP
2664 if (r < 0)
2665 return r;
2666
fb6d9b77 2667 bus_message_set_sender_local(bus, m);
34a2c9e8 2668
7adc46fc 2669 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2670 if (r < 0)
2671 return r;
2672
2673 sd_bus_close(bus);
2674
19befb2d 2675 bus->current_message = m;
718db961
LP
2676 bus->iteration_counter++;
2677
2678 r = process_filter(bus, m);
2679 if (r != 0)
2680 goto finish;
2681
2682 r = process_match(bus, m);
2683 if (r != 0)
2684 goto finish;
2685
2686 if (ret) {
2687 *ret = m;
2688 m = NULL;
2689 }
2690
2691 r = 1;
2692
2693finish:
19befb2d
LP
2694 bus->current_message = NULL;
2695
718db961
LP
2696 return r;
2697}
2698
766c5809 2699static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
8ce2afd6 2700 BUS_DONT_DESTROY(bus);
29ddb38f 2701 int r;
0a72c2bd 2702
992c052c
LP
2703 /* Returns 0 when we didn't do anything. This should cause the
2704 * caller to invoke sd_bus_wait() before returning the next
2705 * time. Returns > 0 when we did something, which possibly
2706 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2707
d6888822
LP
2708 assert_return(bus, -EINVAL);
2709 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2710
992c052c 2711 /* We don't allow recursively invoking sd_bus_process(). */
19befb2d
LP
2712 assert_return(!bus->current_message, -EBUSY);
2713 assert(!bus->current_slot);
0a72c2bd 2714
992c052c 2715 switch (bus->state) {
0a72c2bd 2716
992c052c 2717 case BUS_UNSET:
992c052c 2718 return -ENOTCONN;
0a72c2bd 2719
6d6f4904
LP
2720 case BUS_CLOSED:
2721 return -ECONNRESET;
2722
992c052c
LP
2723 case BUS_OPENING:
2724 r = bus_socket_process_opening(bus);
441d56a1 2725 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2726 bus_enter_closing(bus);
2727 r = 1;
2728 } else if (r < 0)
29ddb38f 2729 return r;
992c052c
LP
2730 if (ret)
2731 *ret = NULL;
a652755d
LP
2732 return r;
2733
992c052c 2734 case BUS_AUTHENTICATING:
992c052c 2735 r = bus_socket_process_authenticating(bus);
441d56a1 2736 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2737 bus_enter_closing(bus);
2738 r = 1;
2739 } else if (r < 0)
29ddb38f 2740 return r;
718db961 2741
992c052c
LP
2742 if (ret)
2743 *ret = NULL;
718db961 2744
992c052c 2745 return r;
a652755d 2746
992c052c
LP
2747 case BUS_RUNNING:
2748 case BUS_HELLO:
766c5809 2749 r = process_running(bus, hint_priority, priority, ret);
441d56a1 2750 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2751 bus_enter_closing(bus);
2752 r = 1;
2753
2754 if (ret)
2755 *ret = NULL;
2756 }
43a43f50 2757
43a43f50 2758 return r;
718db961
LP
2759
2760 case BUS_CLOSING:
2761 return process_closing(bus, ret);
992c052c 2762 }
43a43f50 2763
992c052c 2764 assert_not_reached("Unknown state");
e3017af9
LP
2765}
2766
766c5809
LP
2767_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2768 return bus_process_internal(bus, false, 0, ret);
2769}
2770
2771_public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2772 return bus_process_internal(bus, true, priority, ret);
2773}
2774
992c052c
LP
2775static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2776 struct pollfd p[2] = {};
2777 int r, e, n;
2778 struct timespec ts;
3a43da28 2779 usec_t m = USEC_INFINITY;
adcdb374
LP
2780
2781 assert(bus);
718db961
LP
2782
2783 if (bus->state == BUS_CLOSING)
2784 return 1;
2785
a3d59cd1
LP
2786 if (!BUS_IS_OPEN(bus->state))
2787 return -ENOTCONN;
adcdb374 2788
992c052c
LP
2789 e = sd_bus_get_events(bus);
2790 if (e < 0)
2791 return e;
adcdb374 2792
992c052c 2793 if (need_more)
8efd6381
LP
2794 /* The caller really needs some more data, he doesn't
2795 * care about what's already read, or any timeouts
ad67ef27 2796 * except its own. */
992c052c 2797 e |= POLLIN;
992c052c 2798 else {
8efd6381
LP
2799 usec_t until;
2800 /* The caller wants to process if there's something to
2801 * process, but doesn't care otherwise */
2802
2803 r = sd_bus_get_timeout(bus, &until);
2804 if (r < 0)
2805 return r;
2806 if (r > 0) {
2807 usec_t nw;
2808 nw = now(CLOCK_MONOTONIC);
2809 m = until > nw ? until - nw : 0;
2810 }
992c052c 2811 }
adcdb374 2812
992c052c
LP
2813 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2814 m = timeout_usec;
adcdb374 2815
992c052c
LP
2816 p[0].fd = bus->input_fd;
2817 if (bus->output_fd == bus->input_fd) {
2818 p[0].events = e;
2819 n = 1;
2820 } else {
2821 p[0].events = e & POLLIN;
2822 p[1].fd = bus->output_fd;
2823 p[1].events = e & POLLOUT;
2824 n = 2;
adcdb374
LP
2825 }
2826
992c052c 2827 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2828 if (r < 0)
992c052c 2829 return -errno;
adcdb374 2830
992c052c 2831 return r > 0 ? 1 : 0;
adcdb374
LP
2832}
2833
d9f644e2 2834_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2835
d6888822 2836 assert_return(bus, -EINVAL);
d6888822 2837 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2838
718db961
LP
2839 if (bus->state == BUS_CLOSING)
2840 return 0;
2841
a3d59cd1
LP
2842 if (!BUS_IS_OPEN(bus->state))
2843 return -ENOTCONN;
718db961 2844
992c052c
LP
2845 if (bus->rqueue_size > 0)
2846 return 0;
9db76355 2847
992c052c
LP
2848 return bus_poll(bus, false, timeout_usec);
2849}
9db76355 2850
d9f644e2 2851_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2852 int r;
9db76355 2853
d6888822 2854 assert_return(bus, -EINVAL);
d6888822 2855 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2856
718db961
LP
2857 if (bus->state == BUS_CLOSING)
2858 return 0;
2859
a3d59cd1
LP
2860 if (!BUS_IS_OPEN(bus->state))
2861 return -ENOTCONN;
718db961 2862
992c052c
LP
2863 r = bus_ensure_running(bus);
2864 if (r < 0)
2865 return r;
9db76355 2866
992c052c
LP
2867 if (bus->wqueue_size <= 0)
2868 return 0;
9db76355 2869
992c052c
LP
2870 for (;;) {
2871 r = dispatch_wqueue(bus);
32f46480 2872 if (r < 0) {
441d56a1 2873 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2874 bus_enter_closing(bus);
441d56a1
LP
2875 return -ECONNRESET;
2876 }
32f46480 2877
9db76355 2878 return r;
32f46480 2879 }
9db76355 2880
992c052c
LP
2881 if (bus->wqueue_size <= 0)
2882 return 0;
9db76355 2883
992c052c 2884 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2885 if (r < 0)
2886 return r;
9db76355 2887 }
9db76355
LP
2888}
2889
19befb2d
LP
2890_public_ int sd_bus_add_filter(
2891 sd_bus *bus,
2892 sd_bus_slot **slot,
2893 sd_bus_message_handler_t callback,
2894 void *userdata) {
d9f644e2 2895
19befb2d 2896 sd_bus_slot *s;
de1c301e 2897
d6888822
LP
2898 assert_return(bus, -EINVAL);
2899 assert_return(callback, -EINVAL);
2900 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2901
19befb2d
LP
2902 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
2903 if (!s)
29ddb38f
LP
2904 return -ENOMEM;
2905
19befb2d 2906 s->filter_callback.callback = callback;
a652755d 2907
19befb2d
LP
2908 bus->filter_callbacks_modified = true;
2909 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
a652755d 2910
19befb2d
LP
2911 if (slot)
2912 *slot = s;
29ddb38f 2913
992c052c 2914 return 0;
a652755d 2915}
392d5b37 2916
19befb2d
LP
2917_public_ int sd_bus_add_match(
2918 sd_bus *bus,
2919 sd_bus_slot **slot,
2920 const char *match,
2921 sd_bus_message_handler_t callback,
2922 void *userdata) {
d9f644e2 2923
992c052c
LP
2924 struct bus_match_component *components = NULL;
2925 unsigned n_components = 0;
2915234d 2926 sd_bus_slot *s = NULL;
992c052c 2927 int r = 0;
392d5b37 2928
d6888822
LP
2929 assert_return(bus, -EINVAL);
2930 assert_return(match, -EINVAL);
2931 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2932
992c052c
LP
2933 r = bus_match_parse(match, &components, &n_components);
2934 if (r < 0)
2935 goto finish;
29ddb38f 2936
19befb2d
LP
2937 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
2938 if (!s) {
2939 r = -ENOMEM;
2940 goto finish;
2941 }
2942
2943 s->match_callback.callback = callback;
2944 s->match_callback.cookie = ++bus->match_cookie;
2945
992c052c 2946 if (bus->bus_client) {
29ddb38f 2947
19befb2d
LP
2948 if (!bus->is_kernel) {
2949 /* When this is not a kernel transport, we
2950 * store the original match string, so that we
2951 * can use it to remove the match again */
2952
2953 s->match_callback.match_string = strdup(match);
2954 if (!s->match_callback.match_string) {
2955 r = -ENOMEM;
2956 goto finish;
2957 }
2958 }
2959
2960 r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie);
992c052c
LP
2961 if (r < 0)
2962 goto finish;
392d5b37
LP
2963 }
2964
992c052c 2965 bus->match_callbacks_modified = true;
19befb2d
LP
2966 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
2967 if (r < 0)
2968 goto finish;
2969
2970 if (slot)
2971 *slot = s;
2972 s = NULL;
917b5dc7 2973
992c052c
LP
2974finish:
2975 bus_match_parse_free(components, n_components);
19befb2d
LP
2976 sd_bus_slot_unref(s);
2977
992c052c 2978 return r;
917b5dc7
LP
2979}
2980
19befb2d
LP
2981int bus_remove_match_by_string(
2982 sd_bus *bus,
2983 const char *match,
2984 sd_bus_message_handler_t callback,
2985 void *userdata) {
d9f644e2 2986
992c052c
LP
2987 struct bus_match_component *components = NULL;
2988 unsigned n_components = 0;
19befb2d
LP
2989 struct match_callback *c;
2990 int r = 0;
917b5dc7 2991
d6888822
LP
2992 assert_return(bus, -EINVAL);
2993 assert_return(match, -EINVAL);
2994 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2995
992c052c 2996 r = bus_match_parse(match, &components, &n_components);
29ddb38f 2997 if (r < 0)
19befb2d 2998 goto finish;
f10dda3b 2999
19befb2d
LP
3000 r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c);
3001 if (r <= 0)
3002 goto finish;
f10dda3b 3003
19befb2d 3004 sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback));
f10dda3b 3005
19befb2d 3006finish:
992c052c 3007 bus_match_parse_free(components, n_components);
f10dda3b 3008
19befb2d 3009 return r;
f10dda3b
LP
3010}
3011
992c052c
LP
3012bool bus_pid_changed(sd_bus *bus) {
3013 assert(bus);
f10dda3b 3014
992c052c
LP
3015 /* We don't support people creating a bus connection and
3016 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 3017
992c052c 3018 return bus->original_pid != getpid();
d5a2b9a6 3019}
40ca29a1
LP
3020
3021static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 3022 sd_bus *bus = userdata;
40ca29a1
LP
3023 int r;
3024
3025 assert(bus);
3026
3027 r = sd_bus_process(bus, NULL);
3028 if (r < 0)
3029 return r;
3030
3031 return 1;
3032}
3033
3034static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 3035 sd_bus *bus = userdata;
40ca29a1
LP
3036 int r;
3037
3038 assert(bus);
3039
3040 r = sd_bus_process(bus, NULL);
3041 if (r < 0)
3042 return r;
3043
3044 return 1;
3045}
3046
3047static int prepare_callback(sd_event_source *s, void *userdata) {
3048 sd_bus *bus = userdata;
3049 int r, e;
3050 usec_t until;
3051
3052 assert(s);
3053 assert(bus);
3054
3055 e = sd_bus_get_events(bus);
3056 if (e < 0)
3057 return e;
3058
3059 if (bus->output_fd != bus->input_fd) {
3060
3061 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
3062 if (r < 0)
3063 return r;
3064
3065 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
3066 if (r < 0)
3067 return r;
3068 } else {
3069 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
3070 if (r < 0)
3071 return r;
3072 }
3073
3074 r = sd_bus_get_timeout(bus, &until);
3075 if (r < 0)
3076 return r;
3077 if (r > 0) {
3078 int j;
3079
3080 j = sd_event_source_set_time(bus->time_event_source, until);
3081 if (j < 0)
3082 return j;
3083 }
3084
3085 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3086 if (r < 0)
3087 return r;
3088
3089 return 1;
3090}
3091
abc5fe72
LP
3092static int quit_callback(sd_event_source *event, void *userdata) {
3093 sd_bus *bus = userdata;
3094
3095 assert(event);
3096
3097 sd_bus_flush(bus);
7bb4d371 3098 sd_bus_close(bus);
abc5fe72
LP
3099
3100 return 1;
3101}
3102
1e05d493
LP
3103static int attach_io_events(sd_bus *bus) {
3104 int r;
3105
3106 assert(bus);
3107
3108 if (bus->input_fd < 0)
3109 return 0;
3110
3111 if (!bus->event)
3112 return 0;
3113
3114 if (!bus->input_io_event_source) {
151b9b96 3115 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
1e05d493
LP
3116 if (r < 0)
3117 return r;
3118
3119 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3120 if (r < 0)
3121 return r;
3122
3123 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
9021bb9f
TG
3124 if (r < 0)
3125 return r;
3126
356779df 3127 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
1e05d493
LP
3128 } else
3129 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3130
3131 if (r < 0)
3132 return r;
3133
3134 if (bus->output_fd != bus->input_fd) {
3135 assert(bus->output_fd >= 0);
3136
3137 if (!bus->output_io_event_source) {
151b9b96 3138 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
1e05d493
LP
3139 if (r < 0)
3140 return r;
3141
3142 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
9021bb9f
TG
3143 if (r < 0)
3144 return r;
3145
356779df 3146 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
1e05d493
LP
3147 } else
3148 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3149
3150 if (r < 0)
3151 return r;
3152 }
3153
3154 return 0;
3155}
3156
3157static void detach_io_events(sd_bus *bus) {
3158 assert(bus);
3159
3160 if (bus->input_io_event_source) {
3161 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3162 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3163 }
3164
3165 if (bus->output_io_event_source) {
3166 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3167 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3168 }
3169}
3170
d9f644e2 3171_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
3172 int r;
3173
3174 assert_return(bus, -EINVAL);
40ca29a1
LP
3175 assert_return(!bus->event, -EBUSY);
3176
3177 assert(!bus->input_io_event_source);
3178 assert(!bus->output_io_event_source);
3179 assert(!bus->time_event_source);
3180
76b54375
LP
3181 if (event)
3182 bus->event = sd_event_ref(event);
3183 else {
3184 r = sd_event_default(&bus->event);
3185 if (r < 0)
3186 return r;
3187 }
40ca29a1 3188
1e05d493 3189 bus->event_priority = priority;
40ca29a1 3190
6a0f1f6d 3191 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
40ca29a1
LP
3192 if (r < 0)
3193 goto fail;
3194
3195 r = sd_event_source_set_priority(bus->time_event_source, priority);
3196 if (r < 0)
3197 goto fail;
3198
356779df 3199 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
9021bb9f
TG
3200 if (r < 0)
3201 goto fail;
3202
151b9b96 3203 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
abc5fe72
LP
3204 if (r < 0)
3205 goto fail;
3206
356779df 3207 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
9021bb9f
TG
3208 if (r < 0)
3209 goto fail;
3210
1e05d493
LP
3211 r = attach_io_events(bus);
3212 if (r < 0)
3213 goto fail;
3214
40ca29a1
LP
3215 return 0;
3216
3217fail:
3218 sd_bus_detach_event(bus);
3219 return r;
3220}
3221
d9f644e2 3222_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 3223 assert_return(bus, -EINVAL);
a82cafb9
LP
3224
3225 if (!bus->event)
3226 return 0;
40ca29a1 3227
1e05d493 3228 detach_io_events(bus);
40ca29a1 3229
86befb40
LP
3230 if (bus->time_event_source) {
3231 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 3232 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 3233 }
40ca29a1 3234
86befb40
LP
3235 if (bus->quit_event_source) {
3236 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 3237 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 3238 }
abc5fe72 3239
93f1bcf4 3240 bus->event = sd_event_unref(bus->event);
a82cafb9 3241 return 1;
40ca29a1 3242}
affff0b6 3243
2be44176
LP
3244_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3245 assert_return(bus, NULL);
3246
3247 return bus->event;
3248}
3249
19befb2d
LP
3250_public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3251 assert_return(bus, NULL);
3252
3253 return bus->current_message;
3254}
3255
3256_public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
affff0b6
LP
3257 assert_return(bus, NULL);
3258
19befb2d 3259 return bus->current_slot;
affff0b6 3260}
76b54375 3261
caa82984
LP
3262_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3263 assert_return(bus, NULL);
3264
3265 return bus->current_handler;
3266}
3267
3268_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3269 assert_return(bus, NULL);
3270
3271 return bus->current_userdata;
3272}
3273
76b54375
LP
3274static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3275 sd_bus *b = NULL;
3276 int r;
3277
3278 assert(bus_open);
3279 assert(default_bus);
3280
3281 if (!ret)
3282 return !!*default_bus;
3283
3284 if (*default_bus) {
3285 *ret = sd_bus_ref(*default_bus);
3286 return 0;
3287 }
3288
3289 r = bus_open(&b);
3290 if (r < 0)
3291 return r;
3292
3293 b->default_bus_ptr = default_bus;
3294 b->tid = gettid();
3295 *default_bus = b;
3296
3297 *ret = b;
3298 return 1;
3299}
3300
3301_public_ int sd_bus_default_system(sd_bus **ret) {
ec202eae 3302 static thread_local sd_bus *default_system_bus = NULL;
76b54375
LP
3303
3304 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3305}
3306
3307_public_ int sd_bus_default_user(sd_bus **ret) {
ec202eae 3308 static thread_local sd_bus *default_user_bus = NULL;
76b54375
LP
3309
3310 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3311}
3312
af08d2f9
LP
3313_public_ int sd_bus_default(sd_bus **ret) {
3314
3315 const char *e;
3316
3317 /* Let's try our best to reuse another cached connection. If
3318 * the starter bus type is set, connect via our normal
3319 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3320 * we can share the connection with the user/system default
3321 * bus. */
3322
3323 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3324 if (e) {
3325 if (streq(e, "system"))
3326 return sd_bus_default_system(ret);
09365592 3327 else if (STR_IN_SET(e, "user", "session"))
af08d2f9
LP
3328 return sd_bus_default_user(ret);
3329 }
3330
3331 /* No type is specified, so we have not other option than to
3332 * use the starter address if it is set. */
3333
3334 e = secure_getenv("DBUS_STARTER_ADDRESS");
3335 if (e) {
3336 static thread_local sd_bus *default_starter_bus = NULL;
3337
3338 return bus_default(sd_bus_open, &default_starter_bus, ret);
3339 }
3340
3341 /* Finally, if nothing is set use the cached connection for
3342 * the right scope */
3343
3344 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3345 return sd_bus_default_user(ret);
3346 else
3347 return sd_bus_default_system(ret);
3348}
3349
76b54375
LP
3350_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3351 assert_return(b, -EINVAL);
3352 assert_return(tid, -EINVAL);
3353 assert_return(!bus_pid_changed(b), -ECHILD);
3354
3355 if (b->tid != 0) {
3356 *tid = b->tid;
3357 return 0;
3358 }
3359
3360 if (b->event)
3361 return sd_event_get_tid(b->event, tid);
3362
3363 return -ENXIO;
3364}
28383ba1 3365
a6278b88
LP
3366_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3367 _cleanup_free_ char *e = NULL;
3368 char *ret;
3369
3370 assert_return(object_path_is_valid(prefix), -EINVAL);
3371 assert_return(external_id, -EINVAL);
3372 assert_return(ret_path, -EINVAL);
3373
3374 e = bus_label_escape(external_id);
3375 if (!e)
3376 return -ENOMEM;
3377
3378 ret = strjoin(prefix, "/", e, NULL);
3379 if (!ret)
3380 return -ENOMEM;
3381
3382 *ret_path = ret;
3383 return 0;
28383ba1
LP
3384}
3385
a6278b88
LP
3386_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3387 const char *e;
3388 char *ret;
3389
3390 assert_return(object_path_is_valid(path), -EINVAL);
3391 assert_return(object_path_is_valid(prefix), -EINVAL);
3392 assert_return(external_id, -EINVAL);
3393
3394 e = object_path_startswith(path, prefix);
3395 if (!e) {
3396 *external_id = NULL;
3397 return 0;
3398 }
3399
3400 ret = bus_label_unescape(e);
3401 if (!ret)
3402 return -ENOMEM;
3403
3404 *external_id = ret;
3405 return 1;
28383ba1 3406}
5b12334d 3407
ae095f86
LP
3408_public_ int sd_bus_try_close(sd_bus *bus) {
3409 int r;
3410
3411 assert_return(bus, -EINVAL);
ae095f86 3412 assert_return(!bus_pid_changed(bus), -ECHILD);
a3d59cd1
LP
3413
3414 if (!bus->is_kernel)
15411c0c 3415 return -EOPNOTSUPP;
a3d59cd1
LP
3416
3417 if (!BUS_IS_OPEN(bus->state))
3418 return -ENOTCONN;
ae095f86 3419
bd746b8b
LP
3420 if (bus->rqueue_size > 0)
3421 return -EBUSY;
3422
14f862a5
LP
3423 if (bus->wqueue_size > 0)
3424 return -EBUSY;
3425
ae095f86
LP
3426 r = bus_kernel_try_close(bus);
3427 if (r < 0)
3428 return r;
3429
3430 sd_bus_close(bus);
3431 return 0;
3432}
5972fe95 3433
455971c1 3434_public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
5972fe95 3435 assert_return(bus, -EINVAL);
455971c1 3436 assert_return(description, -EINVAL);
f4b2933e 3437 assert_return(bus->description, -ENXIO);
5972fe95
LP
3438 assert_return(!bus_pid_changed(bus), -ECHILD);
3439
455971c1 3440 *description = bus->description;
5972fe95
LP
3441 return 0;
3442}
fe3f22d1
DK
3443
3444int bus_get_root_path(sd_bus *bus) {
3445 int r;
3446
3447 if (bus->cgroup_root)
3448 return 0;
3449
3450 r = cg_get_root_path(&bus->cgroup_root);
3451 if (r == -ENOENT) {
3452 bus->cgroup_root = strdup("/");
3453 if (!bus->cgroup_root)
3454 return -ENOMEM;
3455
3456 r = 0;
3457 }
3458
3459 return r;
3460}
3acc1daf
LP
3461
3462_public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
3463 int r;
3464
3465 assert_return(bus, -EINVAL);
3466 assert_return(scope, -EINVAL);
3467 assert_return(!bus_pid_changed(bus), -ECHILD);
3468
3469 if (bus->is_kernel) {
3470 _cleanup_free_ char *n = NULL;
3471 const char *dash;
3472
3473 r = bus_kernel_get_bus_name(bus, &n);
3474 if (r < 0)
3475 return r;
3476
3477 if (streq(n, "0-system")) {
3478 *scope = "system";
5b820358 3479 return 0;
3acc1daf
LP
3480 }
3481
3482 dash = strchr(n, '-');
d2df88ff 3483 if (streq_ptr(dash, "-user")) {
3acc1daf 3484 *scope = "user";
5b820358 3485 return 0;
3acc1daf
LP
3486 }
3487 }
3488
3489 if (bus->is_user) {
3490 *scope = "user";
5b820358 3491 return 0;
3acc1daf
LP
3492 }
3493
3494 if (bus->is_system) {
3495 *scope = "system";
5b820358
LP
3496 return 0;
3497 }
3498
3499 return -ENODATA;
3500}
3501
3502_public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
3503
3504 assert_return(bus, -EINVAL);
3505 assert_return(address, -EINVAL);
3506 assert_return(!bus_pid_changed(bus), -ECHILD);
3507
3508 if (bus->address) {
3509 *address = bus->address;
3510 return 0;
3acc1daf
LP
3511 }
3512
3513 return -ENODATA;
3514}
224b3787 3515
882897af 3516_public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
224b3787
LP
3517 assert_return(bus, -EINVAL);
3518 assert_return(mask, -EINVAL);
3519 assert_return(!bus_pid_changed(bus), -ECHILD);
3520
3521 *mask = bus->creds_mask;
3522 return 0;
3523}
3524
882897af 3525_public_ int sd_bus_is_bus_client(sd_bus *bus) {
224b3787
LP
3526 assert_return(bus, -EINVAL);
3527 assert_return(!bus_pid_changed(bus), -ECHILD);
3528
3529 return bus->bus_client;
3530}
3531
882897af 3532_public_ int sd_bus_is_server(sd_bus *bus) {
224b3787
LP
3533 assert_return(bus, -EINVAL);
3534 assert_return(!bus_pid_changed(bus), -ECHILD);
3535
3536 return bus->is_server;
3537}
3538
882897af 3539_public_ int sd_bus_is_anonymous(sd_bus *bus) {
224b3787
LP
3540 assert_return(bus, -EINVAL);
3541 assert_return(!bus_pid_changed(bus), -ECHILD);
3542
3543 return bus->anonymous_auth;
3544}
3545
882897af 3546_public_ int sd_bus_is_trusted(sd_bus *bus) {
224b3787
LP
3547 assert_return(bus, -EINVAL);
3548 assert_return(!bus_pid_changed(bus), -ECHILD);
3549
3550 return bus->trusted;
3551}
3552
882897af 3553_public_ int sd_bus_is_monitor(sd_bus *bus) {
224b3787
LP
3554 assert_return(bus, -EINVAL);
3555 assert_return(!bus_pid_changed(bus), -ECHILD);
3556
3557 return !!(bus->hello_flags & KDBUS_HELLO_MONITOR);
3558}