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