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