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