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