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