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