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