LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - sd-bus.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 1026 2059 49.8 %
Date: 2015-07-29 18:47:03 Functions: 80 123 65.0 %

          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             : }

Generated by: LCOV version 1.11