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