]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/sd-bus.c
bus: don't generate NameAcquired/NameLost messages in the library
[thirdparty/systemd.git] / src / libsystemd-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"
de1c301e
LP
37
38#include "sd-bus.h"
39#include "bus-internal.h"
40#include "bus-message.h"
41#include "bus-type.h"
a7e3212d 42#include "bus-socket.h"
6629161f 43#include "bus-kernel.h"
392d5b37 44#include "bus-control.h"
29ddb38f
LP
45#include "bus-introspect.h"
46#include "bus-signature.h"
992c052c 47#include "bus-objects.h"
40ca29a1 48#include "bus-util.h"
a7893c6b 49#include "bus-container.h"
de1c301e 50
e3017af9
LP
51static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
52
f54514f3
LP
53static void bus_close_fds(sd_bus *b) {
54 assert(b);
55
56 if (b->input_fd >= 0)
57 close_nointr_nofail(b->input_fd);
58
59 if (b->output_fd >= 0 && b->output_fd != b->input_fd)
60 close_nointr_nofail(b->output_fd);
61
62 b->input_fd = b->output_fd = -1;
63}
64
29ddb38f
LP
65static void bus_node_destroy(sd_bus *b, struct node *n) {
66 struct node_callback *c;
67 struct node_vtable *v;
68 struct node_enumerator *e;
69
70 assert(b);
71
72 if (!n)
73 return;
74
75 while (n->child)
76 bus_node_destroy(b, n->child);
77
78 while ((c = n->callbacks)) {
71fda00f 79 LIST_REMOVE(callbacks, n->callbacks, c);
29ddb38f
LP
80 free(c);
81 }
82
83 while ((v = n->vtables)) {
71fda00f 84 LIST_REMOVE(vtables, n->vtables, v);
29ddb38f
LP
85 free(v->interface);
86 free(v);
87 }
88
89 while ((e = n->enumerators)) {
71fda00f 90 LIST_REMOVE(enumerators, n->enumerators, e);
29ddb38f
LP
91 free(e);
92 }
93
94 if (n->parent)
71fda00f 95 LIST_REMOVE(siblings, n->parent->child, n);
29ddb38f
LP
96
97 assert_se(hashmap_remove(b->nodes, n->path) == n);
98 free(n->path);
99 free(n);
100}
101
0e586eae
LP
102static void bus_reset_queues(sd_bus *b) {
103 unsigned i;
104
105 assert(b);
106
107 for (i = 0; i < b->rqueue_size; i++)
108 sd_bus_message_unref(b->rqueue[i]);
109 free(b->rqueue);
110
111 for (i = 0; i < b->wqueue_size; i++)
112 sd_bus_message_unref(b->wqueue[i]);
113 free(b->wqueue);
114
115 b->rqueue = b->wqueue = NULL;
116 b->rqueue_size = b->wqueue_size = 0;
117}
118
de1c301e
LP
119static void bus_free(sd_bus *b) {
120 struct filter_callback *f;
29ddb38f 121 struct node *n;
de1c301e
LP
122
123 assert(b);
124
40ca29a1
LP
125 sd_bus_detach_event(b);
126
f54514f3 127 bus_close_fds(b);
de1c301e 128
63edf05e
LP
129 if (b->kdbus_buffer)
130 munmap(b->kdbus_buffer, KDBUS_POOL_SIZE);
131
de1c301e 132 free(b->rbuffer);
89ffcd2a 133 free(b->unique_name);
2181a7f5 134 free(b->auth_buffer);
89ffcd2a 135 free(b->address);
e9a967f9 136 free(b->kernel);
a7893c6b 137 free(b->machine);
89ffcd2a 138
2fd9ae2e
LP
139 free(b->exec_path);
140 strv_free(b->exec_argv);
141
2c93b4ef
LP
142 close_many(b->fds, b->n_fds);
143 free(b->fds);
144
0e586eae 145 bus_reset_queues(b);
de1c301e
LP
146
147 hashmap_free_free(b->reply_callbacks);
e3017af9 148 prioq_free(b->reply_callbacks_prioq);
de1c301e
LP
149
150 while ((f = b->filter_callbacks)) {
71fda00f 151 LIST_REMOVE(callbacks, b->filter_callbacks, f);
de1c301e
LP
152 free(f);
153 }
154
392d5b37
LP
155 bus_match_free(&b->match_callbacks);
156
29ddb38f
LP
157 hashmap_free_free(b->vtable_methods);
158 hashmap_free_free(b->vtable_properties);
159
160 while ((n = hashmap_first(b->nodes)))
161 bus_node_destroy(b, n);
162
163 hashmap_free(b->nodes);
164
bc7fd8cd
LP
165 bus_kernel_flush_memfd(b);
166
45fbe937
LP
167 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
168
de1c301e
LP
169 free(b);
170}
171
d9f644e2 172_public_ int sd_bus_new(sd_bus **ret) {
de1c301e
LP
173 sd_bus *r;
174
d6888822 175 assert_return(ret, -EINVAL);
021a1e78 176
de1c301e
LP
177 r = new0(sd_bus, 1);
178 if (!r)
021a1e78 179 return -ENOMEM;
de1c301e 180
e4ee6e5c 181 r->n_ref = REFCNT_INIT;
e82c9509 182 r->input_fd = r->output_fd = -1;
de1c301e 183 r->message_version = 1;
d21a7bb1
DM
184 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
185 r->attach_flags |= KDBUS_ATTACH_NAMES;
d5a2b9a6 186 r->original_pid = getpid();
de1c301e 187
45fbe937
LP
188 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
189
de1c301e
LP
190 /* We guarantee that wqueue always has space for at least one
191 * entry */
192 r->wqueue = new(sd_bus_message*, 1);
193 if (!r->wqueue) {
194 free(r);
021a1e78 195 return -ENOMEM;
de1c301e
LP
196 }
197
021a1e78
LP
198 *ret = r;
199 return 0;
200}
201
d9f644e2 202_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
021a1e78
LP
203 char *a;
204
d6888822
LP
205 assert_return(bus, -EINVAL);
206 assert_return(bus->state == BUS_UNSET, -EPERM);
207 assert_return(address, -EINVAL);
208 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
209
210 a = strdup(address);
211 if (!a)
212 return -ENOMEM;
213
214 free(bus->address);
215 bus->address = a;
216
217 return 0;
218}
219
d9f644e2 220_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822
LP
221 assert_return(bus, -EINVAL);
222 assert_return(bus->state == BUS_UNSET, -EPERM);
223 assert_return(input_fd >= 0, -EINVAL);
224 assert_return(output_fd >= 0, -EINVAL);
225 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 226
e82c9509
LP
227 bus->input_fd = input_fd;
228 bus->output_fd = output_fd;
021a1e78
LP
229 return 0;
230}
231
d9f644e2 232_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
2fd9ae2e
LP
233 char *p, **a;
234
d6888822
LP
235 assert_return(bus, -EINVAL);
236 assert_return(bus->state == BUS_UNSET, -EPERM);
237 assert_return(path, -EINVAL);
238 assert_return(!strv_isempty(argv), -EINVAL);
239 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e
LP
240
241 p = strdup(path);
242 if (!p)
243 return -ENOMEM;
244
245 a = strv_copy(argv);
246 if (!a) {
247 free(p);
248 return -ENOMEM;
249 }
250
251 free(bus->exec_path);
252 strv_free(bus->exec_argv);
253
254 bus->exec_path = p;
255 bus->exec_argv = a;
256
257 return 0;
258}
259
d9f644e2 260_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822
LP
261 assert_return(bus, -EINVAL);
262 assert_return(bus->state == BUS_UNSET, -EPERM);
263 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 264
94bbf1ba 265 bus->bus_client = !!b;
021a1e78
LP
266 return 0;
267}
268
d9f644e2 269_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822
LP
270 assert_return(bus, -EINVAL);
271 assert_return(bus->state == BUS_UNSET, -EPERM);
272 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 273
264ad849
LP
274 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
275 return 0;
276}
277
f21326e6 278_public_ int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b) {
16be4368
KS
279 assert_return(bus, -EINVAL);
280 assert_return(bus->state == BUS_UNSET, -EPERM);
281 assert_return(!bus_pid_changed(bus), -ECHILD);
282
d21a7bb1 283 SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b);
16be4368
KS
284 return 0;
285}
286
5b12334d 287_public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t mask) {
16be4368 288 assert_return(bus, -EINVAL);
5b12334d 289 assert_return(mask <= _SD_BUS_CREDS_MAX, -EINVAL);
16be4368
KS
290 assert_return(bus->state == BUS_UNSET, -EPERM);
291 assert_return(!bus_pid_changed(bus), -ECHILD);
292
87b522ae 293 return kdbus_translate_attach_flags(mask, &bus->creds_mask);
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
ebcf1f97 316static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
de1c301e
LP
317 const char *s;
318 int r;
319
320 assert(bus);
c99c09a2 321 assert(bus->state == BUS_HELLO || bus->state == BUS_CLOSING);
de1c301e
LP
322 assert(reply);
323
40ca29a1 324 r = sd_bus_message_get_errno(reply);
eb01ba5d
LP
325 if (r < 0)
326 return r;
40ca29a1
LP
327 if (r > 0)
328 return -r;
eb01ba5d 329
de1c301e
LP
330 r = sd_bus_message_read(reply, "s", &s);
331 if (r < 0)
332 return r;
333
dafb7591
LP
334 if (!service_name_is_valid(s) || s[0] != ':')
335 return -EBADMSG;
336
de1c301e
LP
337 bus->unique_name = strdup(s);
338 if (!bus->unique_name)
339 return -ENOMEM;
340
c99c09a2
LP
341 if (bus->state == BUS_HELLO)
342 bus->state = BUS_RUNNING;
dafb7591 343
de1c301e
LP
344 return 1;
345}
346
347static int bus_send_hello(sd_bus *bus) {
348 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
349 int r;
350
351 assert(bus);
352
6629161f 353 if (!bus->bus_client || bus->is_kernel)
021a1e78
LP
354 return 0;
355
de1c301e
LP
356 r = sd_bus_message_new_method_call(
357 bus,
358 "org.freedesktop.DBus",
359 "/",
360 "org.freedesktop.DBus",
361 "Hello",
362 &m);
363 if (r < 0)
364 return r;
365
c49b30a2 366 return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_serial);
de1c301e
LP
367}
368
a7e3212d 369int bus_start_running(sd_bus *bus) {
de1c301e
LP
370 assert(bus);
371
f08838da 372 if (bus->bus_client && !bus->is_kernel) {
de1c301e 373 bus->state = BUS_HELLO;
e3017af9 374 return 1;
de1c301e
LP
375 }
376
377 bus->state = BUS_RUNNING;
e3017af9 378 return 1;
de1c301e
LP
379}
380
381static int parse_address_key(const char **p, const char *key, char **value) {
382 size_t l, n = 0;
383 const char *a;
384 char *r = NULL;
385
386 assert(p);
387 assert(*p);
de1c301e
LP
388 assert(value);
389
2fd9ae2e
LP
390 if (key) {
391 l = strlen(key);
392 if (strncmp(*p, key, l) != 0)
393 return 0;
de1c301e 394
2fd9ae2e
LP
395 if ((*p)[l] != '=')
396 return 0;
de1c301e 397
2fd9ae2e
LP
398 if (*value)
399 return -EINVAL;
de1c301e 400
2fd9ae2e
LP
401 a = *p + l + 1;
402 } else
403 a = *p;
404
405 while (*a != ';' && *a != ',' && *a != 0) {
de1c301e
LP
406 char c, *t;
407
408 if (*a == '%') {
409 int x, y;
410
411 x = unhexchar(a[1]);
412 if (x < 0) {
413 free(r);
414 return x;
415 }
416
417 y = unhexchar(a[2]);
418 if (y < 0) {
419 free(r);
420 return y;
421 }
422
de1c301e 423 c = (char) ((x << 4) | y);
89ffcd2a
LP
424 a += 3;
425 } else {
de1c301e 426 c = *a;
89ffcd2a
LP
427 a++;
428 }
de1c301e 429
89ffcd2a 430 t = realloc(r, n + 2);
de1c301e
LP
431 if (!t) {
432 free(r);
433 return -ENOMEM;
434 }
435
436 r = t;
437 r[n++] = c;
438 }
439
89ffcd2a
LP
440 if (!r) {
441 r = strdup("");
442 if (!r)
443 return -ENOMEM;
444 } else
445 r[n] = 0;
446
447 if (*a == ',')
448 a++;
449
de1c301e 450 *p = a;
2fd9ae2e
LP
451
452 free(*value);
de1c301e 453 *value = r;
2fd9ae2e 454
de1c301e
LP
455 return 1;
456}
457
458static void skip_address_key(const char **p) {
459 assert(p);
460 assert(*p);
461
89ffcd2a
LP
462 *p += strcspn(*p, ",");
463
464 if (**p == ',')
465 (*p) ++;
de1c301e
LP
466}
467
2fd9ae2e
LP
468static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
469 _cleanup_free_ char *path = NULL, *abstract = NULL;
470 size_t l;
de1c301e
LP
471 int r;
472
473 assert(b);
2fd9ae2e
LP
474 assert(p);
475 assert(*p);
476 assert(guid);
de1c301e 477
2fd9ae2e
LP
478 while (**p != 0 && **p != ';') {
479 r = parse_address_key(p, "guid", guid);
480 if (r < 0)
481 return r;
482 else if (r > 0)
483 continue;
de1c301e 484
2fd9ae2e
LP
485 r = parse_address_key(p, "path", &path);
486 if (r < 0)
487 return r;
488 else if (r > 0)
489 continue;
de1c301e 490
2fd9ae2e
LP
491 r = parse_address_key(p, "abstract", &abstract);
492 if (r < 0)
493 return r;
494 else if (r > 0)
495 continue;
de1c301e 496
2fd9ae2e
LP
497 skip_address_key(p);
498 }
de1c301e 499
2fd9ae2e
LP
500 if (!path && !abstract)
501 return -EINVAL;
de1c301e 502
2fd9ae2e
LP
503 if (path && abstract)
504 return -EINVAL;
505
506 if (path) {
507 l = strlen(path);
508 if (l > sizeof(b->sockaddr.un.sun_path))
509 return -E2BIG;
de1c301e 510
2fd9ae2e
LP
511 b->sockaddr.un.sun_family = AF_UNIX;
512 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
513 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
514 } else if (abstract) {
515 l = strlen(abstract);
516 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
517 return -E2BIG;
518
519 b->sockaddr.un.sun_family = AF_UNIX;
520 b->sockaddr.un.sun_path[0] = 0;
521 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
522 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
523 }
524
525 return 0;
526}
527
528static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
529 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 530 int r;
b92bea5d
ZJS
531 struct addrinfo *result, hints = {
532 .ai_socktype = SOCK_STREAM,
533 .ai_flags = AI_ADDRCONFIG,
534 };
2fd9ae2e
LP
535
536 assert(b);
537 assert(p);
538 assert(*p);
539 assert(guid);
540
541 while (**p != 0 && **p != ';') {
542 r = parse_address_key(p, "guid", guid);
543 if (r < 0)
544 return r;
545 else if (r > 0)
546 continue;
547
548 r = parse_address_key(p, "host", &host);
549 if (r < 0)
550 return r;
551 else if (r > 0)
552 continue;
553
554 r = parse_address_key(p, "port", &port);
555 if (r < 0)
556 return r;
557 else if (r > 0)
558 continue;
559
560 r = parse_address_key(p, "family", &family);
561 if (r < 0)
562 return r;
563 else if (r > 0)
564 continue;
565
566 skip_address_key(p);
567 }
568
569 if (!host || !port)
570 return -EINVAL;
571
2fd9ae2e
LP
572 if (family) {
573 if (streq(family, "ipv4"))
574 hints.ai_family = AF_INET;
575 else if (streq(family, "ipv6"))
576 hints.ai_family = AF_INET6;
577 else
578 return -EINVAL;
579 }
580
581 r = getaddrinfo(host, port, &hints, &result);
582 if (r == EAI_SYSTEM)
583 return -errno;
584 else if (r != 0)
585 return -EADDRNOTAVAIL;
586
587 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
588 b->sockaddr_size = result->ai_addrlen;
589
590 freeaddrinfo(result);
591
592 return 0;
593}
594
595static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
596 char *path = NULL;
597 unsigned n_argv = 0, j;
598 char **argv = NULL;
599 int r;
600
601 assert(b);
602 assert(p);
603 assert(*p);
604 assert(guid);
605
606 while (**p != 0 && **p != ';') {
607 r = parse_address_key(p, "guid", guid);
608 if (r < 0)
609 goto fail;
610 else if (r > 0)
611 continue;
612
613 r = parse_address_key(p, "path", &path);
614 if (r < 0)
615 goto fail;
616 else if (r > 0)
617 continue;
618
619 if (startswith(*p, "argv")) {
620 unsigned ul;
621
622 errno = 0;
623 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 624 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
625 r = -EINVAL;
626 goto fail;
627 }
628
629 (*p) ++;
630
631 if (ul >= n_argv) {
632 char **x;
633
634 x = realloc(argv, sizeof(char*) * (ul + 2));
635 if (!x) {
636 r = -ENOMEM;
637 goto fail;
638 }
639
640 memset(x + n_argv, 0, sizeof(char*) * (ul - n_argv + 2));
641
642 argv = x;
643 n_argv = ul + 1;
644 }
645
646 r = parse_address_key(p, NULL, argv + ul);
de1c301e 647 if (r < 0)
2fd9ae2e 648 goto fail;
de1c301e 649
2fd9ae2e 650 continue;
de1c301e
LP
651 }
652
2fd9ae2e
LP
653 skip_address_key(p);
654 }
de1c301e 655
5a0f6033
LP
656 if (!path) {
657 r = -EINVAL;
2fd9ae2e 658 goto fail;
5a0f6033 659 }
de1c301e 660
2fd9ae2e
LP
661 /* Make sure there are no holes in the array, with the
662 * exception of argv[0] */
663 for (j = 1; j < n_argv; j++)
664 if (!argv[j]) {
665 r = -EINVAL;
666 goto fail;
667 }
668
669 if (argv && argv[0] == NULL) {
670 argv[0] = strdup(path);
671 if (!argv[0]) {
672 r = -ENOMEM;
673 goto fail;
674 }
675 }
de1c301e 676
2fd9ae2e
LP
677 b->exec_path = path;
678 b->exec_argv = argv;
679 return 0;
de1c301e 680
2fd9ae2e
LP
681fail:
682 for (j = 0; j < n_argv; j++)
683 free(argv[j]);
684
685 free(argv);
686 free(path);
687 return r;
688}
689
6629161f
LP
690static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
691 _cleanup_free_ char *path = NULL;
692 int r;
693
694 assert(b);
695 assert(p);
696 assert(*p);
697 assert(guid);
698
699 while (**p != 0 && **p != ';') {
700 r = parse_address_key(p, "guid", guid);
701 if (r < 0)
702 return r;
703 else if (r > 0)
704 continue;
705
706 r = parse_address_key(p, "path", &path);
707 if (r < 0)
708 return r;
709 else if (r > 0)
710 continue;
711
712 skip_address_key(p);
713 }
714
715 if (!path)
716 return -EINVAL;
717
718 free(b->kernel);
719 b->kernel = path;
720 path = NULL;
721
722 return 0;
723}
724
a7893c6b
LP
725static int parse_container_address(sd_bus *b, const char **p, char **guid) {
726 _cleanup_free_ char *machine = NULL;
727 int r;
728
729 assert(b);
730 assert(p);
731 assert(*p);
732 assert(guid);
733
734 while (**p != 0 && **p != ';') {
735 r = parse_address_key(p, "guid", guid);
736 if (r < 0)
737 return r;
738 else if (r > 0)
739 continue;
740
741 r = parse_address_key(p, "machine", &machine);
742 if (r < 0)
743 return r;
744 else if (r > 0)
745 continue;
746
747 skip_address_key(p);
748 }
749
750 if (!machine)
751 return -EINVAL;
752
753 free(b->machine);
754 b->machine = machine;
755 machine = NULL;
756
757 b->sockaddr.un.sun_family = AF_UNIX;
758 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
759 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1;
760
761 return 0;
762}
763
2fd9ae2e
LP
764static void bus_reset_parsed_address(sd_bus *b) {
765 assert(b);
766
767 zero(b->sockaddr);
768 b->sockaddr_size = 0;
769 strv_free(b->exec_argv);
770 free(b->exec_path);
771 b->exec_path = NULL;
772 b->exec_argv = NULL;
98178d39 773 b->server_id = SD_ID128_NULL;
6629161f
LP
774 free(b->kernel);
775 b->kernel = NULL;
a7893c6b
LP
776 free(b->machine);
777 b->machine = NULL;
2fd9ae2e
LP
778}
779
780static int bus_parse_next_address(sd_bus *b) {
781 _cleanup_free_ char *guid = NULL;
782 const char *a;
783 int r;
784
785 assert(b);
786
787 if (!b->address)
788 return 0;
789 if (b->address[b->address_index] == 0)
790 return 0;
791
792 bus_reset_parsed_address(b);
793
794 a = b->address + b->address_index;
de1c301e 795
2fd9ae2e 796 while (*a != 0) {
de1c301e 797
2fd9ae2e
LP
798 if (*a == ';') {
799 a++;
800 continue;
de1c301e
LP
801 }
802
2fd9ae2e
LP
803 if (startswith(a, "unix:")) {
804 a += 5;
de1c301e 805
2fd9ae2e 806 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
807 if (r < 0)
808 return r;
2fd9ae2e 809 break;
de1c301e 810
2fd9ae2e 811 } else if (startswith(a, "tcp:")) {
de1c301e 812
2fd9ae2e
LP
813 a += 4;
814 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
815 if (r < 0)
816 return r;
de1c301e 817
2fd9ae2e
LP
818 break;
819
820 } else if (startswith(a, "unixexec:")) {
821
822 a += 9;
823 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
824 if (r < 0)
825 return r;
de1c301e 826
2fd9ae2e 827 break;
de1c301e 828
6629161f
LP
829 } else if (startswith(a, "kernel:")) {
830
831 a += 7;
832 r = parse_kernel_address(b, &a, &guid);
833 if (r < 0)
834 return r;
835
a7893c6b
LP
836 break;
837 } else if (startswith(a, "x-container:")) {
838
839 a += 12;
840 r = parse_container_address(b, &a, &guid);
841 if (r < 0)
842 return r;
843
6629161f 844 break;
de1c301e
LP
845 }
846
2fd9ae2e
LP
847 a = strchr(a, ';');
848 if (!a)
849 return 0;
de1c301e
LP
850 }
851
852 if (guid) {
98178d39 853 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
854 if (r < 0)
855 return r;
856 }
857
2fd9ae2e 858 b->address_index = a - b->address;
de1c301e
LP
859 return 1;
860}
861
a7e3212d 862static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
863 int r;
864
865 assert(b);
866
867 for (;;) {
e82c9509 868 sd_bus_close(b);
2fd9ae2e 869
a7893c6b 870 if (b->exec_path) {
a7e3212d 871
a7893c6b 872 r = bus_socket_exec(b);
2fd9ae2e
LP
873 if (r >= 0)
874 return r;
875
876 b->last_connect_error = -r;
a7893c6b 877 } else if (b->kernel) {
2fd9ae2e 878
a7893c6b
LP
879 r = bus_kernel_connect(b);
880 if (r >= 0)
881 return r;
2fd9ae2e 882
a7893c6b
LP
883 b->last_connect_error = -r;
884
885 } else if (b->machine) {
886
887 r = bus_container_connect(b);
2fd9ae2e
LP
888 if (r >= 0)
889 return r;
890
6629161f 891 b->last_connect_error = -r;
6629161f 892
a7893c6b
LP
893 } else if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
894
895 r = bus_socket_connect(b);
6629161f
LP
896 if (r >= 0)
897 return r;
898
2fd9ae2e
LP
899 b->last_connect_error = -r;
900 }
901
902 r = bus_parse_next_address(b);
903 if (r < 0)
904 return r;
905 if (r == 0)
906 return b->last_connect_error ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
907 }
908}
909
a7e3212d
LP
910int bus_next_address(sd_bus *b) {
911 assert(b);
912
913 bus_reset_parsed_address(b);
914 return bus_start_address(b);
915}
916
021a1e78 917static int bus_start_fd(sd_bus *b) {
6629161f 918 struct stat st;
021a1e78
LP
919 int r;
920
921 assert(b);
e82c9509
LP
922 assert(b->input_fd >= 0);
923 assert(b->output_fd >= 0);
021a1e78 924
e82c9509 925 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
926 if (r < 0)
927 return r;
928
e82c9509 929 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
930 if (r < 0)
931 return r;
932
e82c9509
LP
933 if (b->input_fd != b->output_fd) {
934 r = fd_nonblock(b->output_fd, true);
935 if (r < 0)
936 return r;
937
938 r = fd_cloexec(b->output_fd, true);
939 if (r < 0)
940 return r;
941 }
942
6629161f
LP
943 if (fstat(b->input_fd, &st) < 0)
944 return -errno;
945
946 if (S_ISCHR(b->input_fd))
947 return bus_kernel_take_fd(b);
948 else
949 return bus_socket_take_fd(b);
021a1e78
LP
950}
951
d9f644e2 952_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
953 int r;
954
d6888822
LP
955 assert_return(bus, -EINVAL);
956 assert_return(bus->state == BUS_UNSET, -EPERM);
957 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
958
959 bus->state = BUS_OPENING;
960
2181a7f5
LP
961 if (bus->is_server && bus->bus_client)
962 return -EINVAL;
963
e82c9509 964 if (bus->input_fd >= 0)
021a1e78 965 r = bus_start_fd(bus);
a7893c6b 966 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel || bus->machine)
a7e3212d 967 r = bus_start_address(bus);
021a1e78
LP
968 else
969 return -EINVAL;
970
971 if (r < 0)
972 return r;
973
974 return bus_send_hello(bus);
975}
976
d9f644e2 977_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
978 const char *e;
979 sd_bus *b;
980 int r;
981
d6888822 982 assert_return(ret, -EINVAL);
de1c301e 983
021a1e78
LP
984 r = sd_bus_new(&b);
985 if (r < 0)
986 return r;
987
6c03089c 988 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
de1c301e 989 if (e) {
021a1e78 990 r = sd_bus_set_address(b, e);
de1c301e 991 if (r < 0)
021a1e78 992 goto fail;
89ffcd2a 993 } else {
89ffcd2a
LP
994 b->sockaddr.un.sun_family = AF_UNIX;
995 strncpy(b->sockaddr.un.sun_path, "/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
996 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/dbus/system_bus_socket") - 1;
89ffcd2a 997 }
de1c301e 998
94bbf1ba 999 b->bus_client = true;
021a1e78
LP
1000
1001 r = sd_bus_start(b);
1002 if (r < 0)
1003 goto fail;
de1c301e
LP
1004
1005 *ret = b;
1006 return 0;
021a1e78
LP
1007
1008fail:
1009 bus_free(b);
1010 return r;
de1c301e
LP
1011}
1012
d9f644e2 1013_public_ int sd_bus_open_user(sd_bus **ret) {
de1c301e
LP
1014 const char *e;
1015 sd_bus *b;
1016 size_t l;
1017 int r;
1018
d6888822 1019 assert_return(ret, -EINVAL);
de1c301e 1020
021a1e78
LP
1021 r = sd_bus_new(&b);
1022 if (r < 0)
1023 return r;
1024
6c03089c 1025 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
de1c301e 1026 if (e) {
021a1e78 1027 r = sd_bus_set_address(b, e);
de1c301e 1028 if (r < 0)
021a1e78 1029 goto fail;
89ffcd2a 1030 } else {
6c03089c 1031 e = secure_getenv("XDG_RUNTIME_DIR");
021a1e78
LP
1032 if (!e) {
1033 r = -ENOENT;
1034 goto fail;
1035 }
de1c301e 1036
89ffcd2a 1037 l = strlen(e);
021a1e78
LP
1038 if (l + 4 > sizeof(b->sockaddr.un.sun_path)) {
1039 r = -E2BIG;
1040 goto fail;
1041 }
de1c301e 1042
89ffcd2a
LP
1043 b->sockaddr.un.sun_family = AF_UNIX;
1044 memcpy(mempcpy(b->sockaddr.un.sun_path, e, l), "/bus", 4);
1045 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l + 4;
de1c301e
LP
1046 }
1047
94bbf1ba 1048 b->bus_client = true;
de1c301e 1049
021a1e78 1050 r = sd_bus_start(b);
2571ead1
LP
1051 if (r < 0)
1052 goto fail;
de1c301e
LP
1053
1054 *ret = b;
1055 return 0;
2571ead1
LP
1056
1057fail:
021a1e78 1058 bus_free(b);
2571ead1 1059 return r;
de1c301e
LP
1060}
1061
d9f644e2 1062_public_ int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
0f8bd8de
LP
1063 _cleanup_free_ char *e = NULL;
1064 char *p = NULL;
1065 sd_bus *bus;
1066 int r;
1067
1068 assert_return(host, -EINVAL);
1069 assert_return(ret, -EINVAL);
1070
1071 e = bus_address_escape(host);
1072 if (!e)
1073 return -ENOMEM;
1074
1075 p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
1076 if (!p)
1077 return -ENOMEM;
a7893c6b
LP
1078
1079 r = sd_bus_new(&bus);
1080 if (r < 0) {
1081 free(p);
1082 return r;
1083 }
1084
1085 bus->address = p;
1086 bus->bus_client = true;
1087
1088 r = sd_bus_start(bus);
1089 if (r < 0) {
1090 bus_free(bus);
1091 return r;
1092 }
1093
1094 *ret = bus;
1095 return 0;
1096}
1097
d9f644e2 1098_public_ int sd_bus_open_system_container(const char *machine, sd_bus **ret) {
a7893c6b
LP
1099 _cleanup_free_ char *e = NULL;
1100 sd_bus *bus;
1101 char *p;
1102 int r;
1103
1104 assert_return(machine, -EINVAL);
1105 assert_return(ret, -EINVAL);
1106
1107 e = bus_address_escape(machine);
1108 if (!e)
1109 return -ENOMEM;
1110
1111 p = strjoin("x-container:machine=", e, NULL);
1112 if (!p)
1113 return -ENOMEM;
0f8bd8de
LP
1114
1115 r = sd_bus_new(&bus);
1116 if (r < 0) {
1117 free(p);
1118 return r;
1119 }
1120
1121 bus->address = p;
1122 bus->bus_client = true;
1123
1124 r = sd_bus_start(bus);
1125 if (r < 0) {
1126 bus_free(bus);
1127 return r;
1128 }
1129
1130 *ret = bus;
1131 return 0;
1132}
1133
d9f644e2 1134_public_ void sd_bus_close(sd_bus *bus) {
0e586eae 1135
de1c301e
LP
1136 if (!bus)
1137 return;
d5a2b9a6
LP
1138 if (bus->state == BUS_CLOSED)
1139 return;
1140 if (bus_pid_changed(bus))
f54514f3
LP
1141 return;
1142
1143 bus->state = BUS_CLOSED;
e82c9509 1144
40ca29a1
LP
1145 sd_bus_detach_event(bus);
1146
0e586eae
LP
1147 /* Drop all queued messages so that they drop references to
1148 * the bus object and the bus may be freed */
1149 bus_reset_queues(bus);
1150
f54514f3
LP
1151 if (!bus->is_kernel)
1152 bus_close_fds(bus);
1153
1154 /* We'll leave the fd open in case this is a kernel bus, since
1155 * there might still be memblocks around that reference this
1156 * bus, and they might need to invoke the
1157 * KDBUS_CMD_MSG_RELEASE ioctl on the fd when they are
1158 * freed. */
de1c301e
LP
1159}
1160
718db961
LP
1161static void bus_enter_closing(sd_bus *bus) {
1162 assert(bus);
1163
1164 if (bus->state != BUS_OPENING &&
1165 bus->state != BUS_AUTHENTICATING &&
1166 bus->state != BUS_HELLO &&
1167 bus->state != BUS_RUNNING)
1168 return;
1169
1170 bus->state = BUS_CLOSING;
1171}
1172
d9f644e2 1173_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
9d6c7c82 1174 assert_return(bus, NULL);
de1c301e 1175
e4ee6e5c 1176 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1177
de1c301e
LP
1178 return bus;
1179}
1180
d9f644e2 1181_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
9d6c7c82 1182 assert_return(bus, NULL);
de1c301e 1183
e4ee6e5c 1184 if (REFCNT_DEC(bus->n_ref) <= 0)
de1c301e
LP
1185 bus_free(bus);
1186
1187 return NULL;
1188}
1189
d9f644e2 1190_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1191
1192 assert_return(bus, -EINVAL);
1193 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1194
f54514f3 1195 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1196}
1197
d9f644e2 1198_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1199 int r;
1200
d6888822
LP
1201 assert_return(bus, -EINVAL);
1202 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1203 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1204
d728d708 1205 if (type == SD_BUS_TYPE_UNIX_FD) {
264ad849 1206 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
021a1e78
LP
1207 return 0;
1208
20902f3e 1209 r = bus_ensure_running(bus);
d728d708
LP
1210 if (r < 0)
1211 return r;
de1c301e 1212
d728d708
LP
1213 return bus->can_fds;
1214 }
1215
1216 return bus_type_is_valid(type);
de1c301e
LP
1217}
1218
d9f644e2 1219_public_ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *server_id) {
d728d708 1220 int r;
de1c301e 1221
d6888822
LP
1222 assert_return(bus, -EINVAL);
1223 assert_return(server_id, -EINVAL);
1224 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1225
20902f3e 1226 r = bus_ensure_running(bus);
d728d708
LP
1227 if (r < 0)
1228 return r;
de1c301e 1229
98178d39 1230 *server_id = bus->server_id;
d728d708 1231 return 0;
de1c301e
LP
1232}
1233
7adc46fc
LP
1234static int bus_seal_message(sd_bus *b, sd_bus_message *m) {
1235 assert(b);
de1c301e
LP
1236 assert(m);
1237
89ffcd2a
LP
1238 if (m->header->version > b->message_version)
1239 return -EPERM;
1240
aea93deb
LP
1241 if (m->sealed) {
1242 /* If we copy the same message to multiple
1243 * destinations, avoid using the same serial
1244 * numbers. */
1245 b->serial = MAX(b->serial, BUS_MESSAGE_SERIAL(m));
de1c301e 1246 return 0;
aea93deb 1247 }
de1c301e 1248
9a17484d 1249 return bus_message_seal(m, ++b->serial);
de1c301e
LP
1250}
1251
7adc46fc
LP
1252int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1253 assert(b);
1254 assert(m);
1255
1256 if (m->header->version > b->message_version)
1257 return -EPERM;
1258
1259 /* The bus specification says the serial number cannot be 0,
1260 * hence let's fill something in for synthetic messages. Since
1261 * synthetic messages might have a fake sender and we don't
1262 * want to interfere with the real sender's serial numbers we
1263 * pick a fixed, artifical one. We use (uint32_t) -1 rather
1264 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1265 * even though kdbus can do 64bit. */
1266
1267 return bus_message_seal(m, 0xFFFFFFFFULL);
1268}
1269
718db961
LP
1270static int bus_write_message(sd_bus *bus, sd_bus_message *message, size_t *idx) {
1271 int r;
1272
1273 assert(bus);
1274 assert(message);
1275
1276 if (bus->is_kernel)
1277 r = bus_kernel_write_message(bus, message);
1278 else
1279 r = bus_socket_write_message(bus, message, idx);
1280
1281 return r;
1282}
1283
de1c301e 1284static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1285 int r, ret = 0;
de1c301e
LP
1286
1287 assert(bus);
89ffcd2a 1288 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1289
de1c301e
LP
1290 while (bus->wqueue_size > 0) {
1291
718db961
LP
1292 r = bus_write_message(bus, bus->wqueue[0], &bus->windex);
1293 if (r < 0)
de1c301e 1294 return r;
718db961 1295 else if (r == 0)
e3017af9
LP
1296 /* Didn't do anything this time */
1297 return ret;
6629161f 1298 else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1299 /* Fully written. Let's drop the entry from
1300 * the queue.
1301 *
1302 * This isn't particularly optimized, but
1303 * well, this is supposed to be our worst-case
1304 * buffer only, and the socket buffer is
1305 * supposed to be our primary buffer, and if
1306 * it got full, then all bets are off
1307 * anyway. */
1308
1309 sd_bus_message_unref(bus->wqueue[0]);
1310 bus->wqueue_size --;
1311 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1312 bus->windex = 0;
1313
e3017af9 1314 ret = 1;
de1c301e
LP
1315 }
1316 }
1317
e3017af9 1318 return ret;
de1c301e
LP
1319}
1320
7d22c717
LP
1321static int bus_read_message(sd_bus *bus) {
1322 assert(bus);
1323
1324 if (bus->is_kernel)
1325 return bus_kernel_read_message(bus);
1326 else
1327 return bus_socket_read_message(bus);
1328}
1329
7adc46fc 1330int bus_rqueue_make_room(sd_bus *bus) {
7d22c717
LP
1331 sd_bus_message **q;
1332 unsigned x;
1333
7adc46fc 1334 x = bus->rqueue_size + 1;
7d22c717
LP
1335
1336 if (bus->rqueue_allocated >= x)
1337 return 0;
1338
1339 if (x > BUS_RQUEUE_MAX)
1340 return -ENOBUFS;
1341
1342 q = realloc(bus->rqueue, x * sizeof(sd_bus_message*));
1343 if (!q)
1344 return -ENOMEM;
1345
1346 bus->rqueue = q;
1347 bus->rqueue_allocated = x;
1348
1349 return 0;
1350}
1351
de1c301e 1352static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
e3017af9 1353 int r, ret = 0;
de1c301e
LP
1354
1355 assert(bus);
1356 assert(m);
89ffcd2a 1357 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1358
7d22c717
LP
1359 for (;;) {
1360 if (bus->rqueue_size > 0) {
1361 /* Dispatch a queued message */
de1c301e 1362
7d22c717
LP
1363 *m = bus->rqueue[0];
1364 bus->rqueue_size --;
1365 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1366 return 1;
1367 }
de1c301e 1368
7d22c717
LP
1369 /* Try to read a new message */
1370 r = bus_read_message(bus);
718db961 1371 if (r < 0)
e3017af9 1372 return r;
e3017af9
LP
1373 if (r == 0)
1374 return ret;
de1c301e 1375
2e8d788c 1376 ret = 1;
7d22c717 1377 }
de1c301e
LP
1378}
1379
d9f644e2 1380_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
de1c301e
LP
1381 int r;
1382
d6888822
LP
1383 assert_return(bus, -EINVAL);
1384 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1385 assert_return(m, -EINVAL);
1386 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
1387
1388 if (m->n_fds > 0) {
1389 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1390 if (r < 0)
1391 return r;
1392 if (r == 0)
1393 return -ENOTSUP;
1394 }
de1c301e 1395
29f6aadd
LP
1396 /* If the serial number isn't kept, then we know that no reply
1397 * is expected */
1398 if (!serial && !m->sealed)
1399 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1400
de1c301e
LP
1401 r = bus_seal_message(bus, m);
1402 if (r < 0)
1403 return r;
1404
5407f2de
LP
1405 /* If this is a reply and no reply was requested, then let's
1406 * suppress this, if we can */
1407 if (m->dont_send && !serial)
7a37d625 1408 return 1;
5407f2de 1409
89ffcd2a 1410 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1411 size_t idx = 0;
1412
718db961
LP
1413 r = bus_write_message(bus, m, &idx);
1414 if (r < 0)
de1c301e 1415 return r;
718db961 1416 else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1417 /* Wasn't fully written. So let's remember how
1418 * much was written. Note that the first entry
1419 * of the wqueue array is always allocated so
1420 * that we always can remember how much was
1421 * written. */
1422 bus->wqueue[0] = sd_bus_message_ref(m);
1423 bus->wqueue_size = 1;
1424 bus->windex = idx;
1425 }
1426 } else {
1427 sd_bus_message **q;
1428
1429 /* Just append it to the queue. */
1430
25220239 1431 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1432 return -ENOBUFS;
1433
1434 q = realloc(bus->wqueue, sizeof(sd_bus_message*) * (bus->wqueue_size + 1));
1435 if (!q)
1436 return -ENOMEM;
1437
1438 bus->wqueue = q;
1439 q[bus->wqueue_size ++] = sd_bus_message_ref(m);
1440 }
1441
1442 if (serial)
1443 *serial = BUS_MESSAGE_SERIAL(m);
1444
7a37d625 1445 return 1;
de1c301e
LP
1446}
1447
911121a7
LP
1448_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *serial) {
1449 int r;
1450
1451 assert_return(bus, -EINVAL);
1452 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1453 assert_return(m, -EINVAL);
1454 assert_return(!bus_pid_changed(bus), -ECHILD);
1455
1456 if (!streq_ptr(m->destination, destination)) {
1457
1458 if (!destination)
1459 return -EEXIST;
1460
1461 r = sd_bus_message_set_destination(m, destination);
1462 if (r < 0)
1463 return r;
1464 }
1465
1466 return sd_bus_send(bus, m, serial);
1467}
1468
de1c301e
LP
1469static usec_t calc_elapse(uint64_t usec) {
1470 if (usec == (uint64_t) -1)
1471 return 0;
1472
1473 if (usec == 0)
e3017af9 1474 usec = BUS_DEFAULT_TIMEOUT;
de1c301e
LP
1475
1476 return now(CLOCK_MONOTONIC) + usec;
1477}
1478
e3017af9
LP
1479static int timeout_compare(const void *a, const void *b) {
1480 const struct reply_callback *x = a, *y = b;
1481
1482 if (x->timeout != 0 && y->timeout == 0)
1483 return -1;
1484
1485 if (x->timeout == 0 && y->timeout != 0)
1486 return 1;
1487
1488 if (x->timeout < y->timeout)
1489 return -1;
1490
1491 if (x->timeout > y->timeout)
1492 return 1;
1493
1494 return 0;
1495}
1496
c49b30a2 1497_public_ int sd_bus_call_async(
de1c301e
LP
1498 sd_bus *bus,
1499 sd_bus_message *m,
52f3ba91 1500 sd_bus_message_handler_t callback,
de1c301e
LP
1501 void *userdata,
1502 uint64_t usec,
1503 uint64_t *serial) {
1504
1505 struct reply_callback *c;
1506 int r;
1507
d6888822
LP
1508 assert_return(bus, -EINVAL);
1509 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1510 assert_return(m, -EINVAL);
40ca29a1 1511 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
d6888822
LP
1512 assert_return(!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1513 assert_return(callback, -EINVAL);
1514 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a
LP
1515
1516 r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func);
1517 if (r < 0)
1518 return r;
de1c301e 1519
e3017af9
LP
1520 if (usec != (uint64_t) -1) {
1521 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1522 if (r < 0)
1523 return r;
1524 }
1525
de1c301e
LP
1526 r = bus_seal_message(bus, m);
1527 if (r < 0)
1528 return r;
1529
eba8617e 1530 c = new0(struct reply_callback, 1);
de1c301e
LP
1531 if (!c)
1532 return -ENOMEM;
1533
1534 c->callback = callback;
1535 c->userdata = userdata;
1536 c->serial = BUS_MESSAGE_SERIAL(m);
1537 c->timeout = calc_elapse(usec);
1538
1539 r = hashmap_put(bus->reply_callbacks, &c->serial, c);
1540 if (r < 0) {
1541 free(c);
1542 return r;
1543 }
1544
e3017af9
LP
1545 if (c->timeout != 0) {
1546 r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1547 if (r < 0) {
1548 c->timeout = 0;
c49b30a2 1549 sd_bus_call_async_cancel(bus, c->serial);
e3017af9
LP
1550 return r;
1551 }
1552 }
1553
de1c301e
LP
1554 r = sd_bus_send(bus, m, serial);
1555 if (r < 0) {
c49b30a2 1556 sd_bus_call_async_cancel(bus, c->serial);
de1c301e
LP
1557 return r;
1558 }
1559
1560 return r;
1561}
1562
c49b30a2 1563_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t serial) {
e3017af9 1564 struct reply_callback *c;
de1c301e 1565
d6888822
LP
1566 assert_return(bus, -EINVAL);
1567 assert_return(serial != 0, -EINVAL);
1568 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1569
1570 c = hashmap_remove(bus->reply_callbacks, &serial);
1571 if (!c)
1572 return 0;
1573
e3017af9
LP
1574 if (c->timeout != 0)
1575 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1576
de1c301e
LP
1577 free(c);
1578 return 1;
1579}
1580
20902f3e 1581int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1582 int r;
1583
1584 assert(bus);
1585
718db961 1586 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED || bus->state == BUS_CLOSING)
021a1e78 1587 return -ENOTCONN;
d728d708
LP
1588 if (bus->state == BUS_RUNNING)
1589 return 1;
89ffcd2a
LP
1590
1591 for (;;) {
1592 r = sd_bus_process(bus, NULL);
1593 if (r < 0)
1594 return r;
d728d708
LP
1595 if (bus->state == BUS_RUNNING)
1596 return 1;
e3017af9
LP
1597 if (r > 0)
1598 continue;
89ffcd2a
LP
1599
1600 r = sd_bus_wait(bus, (uint64_t) -1);
1601 if (r < 0)
1602 return r;
1603 }
1604}
1605
c49b30a2 1606_public_ int sd_bus_call(
de1c301e
LP
1607 sd_bus *bus,
1608 sd_bus_message *m,
1609 uint64_t usec,
1610 sd_bus_error *error,
1611 sd_bus_message **reply) {
1612
de1c301e
LP
1613 usec_t timeout;
1614 uint64_t serial;
7d22c717
LP
1615 unsigned i;
1616 int r;
de1c301e 1617
d6888822
LP
1618 assert_return(bus, -EINVAL);
1619 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1620 assert_return(m, -EINVAL);
40ca29a1 1621 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
d6888822
LP
1622 assert_return(!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1623 assert_return(!bus_error_is_dirty(error), -EINVAL);
1624 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a 1625
20902f3e 1626 r = bus_ensure_running(bus);
89ffcd2a
LP
1627 if (r < 0)
1628 return r;
de1c301e
LP
1629
1630 r = sd_bus_send(bus, m, &serial);
1631 if (r < 0)
1632 return r;
1633
1634 timeout = calc_elapse(usec);
7d22c717 1635 i = bus->rqueue_size;
de1c301e
LP
1636
1637 for (;;) {
1638 usec_t left;
de1c301e 1639
7d22c717 1640 r = bus_read_message(bus);
de1c301e
LP
1641 if (r < 0)
1642 return r;
718db961 1643
7d22c717
LP
1644 while (i < bus->rqueue_size) {
1645 sd_bus_message *incoming = NULL;
1646
1647 incoming = bus->rqueue[i];
89ffcd2a 1648
de1c301e
LP
1649 if (incoming->reply_serial == serial) {
1650 /* Found a match! */
1651
7d22c717
LP
1652 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1653 bus->rqueue_size--;
1654
40ca29a1 1655 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0
LP
1656
1657 if (reply)
1658 *reply = incoming;
1659 else
1660 sd_bus_message_unref(incoming);
1661
7a37d625 1662 return 1;
de1c301e
LP
1663 }
1664
40ca29a1 1665 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
de1c301e
LP
1666 int k;
1667
1668 r = sd_bus_error_copy(error, &incoming->error);
1669 if (r < 0) {
1670 sd_bus_message_unref(incoming);
1671 return r;
1672 }
1673
40ca29a1 1674 k = sd_bus_error_get_errno(&incoming->error);
de1c301e 1675 sd_bus_message_unref(incoming);
40ca29a1 1676 return -k;
de1c301e
LP
1677 }
1678
1679 sd_bus_message_unref(incoming);
1680 return -EIO;
a8a07f89
LP
1681
1682 } else if (incoming->header->serial == serial &&
1683 bus->unique_name &&
1684 incoming->sender &&
1685 streq(bus->unique_name, incoming->sender)) {
1686
7d22c717
LP
1687 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1688 bus->rqueue_size--;
1689
a8a07f89
LP
1690 /* Our own message? Somebody is trying
1691 * to send its own client a message,
1692 * let's not dead-lock, let's fail
1693 * immediately. */
1694
1695 sd_bus_message_unref(incoming);
1696 return -ELOOP;
de1c301e
LP
1697 }
1698
de1c301e 1699 /* Try to read more, right-away */
7d22c717 1700 i++;
de1c301e 1701 }
7d22c717
LP
1702
1703 if (r > 0)
e3017af9 1704 continue;
de1c301e
LP
1705
1706 if (timeout > 0) {
1707 usec_t n;
1708
1709 n = now(CLOCK_MONOTONIC);
1710 if (n >= timeout)
1711 return -ETIMEDOUT;
1712
1713 left = timeout - n;
1714 } else
1715 left = (uint64_t) -1;
1716
e3017af9 1717 r = bus_poll(bus, true, left);
de1c301e
LP
1718 if (r < 0)
1719 return r;
1720
1721 r = dispatch_wqueue(bus);
1722 if (r < 0)
1723 return r;
1724 }
1725}
1726
d9f644e2 1727_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
1728
1729 assert_return(bus, -EINVAL);
d6888822
LP
1730 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1731 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1732
e82c9509 1733 return bus->input_fd;
de1c301e
LP
1734}
1735
d9f644e2 1736_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
1737 int flags = 0;
1738
d6888822 1739 assert_return(bus, -EINVAL);
718db961 1740 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 1741 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1742
1743 if (bus->state == BUS_OPENING)
1744 flags |= POLLOUT;
89ffcd2a
LP
1745 else if (bus->state == BUS_AUTHENTICATING) {
1746
2181a7f5 1747 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
1748 flags |= POLLOUT;
1749
1750 flags |= POLLIN;
1751
1752 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
1753 if (bus->rqueue_size <= 0)
1754 flags |= POLLIN;
1755 if (bus->wqueue_size > 0)
1756 flags |= POLLOUT;
1757 }
1758
1759 return flags;
1760}
1761
d9f644e2 1762_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
1763 struct reply_callback *c;
1764
d6888822
LP
1765 assert_return(bus, -EINVAL);
1766 assert_return(timeout_usec, -EINVAL);
718db961 1767 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 1768 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1769
718db961
LP
1770 if (bus->state == BUS_CLOSING) {
1771 *timeout_usec = 0;
1772 return 1;
1773 }
1774
e3017af9
LP
1775 if (bus->state == BUS_AUTHENTICATING) {
1776 *timeout_usec = bus->auth_timeout;
1777 return 1;
1778 }
1779
adee69fa
LP
1780 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
1781 *timeout_usec = (uint64_t) -1;
e3017af9 1782 return 0;
adee69fa 1783 }
e3017af9 1784
8efd6381
LP
1785 if (bus->rqueue_size > 0) {
1786 *timeout_usec = 0;
1787 return 1;
1788 }
1789
e3017af9 1790 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
1791 if (!c) {
1792 *timeout_usec = (uint64_t) -1;
e3017af9 1793 return 0;
adee69fa 1794 }
e3017af9
LP
1795
1796 *timeout_usec = c->timeout;
1797 return 1;
1798}
1799
1800static int process_timeout(sd_bus *bus) {
ebcf1f97 1801 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
eb01ba5d 1802 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9
LP
1803 struct reply_callback *c;
1804 usec_t n;
1805 int r;
1806
1807 assert(bus);
1808
1809 c = prioq_peek(bus->reply_callbacks_prioq);
1810 if (!c)
1811 return 0;
1812
1813 n = now(CLOCK_MONOTONIC);
1814 if (c->timeout > n)
1815 return 0;
1816
eb01ba5d
LP
1817 r = bus_message_new_synthetic_error(
1818 bus,
1819 c->serial,
14c24659 1820 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
1821 &m);
1822 if (r < 0)
1823 return r;
1824
34a2c9e8
LP
1825 m->sender = "org.freedesktop.DBus";
1826
7adc46fc 1827 r = bus_seal_synthetic_message(bus, m);
718db961
LP
1828 if (r < 0)
1829 return r;
1830
e3017af9
LP
1831 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
1832 hashmap_remove(bus->reply_callbacks, &c->serial);
1833
718db961
LP
1834 bus->current = m;
1835 bus->iteration_counter ++;
1836
ebcf1f97
LP
1837 r = c->callback(bus, m, c->userdata, &error_buffer);
1838 r = bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
1839 free(c);
1840
718db961
LP
1841 bus->current = NULL;
1842
ebcf1f97 1843 return r;
e3017af9
LP
1844}
1845
9d373862
LP
1846static int process_hello(sd_bus *bus, sd_bus_message *m) {
1847 assert(bus);
1848 assert(m);
1849
1850 if (bus->state != BUS_HELLO)
1851 return 0;
1852
1853 /* Let's make sure the first message on the bus is the HELLO
1854 * reply. But note that we don't actually parse the message
2181a7f5
LP
1855 * here (we leave that to the usual handling), we just verify
1856 * we don't let any earlier msg through. */
9d373862 1857
40ca29a1
LP
1858 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1859 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
1860 return -EIO;
1861
1862 if (m->reply_serial != bus->hello_serial)
1863 return -EIO;
1864
1865 return 0;
1866}
1867
a652755d 1868static int process_reply(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 1869 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
1870 struct reply_callback *c;
1871 int r;
1872
1873 assert(bus);
1874 assert(m);
1875
40ca29a1
LP
1876 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1877 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
1878 return 0;
1879
1880 c = hashmap_remove(bus->reply_callbacks, &m->reply_serial);
1881 if (!c)
1882 return 0;
1883
1884 if (c->timeout != 0)
1885 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1886
88fe224c
LP
1887 r = sd_bus_message_rewind(m, true);
1888 if (r < 0)
1889 return r;
1890
ebcf1f97
LP
1891 r = c->callback(bus, m, c->userdata, &error_buffer);
1892 r = bus_maybe_reply_error(m, r, &error_buffer);
a652755d
LP
1893 free(c);
1894
ebcf1f97 1895 return r;
a652755d
LP
1896}
1897
1898static int process_filter(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 1899 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
1900 struct filter_callback *l;
1901 int r;
1902
392d5b37
LP
1903 assert(bus);
1904 assert(m);
1905
7286037f
LP
1906 do {
1907 bus->filter_callbacks_modified = false;
1908
1909 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1910
1911 if (bus->filter_callbacks_modified)
1912 break;
1913
1914 /* Don't run this more than once per iteration */
1915 if (l->last_iteration == bus->iteration_counter)
1916 continue;
1917
1918 l->last_iteration = bus->iteration_counter;
1919
88fe224c
LP
1920 r = sd_bus_message_rewind(m, true);
1921 if (r < 0)
1922 return r;
1923
969987ea 1924 r = l->callback(bus, m, l->userdata, &error_buffer);
ebcf1f97 1925 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
1926 if (r != 0)
1927 return r;
1928
1929 }
1930
1931 } while (bus->filter_callbacks_modified);
a652755d
LP
1932
1933 return 0;
1934}
1935
392d5b37 1936static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
1937 int r;
1938
392d5b37
LP
1939 assert(bus);
1940 assert(m);
1941
7286037f
LP
1942 do {
1943 bus->match_callbacks_modified = false;
1944
eb01ba5d 1945 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
1946 if (r != 0)
1947 return r;
1948
1949 } while (bus->match_callbacks_modified);
1950
1951 return 0;
392d5b37
LP
1952}
1953
b9bf7e2b
LP
1954static int process_builtin(sd_bus *bus, sd_bus_message *m) {
1955 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1956 int r;
1957
1958 assert(bus);
1959 assert(m);
1960
40ca29a1 1961 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
1962 return 0;
1963
1964 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
1965 return 0;
1966
1967 if (m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
1968 return 1;
1969
1970 if (streq_ptr(m->member, "Ping"))
df2d202e 1971 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
1972 else if (streq_ptr(m->member, "GetMachineId")) {
1973 sd_id128_t id;
1974 char sid[33];
1975
1976 r = sd_id128_get_machine(&id);
1977 if (r < 0)
1978 return r;
1979
df2d202e 1980 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
1981 if (r < 0)
1982 return r;
1983
1984 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
1985 } else {
29ddb38f 1986 r = sd_bus_message_new_method_errorf(
df2d202e 1987 m, &reply,
40ca29a1 1988 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 1989 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
1990 }
1991
1992 if (r < 0)
1993 return r;
1994
1995 r = sd_bus_send(bus, reply, NULL);
1996 if (r < 0)
1997 return r;
1998
1999 return 1;
2000}
2001
992c052c 2002static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2003 int r;
2004
2005 assert(bus);
992c052c 2006 assert(m);
e3017af9 2007
affff0b6 2008 bus->current = m;
992c052c 2009 bus->iteration_counter++;
e3017af9 2010
40ca29a1
LP
2011 log_debug("Got message sender=%s object=%s interface=%s member=%s",
2012 strna(sd_bus_message_get_sender(m)),
2013 strna(sd_bus_message_get_path(m)),
2014 strna(sd_bus_message_get_interface(m)),
2015 strna(sd_bus_message_get_member(m)));
2016
992c052c
LP
2017 r = process_hello(bus, m);
2018 if (r != 0)
affff0b6 2019 goto finish;
a652755d 2020
992c052c
LP
2021 r = process_reply(bus, m);
2022 if (r != 0)
affff0b6 2023 goto finish;
e3017af9 2024
992c052c
LP
2025 r = process_filter(bus, m);
2026 if (r != 0)
affff0b6 2027 goto finish;
a652755d 2028
992c052c
LP
2029 r = process_match(bus, m);
2030 if (r != 0)
affff0b6 2031 goto finish;
a652755d 2032
992c052c
LP
2033 r = process_builtin(bus, m);
2034 if (r != 0)
affff0b6
LP
2035 goto finish;
2036
2037 r = bus_process_object(bus, m);
a652755d 2038
affff0b6
LP
2039finish:
2040 bus->current = NULL;
2041 return r;
29ddb38f 2042}
88fe224c 2043
992c052c
LP
2044static int process_running(sd_bus *bus, sd_bus_message **ret) {
2045 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 2046 int r;
a652755d 2047
29ddb38f 2048 assert(bus);
992c052c 2049 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 2050
992c052c
LP
2051 r = process_timeout(bus);
2052 if (r != 0)
2053 goto null_message;
7286037f 2054
992c052c
LP
2055 r = dispatch_wqueue(bus);
2056 if (r != 0)
2057 goto null_message;
7286037f 2058
992c052c
LP
2059 r = dispatch_rqueue(bus, &m);
2060 if (r < 0)
2061 return r;
2062 if (!m)
2063 goto null_message;
7286037f 2064
992c052c
LP
2065 r = process_message(bus, m);
2066 if (r != 0)
2067 goto null_message;
7286037f 2068
992c052c
LP
2069 if (ret) {
2070 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2071 if (r < 0)
2072 return r;
e3017af9 2073
992c052c
LP
2074 *ret = m;
2075 m = NULL;
2076 return 1;
2077 }
a652755d 2078
40ca29a1 2079 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2080
992c052c 2081 r = sd_bus_reply_method_errorf(
df2d202e 2082 m,
40ca29a1 2083 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2084 "Unknown object '%s'.", m->path);
29ddb38f
LP
2085 if (r < 0)
2086 return r;
2087 }
e3017af9 2088
992c052c 2089 return 1;
0a72c2bd 2090
992c052c
LP
2091null_message:
2092 if (r >= 0 && ret)
2093 *ret = NULL;
0a72c2bd 2094
992c052c 2095 return r;
29ddb38f 2096}
0a72c2bd 2097
718db961
LP
2098static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2099 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2100 struct reply_callback *c;
2101 int r;
2102
2103 assert(bus);
2104 assert(bus->state == BUS_CLOSING);
2105
2106 c = hashmap_first(bus->reply_callbacks);
2107 if (c) {
ebcf1f97
LP
2108 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2109
718db961
LP
2110 /* First, fail all outstanding method calls */
2111 r = bus_message_new_synthetic_error(
2112 bus,
2113 c->serial,
14c24659 2114 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
718db961
LP
2115 &m);
2116 if (r < 0)
2117 return r;
2118
7adc46fc 2119 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2120 if (r < 0)
2121 return r;
2122
2123 if (c->timeout != 0)
2124 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2125
2126 hashmap_remove(bus->reply_callbacks, &c->serial);
2127
2128 bus->current = m;
2129 bus->iteration_counter++;
2130
ebcf1f97
LP
2131 r = c->callback(bus, m, c->userdata, &error_buffer);
2132 r = bus_maybe_reply_error(m, r, &error_buffer);
718db961
LP
2133 free(c);
2134
718db961
LP
2135 goto finish;
2136 }
2137
2138 /* Then, synthesize a Disconnected message */
2139 r = sd_bus_message_new_signal(
2140 bus,
2141 "/org/freedesktop/DBus/Local",
2142 "org.freedesktop.DBus.Local",
2143 "Disconnected",
2144 &m);
2145 if (r < 0)
2146 return r;
2147
34a2c9e8
LP
2148 m->sender = "org.freedesktop.DBus.Local";
2149
7adc46fc 2150 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2151 if (r < 0)
2152 return r;
2153
2154 sd_bus_close(bus);
2155
2156 bus->current = m;
2157 bus->iteration_counter++;
2158
2159 r = process_filter(bus, m);
2160 if (r != 0)
2161 goto finish;
2162
2163 r = process_match(bus, m);
2164 if (r != 0)
2165 goto finish;
2166
2167 if (ret) {
2168 *ret = m;
2169 m = NULL;
2170 }
2171
2172 r = 1;
2173
2174finish:
2175 bus->current = NULL;
2176 return r;
2177}
2178
d9f644e2 2179_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
8ce2afd6 2180 BUS_DONT_DESTROY(bus);
29ddb38f 2181 int r;
0a72c2bd 2182
992c052c
LP
2183 /* Returns 0 when we didn't do anything. This should cause the
2184 * caller to invoke sd_bus_wait() before returning the next
2185 * time. Returns > 0 when we did something, which possibly
2186 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2187
d6888822
LP
2188 assert_return(bus, -EINVAL);
2189 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2190
992c052c 2191 /* We don't allow recursively invoking sd_bus_process(). */
718db961 2192 assert_return(!bus->current, -EBUSY);
0a72c2bd 2193
992c052c 2194 switch (bus->state) {
0a72c2bd 2195
992c052c
LP
2196 case BUS_UNSET:
2197 case BUS_CLOSED:
2198 return -ENOTCONN;
0a72c2bd 2199
992c052c
LP
2200 case BUS_OPENING:
2201 r = bus_socket_process_opening(bus);
718db961
LP
2202 if (r == -ECONNRESET || r == -EPIPE) {
2203 bus_enter_closing(bus);
2204 r = 1;
2205 } else if (r < 0)
29ddb38f 2206 return r;
992c052c
LP
2207 if (ret)
2208 *ret = NULL;
a652755d
LP
2209 return r;
2210
992c052c 2211 case BUS_AUTHENTICATING:
992c052c 2212 r = bus_socket_process_authenticating(bus);
718db961
LP
2213 if (r == -ECONNRESET || r == -EPIPE) {
2214 bus_enter_closing(bus);
2215 r = 1;
2216 } else if (r < 0)
29ddb38f 2217 return r;
718db961 2218
992c052c
LP
2219 if (ret)
2220 *ret = NULL;
718db961 2221
992c052c 2222 return r;
a652755d 2223
992c052c
LP
2224 case BUS_RUNNING:
2225 case BUS_HELLO:
992c052c 2226 r = process_running(bus, ret);
718db961
LP
2227 if (r == -ECONNRESET || r == -EPIPE) {
2228 bus_enter_closing(bus);
2229 r = 1;
2230
2231 if (ret)
2232 *ret = NULL;
2233 }
43a43f50 2234
43a43f50 2235 return r;
718db961
LP
2236
2237 case BUS_CLOSING:
2238 return process_closing(bus, ret);
992c052c 2239 }
43a43f50 2240
992c052c 2241 assert_not_reached("Unknown state");
e3017af9
LP
2242}
2243
992c052c
LP
2244static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2245 struct pollfd p[2] = {};
2246 int r, e, n;
2247 struct timespec ts;
8efd6381 2248 usec_t m = (usec_t) -1;
adcdb374
LP
2249
2250 assert(bus);
718db961
LP
2251
2252 if (bus->state == BUS_CLOSING)
2253 return 1;
2254
d6888822 2255 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
adcdb374 2256
992c052c
LP
2257 e = sd_bus_get_events(bus);
2258 if (e < 0)
2259 return e;
adcdb374 2260
992c052c 2261 if (need_more)
8efd6381
LP
2262 /* The caller really needs some more data, he doesn't
2263 * care about what's already read, or any timeouts
2264 * except its own.*/
992c052c 2265 e |= POLLIN;
992c052c 2266 else {
8efd6381
LP
2267 usec_t until;
2268 /* The caller wants to process if there's something to
2269 * process, but doesn't care otherwise */
2270
2271 r = sd_bus_get_timeout(bus, &until);
2272 if (r < 0)
2273 return r;
2274 if (r > 0) {
2275 usec_t nw;
2276 nw = now(CLOCK_MONOTONIC);
2277 m = until > nw ? until - nw : 0;
2278 }
992c052c 2279 }
adcdb374 2280
992c052c
LP
2281 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2282 m = timeout_usec;
adcdb374 2283
992c052c
LP
2284 p[0].fd = bus->input_fd;
2285 if (bus->output_fd == bus->input_fd) {
2286 p[0].events = e;
2287 n = 1;
2288 } else {
2289 p[0].events = e & POLLIN;
2290 p[1].fd = bus->output_fd;
2291 p[1].events = e & POLLOUT;
2292 n = 2;
adcdb374
LP
2293 }
2294
992c052c 2295 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2296 if (r < 0)
992c052c 2297 return -errno;
adcdb374 2298
992c052c 2299 return r > 0 ? 1 : 0;
adcdb374
LP
2300}
2301
d9f644e2 2302_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2303
d6888822 2304 assert_return(bus, -EINVAL);
d6888822 2305 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2306
718db961
LP
2307 if (bus->state == BUS_CLOSING)
2308 return 0;
2309
2310 assert_return(BUS_IS_OPEN(bus->state) , -ENOTCONN);
2311
992c052c
LP
2312 if (bus->rqueue_size > 0)
2313 return 0;
9db76355 2314
992c052c
LP
2315 return bus_poll(bus, false, timeout_usec);
2316}
9db76355 2317
d9f644e2 2318_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2319 int r;
9db76355 2320
d6888822 2321 assert_return(bus, -EINVAL);
d6888822 2322 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2323
718db961
LP
2324 if (bus->state == BUS_CLOSING)
2325 return 0;
2326
2327 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2328
992c052c
LP
2329 r = bus_ensure_running(bus);
2330 if (r < 0)
2331 return r;
9db76355 2332
992c052c
LP
2333 if (bus->wqueue_size <= 0)
2334 return 0;
9db76355 2335
992c052c
LP
2336 for (;;) {
2337 r = dispatch_wqueue(bus);
9db76355
LP
2338 if (r < 0)
2339 return r;
2340
992c052c
LP
2341 if (bus->wqueue_size <= 0)
2342 return 0;
9db76355 2343
992c052c 2344 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2345 if (r < 0)
2346 return r;
9db76355 2347 }
9db76355
LP
2348}
2349
d9f644e2
ZJS
2350_public_ int sd_bus_add_filter(sd_bus *bus,
2351 sd_bus_message_handler_t callback,
2352 void *userdata) {
2353
992c052c 2354 struct filter_callback *f;
de1c301e 2355
d6888822
LP
2356 assert_return(bus, -EINVAL);
2357 assert_return(callback, -EINVAL);
2358 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2359
992c052c
LP
2360 f = new0(struct filter_callback, 1);
2361 if (!f)
29ddb38f 2362 return -ENOMEM;
992c052c
LP
2363 f->callback = callback;
2364 f->userdata = userdata;
29ddb38f 2365
992c052c 2366 bus->filter_callbacks_modified = true;
71fda00f 2367 LIST_PREPEND(callbacks, bus->filter_callbacks, f);
de1c301e
LP
2368 return 0;
2369}
a652755d 2370
d9f644e2
ZJS
2371_public_ int sd_bus_remove_filter(sd_bus *bus,
2372 sd_bus_message_handler_t callback,
2373 void *userdata) {
2374
992c052c 2375 struct filter_callback *f;
a652755d 2376
d6888822
LP
2377 assert_return(bus, -EINVAL);
2378 assert_return(callback, -EINVAL);
2379 assert_return(!bus_pid_changed(bus), -ECHILD);
a652755d 2380
992c052c
LP
2381 LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
2382 if (f->callback == callback && f->userdata == userdata) {
2383 bus->filter_callbacks_modified = true;
71fda00f 2384 LIST_REMOVE(callbacks, bus->filter_callbacks, f);
992c052c
LP
2385 free(f);
2386 return 1;
29ddb38f
LP
2387 }
2388 }
2389
992c052c 2390 return 0;
a652755d 2391}
392d5b37 2392
d9f644e2
ZJS
2393_public_ int sd_bus_add_match(sd_bus *bus,
2394 const char *match,
2395 sd_bus_message_handler_t callback,
2396 void *userdata) {
2397
992c052c
LP
2398 struct bus_match_component *components = NULL;
2399 unsigned n_components = 0;
2400 uint64_t cookie = 0;
2401 int r = 0;
392d5b37 2402
d6888822
LP
2403 assert_return(bus, -EINVAL);
2404 assert_return(match, -EINVAL);
2405 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2406
992c052c
LP
2407 r = bus_match_parse(match, &components, &n_components);
2408 if (r < 0)
2409 goto finish;
29ddb38f 2410
992c052c
LP
2411 if (bus->bus_client) {
2412 cookie = ++bus->match_cookie;
29ddb38f 2413
992c052c
LP
2414 r = bus_add_match_internal(bus, match, components, n_components, cookie);
2415 if (r < 0)
2416 goto finish;
392d5b37
LP
2417 }
2418
992c052c
LP
2419 bus->match_callbacks_modified = true;
2420 r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
29ddb38f 2421 if (r < 0) {
992c052c
LP
2422 if (bus->bus_client)
2423 bus_remove_match_internal(bus, match, cookie);
29ddb38f 2424 }
917b5dc7 2425
992c052c
LP
2426finish:
2427 bus_match_parse_free(components, n_components);
2428 return r;
917b5dc7
LP
2429}
2430
d9f644e2
ZJS
2431_public_ int sd_bus_remove_match(sd_bus *bus,
2432 const char *match,
2433 sd_bus_message_handler_t callback,
2434 void *userdata) {
2435
992c052c
LP
2436 struct bus_match_component *components = NULL;
2437 unsigned n_components = 0;
2438 int r = 0, q = 0;
2439 uint64_t cookie = 0;
917b5dc7 2440
d6888822
LP
2441 assert_return(bus, -EINVAL);
2442 assert_return(match, -EINVAL);
2443 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2444
992c052c 2445 r = bus_match_parse(match, &components, &n_components);
29ddb38f
LP
2446 if (r < 0)
2447 return r;
f10dda3b 2448
992c052c
LP
2449 bus->match_callbacks_modified = true;
2450 r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
f10dda3b 2451
992c052c
LP
2452 if (bus->bus_client)
2453 q = bus_remove_match_internal(bus, match, cookie);
f10dda3b 2454
992c052c 2455 bus_match_parse_free(components, n_components);
f10dda3b 2456
992c052c 2457 return r < 0 ? r : q;
f10dda3b
LP
2458}
2459
992c052c
LP
2460bool bus_pid_changed(sd_bus *bus) {
2461 assert(bus);
f10dda3b 2462
992c052c
LP
2463 /* We don't support people creating a bus connection and
2464 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 2465
992c052c 2466 return bus->original_pid != getpid();
d5a2b9a6 2467}
40ca29a1
LP
2468
2469static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 2470 sd_bus *bus = userdata;
40ca29a1
LP
2471 int r;
2472
2473 assert(bus);
2474
2475 r = sd_bus_process(bus, NULL);
2476 if (r < 0)
2477 return r;
2478
2479 return 1;
2480}
2481
2482static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 2483 sd_bus *bus = userdata;
40ca29a1
LP
2484 int r;
2485
2486 assert(bus);
2487
2488 r = sd_bus_process(bus, NULL);
2489 if (r < 0)
2490 return r;
2491
2492 return 1;
2493}
2494
2495static int prepare_callback(sd_event_source *s, void *userdata) {
2496 sd_bus *bus = userdata;
2497 int r, e;
2498 usec_t until;
2499
2500 assert(s);
2501 assert(bus);
2502
2503 e = sd_bus_get_events(bus);
2504 if (e < 0)
2505 return e;
2506
2507 if (bus->output_fd != bus->input_fd) {
2508
2509 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
2510 if (r < 0)
2511 return r;
2512
2513 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
2514 if (r < 0)
2515 return r;
2516 } else {
2517 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
2518 if (r < 0)
2519 return r;
2520 }
2521
2522 r = sd_bus_get_timeout(bus, &until);
2523 if (r < 0)
2524 return r;
2525 if (r > 0) {
2526 int j;
2527
2528 j = sd_event_source_set_time(bus->time_event_source, until);
2529 if (j < 0)
2530 return j;
2531 }
2532
2533 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
2534 if (r < 0)
2535 return r;
2536
2537 return 1;
2538}
2539
abc5fe72
LP
2540static int quit_callback(sd_event_source *event, void *userdata) {
2541 sd_bus *bus = userdata;
2542
2543 assert(event);
2544
2545 sd_bus_flush(bus);
2546
2547 return 1;
2548}
2549
d9f644e2 2550_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
2551 int r;
2552
2553 assert_return(bus, -EINVAL);
40ca29a1
LP
2554 assert_return(!bus->event, -EBUSY);
2555
2556 assert(!bus->input_io_event_source);
2557 assert(!bus->output_io_event_source);
2558 assert(!bus->time_event_source);
2559
76b54375
LP
2560 if (event)
2561 bus->event = sd_event_ref(event);
2562 else {
2563 r = sd_event_default(&bus->event);
2564 if (r < 0)
2565 return r;
2566 }
40ca29a1 2567
76b54375 2568 r = sd_event_add_io(bus->event, bus->input_fd, 0, io_callback, bus, &bus->input_io_event_source);
40ca29a1
LP
2569 if (r < 0)
2570 goto fail;
2571
2572 r = sd_event_source_set_priority(bus->input_io_event_source, priority);
2573 if (r < 0)
2574 goto fail;
2575
2576 if (bus->output_fd != bus->input_fd) {
76b54375 2577 r = sd_event_add_io(bus->event, bus->output_fd, 0, io_callback, bus, &bus->output_io_event_source);
40ca29a1
LP
2578 if (r < 0)
2579 goto fail;
2580
2581 r = sd_event_source_set_priority(bus->output_io_event_source, priority);
2582 if (r < 0)
2583 goto fail;
2584 }
2585
2586 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
2587 if (r < 0)
2588 goto fail;
2589
76b54375 2590 r = sd_event_add_monotonic(bus->event, 0, 0, time_callback, bus, &bus->time_event_source);
40ca29a1
LP
2591 if (r < 0)
2592 goto fail;
2593
2594 r = sd_event_source_set_priority(bus->time_event_source, priority);
2595 if (r < 0)
2596 goto fail;
2597
76b54375 2598 r = sd_event_add_quit(bus->event, quit_callback, bus, &bus->quit_event_source);
abc5fe72
LP
2599 if (r < 0)
2600 goto fail;
2601
40ca29a1
LP
2602 return 0;
2603
2604fail:
2605 sd_bus_detach_event(bus);
2606 return r;
2607}
2608
d9f644e2 2609_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1
LP
2610 assert_return(bus, -EINVAL);
2611 assert_return(bus->event, -ENXIO);
2612
86befb40
LP
2613 if (bus->input_io_event_source) {
2614 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
40ca29a1 2615 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
86befb40 2616 }
40ca29a1 2617
86befb40
LP
2618 if (bus->output_io_event_source) {
2619 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
40ca29a1 2620 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
86befb40 2621 }
40ca29a1 2622
86befb40
LP
2623 if (bus->time_event_source) {
2624 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 2625 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 2626 }
40ca29a1 2627
86befb40
LP
2628 if (bus->quit_event_source) {
2629 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 2630 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 2631 }
abc5fe72 2632
40ca29a1
LP
2633 if (bus->event)
2634 bus->event = sd_event_unref(bus->event);
2635
2636 return 0;
2637}
affff0b6 2638
2be44176
LP
2639_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
2640 assert_return(bus, NULL);
2641
2642 return bus->event;
2643}
2644
76b54375 2645_public_ sd_bus_message* sd_bus_get_current(sd_bus *bus) {
affff0b6
LP
2646 assert_return(bus, NULL);
2647
2648 return bus->current;
2649}
76b54375
LP
2650
2651static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
2652 sd_bus *b = NULL;
2653 int r;
2654
2655 assert(bus_open);
2656 assert(default_bus);
2657
2658 if (!ret)
2659 return !!*default_bus;
2660
2661 if (*default_bus) {
2662 *ret = sd_bus_ref(*default_bus);
2663 return 0;
2664 }
2665
2666 r = bus_open(&b);
2667 if (r < 0)
2668 return r;
2669
2670 b->default_bus_ptr = default_bus;
2671 b->tid = gettid();
2672 *default_bus = b;
2673
2674 *ret = b;
2675 return 1;
2676}
2677
2678_public_ int sd_bus_default_system(sd_bus **ret) {
2679 static __thread sd_bus *default_system_bus = NULL;
2680
2681 return bus_default(sd_bus_open_system, &default_system_bus, ret);
2682}
2683
2684_public_ int sd_bus_default_user(sd_bus **ret) {
2685 static __thread sd_bus *default_user_bus = NULL;
2686
2687 return bus_default(sd_bus_open_user, &default_user_bus, ret);
2688}
2689
2690_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
2691 assert_return(b, -EINVAL);
2692 assert_return(tid, -EINVAL);
2693 assert_return(!bus_pid_changed(b), -ECHILD);
2694
2695 if (b->tid != 0) {
2696 *tid = b->tid;
2697 return 0;
2698 }
2699
2700 if (b->event)
2701 return sd_event_get_tid(b->event, tid);
2702
2703 return -ENXIO;
2704}
28383ba1
LP
2705
2706_public_ char *sd_bus_label_escape(const char *s) {
2707 char *r, *t;
2708 const char *f;
2709
2710 assert_return(s, NULL);
2711
2712 /* Escapes all chars that D-Bus' object path cannot deal
2713 * with. Can be reversed with bus_path_unescape(). We special
2714 * case the empty string. */
2715
2716 if (*s == 0)
2717 return strdup("_");
2718
2719 r = new(char, strlen(s)*3 + 1);
2720 if (!r)
2721 return NULL;
2722
2723 for (f = s, t = r; *f; f++) {
2724
2725 /* Escape everything that is not a-zA-Z0-9. We also
2726 * escape 0-9 if it's the first character */
2727
2728 if (!(*f >= 'A' && *f <= 'Z') &&
2729 !(*f >= 'a' && *f <= 'z') &&
2730 !(f > s && *f >= '0' && *f <= '9')) {
2731 *(t++) = '_';
2732 *(t++) = hexchar(*f >> 4);
2733 *(t++) = hexchar(*f);
2734 } else
2735 *(t++) = *f;
2736 }
2737
2738 *t = 0;
2739
2740 return r;
2741}
2742
2743_public_ char *sd_bus_label_unescape(const char *f) {
2744 char *r, *t;
2745
2746 assert_return(f, NULL);
2747
2748 /* Special case for the empty string */
2749 if (streq(f, "_"))
2750 return strdup("");
2751
2752 r = new(char, strlen(f) + 1);
2753 if (!r)
2754 return NULL;
2755
2756 for (t = r; *f; f++) {
2757
2758 if (*f == '_') {
2759 int a, b;
2760
2761 if ((a = unhexchar(f[1])) < 0 ||
2762 (b = unhexchar(f[2])) < 0) {
2763 /* Invalid escape code, let's take it literal then */
2764 *(t++) = '_';
2765 } else {
2766 *(t++) = (char) ((a << 4) | b);
2767 f += 2;
2768 }
2769 } else
2770 *(t++) = *f;
2771 }
2772
2773 *t = 0;
2774
2775 return r;
2776}
5b12334d
LP
2777
2778_public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
2779 sd_bus_creds *c;
2780 pid_t pid = 0;
2781 int r;
2782
2783 assert_return(bus, -EINVAL);
2784 assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
2785 assert_return(ret, -EINVAL);
2786 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2787 assert_return(!bus_pid_changed(bus), -ECHILD);
2788 assert_return(!bus->is_kernel, -ENOTSUP);
2789
2790 if (!bus->ucred_valid && !isempty(bus->label))
2791 return -ENODATA;
2792
2793 c = bus_creds_new();
2794 if (!c)
2795 return -ENOMEM;
2796
2797 if (bus->ucred_valid) {
2798 pid = c->pid = bus->ucred.pid;
2799 c->uid = bus->ucred.uid;
2800 c->gid = bus->ucred.gid;
2801
2802 c->mask |= ((SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask) & bus->creds_mask;
2803 }
2804
2805 if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
2806 c->label = strdup(bus->label);
2807 if (!c->label) {
2808 sd_bus_creds_unref(c);
2809 return -ENOMEM;
2810 }
2811
2812 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT | bus->creds_mask;
2813 }
2814
2815 r = bus_creds_add_more(c, mask, pid, 0);
2816 if (r < 0)
2817 return r;
2818
2819 *ret = c;
2820 return 0;
2821}