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