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