LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - sd-bus.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 1395 2377 58.7 %
Date: 2019-08-22 15:41:25 Functions: 107 158 67.7 %

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

Generated by: LCOV version 1.14