X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-util.c;h=2140dbc676888c29f25a88832033bfedcae9d318;hp=ad1cb1a6d0fe84e5ab6cbe56ca1454341b885f98;hb=21586b77de9bad401f245dd55b75cedb0c2e9b7c;hpb=e65040306900e36aaa84b52428be3490bf107850 diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c index ad1cb1a6d..2140dbc67 100644 --- a/src/libsystemd-bus/bus-util.c +++ b/src/libsystemd-bus/bus-util.c @@ -25,15 +25,16 @@ #include "strv.h" #include "macro.h" #include "def.h" +#include "missing.h" #include "sd-event.h" #include "sd-bus.h" #include "bus-error.h" #include "bus-message.h" - #include "bus-util.h" +#include "bus-internal.h" -static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata) { +static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { sd_event *e = userdata; assert(bus); @@ -102,25 +103,6 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t return 0; } -int bus_property_get_tristate( - sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - sd_bus_error *error, - void *userdata) { - - int *tristate = userdata; - int r; - - r = sd_bus_message_append(reply, "b", *tristate > 0); - if (r < 0) - return r; - - return 1; -} - int bus_verify_polkit( sd_bus *bus, sd_bus_message *m, @@ -151,7 +133,7 @@ int bus_verify_polkit( #ifdef ENABLE_POLKIT else { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - unsigned authorized = false, challenge = false; + int authorized = false, challenge = false; r = sd_bus_call_method( bus, @@ -178,9 +160,9 @@ int bus_verify_polkit( return r; } - r = sd_bus_message_read(reply, "(bb)", &authorized, &challenge); - if (r < 0) - return r; + r = sd_bus_message_enter_container(reply, 'r', "bba{ss}"); + if (r >= 0) + r = sd_bus_message_read(reply, "bb", &authorized, &challenge); if (authorized) return 1; @@ -202,11 +184,30 @@ typedef struct AsyncPolkitQuery { sd_bus_message_handler_t callback; void *userdata; uint64_t serial; + Hashmap *registry; } AsyncPolkitQuery; -static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) { - AsyncPolkitQuery *q = userdata; +static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) { + + if (!q) + return; + + if (q->serial > 0 && b) + sd_bus_call_async_cancel(b, q->serial); + + if (q->registry && q->request) + hashmap_remove(q->registry, q->request); + + sd_bus_message_unref(q->request); + sd_bus_message_unref(q->reply); + + free(q); +} + +static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) { + _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + AsyncPolkitQuery *q = userdata; int r; assert(bus); @@ -216,30 +217,18 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd q->reply = sd_bus_message_ref(reply); q->serial = 0; - m = sd_bus_message_ref(q->request); - - r = sd_bus_message_rewind(m, true); - if (r < 0) - return r; - - r = q->callback(bus, m, q->userdata); - if (r < 0) - return r; - - return 1; -} - -static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) { - - if (!q) - return; + r = sd_bus_message_rewind(q->request, true); + if (r < 0) { + r = sd_bus_reply_method_errno(q->request, r, NULL); + goto finish; + } - if (q->serial > 0 && b) - sd_bus_send_with_reply_cancel(b, q->serial); + r = q->callback(bus, q->request, q->userdata, &error_buffer); + r = bus_maybe_reply_error(q->request, r, &error_buffer); - sd_bus_message_unref(q->request); - sd_bus_message_unref(q->reply); - free(q); +finish: + async_polkit_query_free(bus, q); + return r; } #endif @@ -268,9 +257,9 @@ int bus_verify_polkit_async( assert(action); #ifdef ENABLE_POLKIT - q = hashmap_remove(*registry, m); + q = hashmap_get(*registry, m); if (q) { - unsigned authorized, challenge; + int authorized, challenge; /* This is the second invocation of this function, and * there's already a response from polkit, let's @@ -280,26 +269,21 @@ int bus_verify_polkit_async( if (sd_bus_message_is_method_error(q->reply, NULL)) { const sd_bus_error *e; - /* Treat no PK available as access denied */ - if (sd_bus_message_is_method_error(q->reply, SD_BUS_ERROR_SERVICE_UNKNOWN)) { - async_polkit_query_free(bus, q); - return -EACCES; - } - + /* Copy error from polkit reply */ e = sd_bus_message_get_error(q->reply); sd_bus_error_copy(error, e); - r = sd_bus_error_get_errno(e); - async_polkit_query_free(bus, q); - return r; + /* Treat no PK available as access denied */ + if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) + return -EACCES; + + return sd_bus_error_get_errno(e); } r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}"); if (r >= 0) r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge); - async_polkit_query_free(bus, q); - if (r < 0) return r; @@ -343,7 +327,7 @@ int bus_verify_polkit_async( action, 0, interactive ? 1 : 0, - ""); + NULL); if (r < 0) return r; @@ -361,9 +345,13 @@ int bus_verify_polkit_async( return r; } - r = sd_bus_send_with_reply(bus, pk, async_polkit_callback, q, 0, &q->serial); - if (r < 0) + q->registry = *registry; + + r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial); + if (r < 0) { + async_polkit_query_free(bus, q); return r; + } return 0; #endif @@ -382,7 +370,7 @@ void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) { #endif } -static int bus_check_peercred(sd_bus *c) { +int bus_check_peercred(sd_bus *c) { struct ucred ucred; socklen_t l; int fd; @@ -440,20 +428,66 @@ int bus_open_system_systemd(sd_bus **_bus) { return 0; } -int bus_generic_print_property(const char *name, sd_bus_message *property, bool all) { +int bus_open_user_systemd(sd_bus **_bus) { + _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_free_ char *p = NULL; + const char *e; + int r; + + /* If we are supposed to talk to the instance, try via + * XDG_RUNTIME_DIR first, then fallback to normal bus + * access */ + + assert(_bus); + + e = secure_getenv("XDG_RUNTIME_DIR"); + if (e) { + if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) + return -ENOMEM; + } + + r = sd_bus_new(&bus); + if (r < 0) + return r; + + r = sd_bus_set_address(bus, p); + if (r < 0) + return r; + + r = sd_bus_start(bus); + if (r < 0) + return r; + + r = bus_check_peercred(bus); + if (r < 0) + return r; + + *_bus = bus; + bus = NULL; + + return 0; +} + +int bus_print_property(const char *name, sd_bus_message *property, bool all) { char type; const char *contents; + int r; assert(name); assert(property); - sd_bus_message_peek_type(property, &type, &contents); + r = sd_bus_message_peek_type(property, &type, &contents); + if (r < 0) + return r; switch (type) { case SD_BUS_TYPE_STRING: { const char *s; - sd_bus_message_read_basic(property, type, &s); + + r = sd_bus_message_read_basic(property, type, &s); + if (r < 0) + return r; if (all || !isempty(s)) printf("%s=%s\n", name, s); @@ -464,7 +498,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool case SD_BUS_TYPE_BOOLEAN: { bool b; - sd_bus_message_read_basic(property, type, &b); + r = sd_bus_message_read_basic(property, type, &b); + if (r < 0) + return r; + printf("%s=%s\n", name, yes_no(b)); return 1; @@ -473,7 +510,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool case SD_BUS_TYPE_UINT64: { uint64_t u; - sd_bus_message_read_basic(property, type, &u); + r = sd_bus_message_read_basic(property, type, &u); + if (r < 0) + return r; /* Yes, heuristics! But we can change this check * should it turn out to not be sufficient */ @@ -498,7 +537,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool case SD_BUS_TYPE_UINT32: { uint32_t u; - sd_bus_message_read_basic(property, type, &u); + r = sd_bus_message_read_basic(property, type, &u); + if (r < 0) + return r; if (strstr(name, "UMask") || strstr(name, "Mode")) printf("%s=%04o\n", name, u); @@ -511,7 +552,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool case SD_BUS_TYPE_INT32: { int32_t i; - sd_bus_message_read_basic(property, type, &i); + r = sd_bus_message_read_basic(property, type, &i); + if (r < 0) + return r; printf("%s=%i\n", name, (int) i); return 1; @@ -520,38 +563,42 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool case SD_BUS_TYPE_DOUBLE: { double d; - sd_bus_message_read_basic(property, type, &d); + r = sd_bus_message_read_basic(property, type, &d); + if (r < 0) + return r; printf("%s=%g\n", name, d); return 1; } case SD_BUS_TYPE_ARRAY: - if (streq(contents, "s")) { - bool space = false; - char tp; - const char *cnt; - - sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents); - - sd_bus_message_peek_type(property, &tp, &cnt); - if (all || cnt) { - const char *str; + bool first = true; + const char *str; - printf("%s=", name); + r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents); + if (r < 0) + return r; + while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) { + if (first) + printf("%s=", name); - while(sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str) > 0) { - printf("%s%s", space ? " " : "", str); + printf("%s%s", first ? "" : " ", str); - space = true; - } + first = false; + } + if (r < 0) + return r; + if (first && all) + printf("%s=", name); + if (!first || all) puts(""); - } - sd_bus_message_exit_container(property); + r = sd_bus_message_exit_container(property); + if (r < 0) + return r; return 1; @@ -559,7 +606,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool const uint8_t *u; size_t n; - sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n); + r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n); + if (r < 0) + return r; + if (all || n > 0) { unsigned int i; @@ -577,7 +627,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool uint32_t *u; size_t n; - sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n); + r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n); + if (r < 0) + return r; + if (all || n > 0) { unsigned int i; @@ -598,160 +651,269 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool return 0; } -int bus_map_all_properties(sd_bus *bus, - const char *destination, - const char *path, - const struct bus_properties_map *map) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; +int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) { + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; int r; - r = sd_bus_call_method( bus, - destination, + assert(bus); + assert(path); + + r = sd_bus_call_method(bus, + dest, path, "org.freedesktop.DBus.Properties", "GetAll", &error, - &m, + &reply, "s", ""); - if (r < 0) { - log_error("Could not get properties: %s", bus_error_message(&error, -r)); + if (r < 0) return r; - } - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); + r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}"); if (r < 0) return r; - while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { const char *name; - char type; const char *contents; - unsigned i; - r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name); + r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name); if (r < 0) return r; - r = sd_bus_message_peek_type(m, NULL, &contents); - if (r < 0) - return r; + if (!filter || strv_find(filter, name)) { + r = sd_bus_message_peek_type(reply, NULL, &contents); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents); + if (r < 0) + return r; + + r = bus_print_property(name, reply, all); + if (r < 0) + return r; + if (r == 0) { + if (all) + printf("%s=[unprintable]\n", name); + /* skip what we didn't read */ + r = sd_bus_message_skip(reply, contents); + if (r < 0) + return r; + } - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents); + r = sd_bus_message_exit_container(reply); + if (r < 0) + return r; + } else { + r = sd_bus_message_skip(reply, "v"); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(reply); if (r < 0) return r; + } + if (r < 0) + return r; - r = sd_bus_message_peek_type(m, &type, &contents); - if (r < 0) { - log_error("Could not determine type of message: %s", strerror(-r)); - return r; - } + r = sd_bus_message_exit_container(reply); + if (r < 0) + return r; - switch (type) { - case SD_BUS_TYPE_STRING: { - const char *s; + return 0; +} - sd_bus_message_read_basic(m, type, &s); - if (isempty(s)) - break; +int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { + sd_id128_t *p = userdata; + const void *v; + size_t n; + int r; - for (i = 0; map[i].type; i++) { - char **p; - - if (!streq(map[i].type, "s")) - continue; - if (!streq(map[i].name, name)) - continue; - - p = map[i].ptr; - free(*p); - *p = strdup(s); - if (!*p) { - r = -ENOMEM; - goto fail; - } - } - break; - } + r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n); + if (r < 0) + return r; - case SD_BUS_TYPE_ARRAY: { - _cleanup_strv_free_ char **l = NULL; + if (n == 0) + *p = SD_ID128_NULL; + else if (n == 16) + memcpy((*p).bytes, v, n); + else + return -EINVAL; - if (!streq(contents, "s")) - break; + return 0; +} - for (i = 0; map[i].type; i++) { - char ***p; +static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) { + char type; + int r; - if (!streq(map[i].type, "as")) - continue; - if (!streq(map[i].name, name)) - continue; + r = sd_bus_message_peek_type(m, &type, NULL); + if (r < 0) + return r; - r = bus_message_read_strv_extend(m, &l); - if (r < 0) - break; + switch (type) { + case SD_BUS_TYPE_STRING: { + const char *s; + char *str; + char **p = userdata; - p = map[i].ptr; - strv_free(*p); - *p = l; - l = NULL; - } + r = sd_bus_message_read_basic(m, type, &s); + if (r < 0) break; - } - case SD_BUS_TYPE_BOOLEAN: { - unsigned b; + if (isempty(s)) + break; - sd_bus_message_read_basic(m, type, &b); + str = strdup(s); + if (!str) { + r = -ENOMEM; + break; + } + free(*p); + *p = str; - for (i = 0; map[i].type; i++) { - bool *p; + break; + } - if (!streq(map[i].type, "b")) - continue; - if (!streq(map[i].name, name)) - continue; + case SD_BUS_TYPE_ARRAY: { + _cleanup_strv_free_ char **l = NULL; + char ***p = userdata; - p = map[i].ptr; - *p = b; - } + r = bus_message_read_strv_extend(m, &l); + if (r < 0) break; - } - case SD_BUS_TYPE_UINT64: { - uint64_t t; + strv_free(*p); + *p = l; + l = NULL; - sd_bus_message_read_basic(m, type, &t); + break; + } - for (i = 0; map[i].type; i++) { - uint64_t *p; + case SD_BUS_TYPE_BOOLEAN: { + unsigned b; + bool *p = userdata; + + r = sd_bus_message_read_basic(m, type, &b); + if (r < 0) + break; - if (!streq(map[i].type, "t")) - continue; - if (!streq(map[i].name, name)) - continue; + *p = b; - p = map[i].ptr; - *p = t; - } + break; + } + + case SD_BUS_TYPE_UINT32: { + uint64_t u; + uint32_t *p = userdata; + + r = sd_bus_message_read_basic(m, type, &u); + if (r < 0) break; - } - default: + *p = u; + + break; + } + + case SD_BUS_TYPE_UINT64: { + uint64_t t; + uint64_t *p = userdata; + + r = sd_bus_message_read_basic(m, type, &t); + if (r < 0) break; - } - r = sd_bus_message_exit_container(m); + *p = t; + + break; + } + + default: + break; + } + + return r; +} + +int bus_map_all_properties(sd_bus *bus, + const char *destination, + const char *path, + const struct bus_properties_map *map, + void *userdata) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + assert(bus); + assert(destination); + assert(path); + assert(map); + + r = sd_bus_call_method( bus, + destination, + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &error, + &m, + "s", ""); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); + if (r < 0) + return r; + + while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + const struct bus_properties_map *prop; + const char *member; + const char *contents; + void *v; + unsigned i; + + r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member); if (r < 0) return r; + for (i = 0, prop = NULL; map[i].member; i++) + if (streq(map[i].member, member)) { + prop = &map[i]; + break; + } + + if (prop) { + r = sd_bus_message_peek_type(m, NULL, &contents); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents); + if (r < 0) + return r; + + v = (uint8_t *)userdata + prop->offset; + if (map[i].set) + r = prop->set(bus, member, m, &error, v); + else + r = map_basic(bus, member, m, &error, v); + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + } else { + r = sd_bus_message_skip(m, "v"); + if (r < 0) + return r; + } + r = sd_bus_message_exit_container(m); if (r < 0) return r; } -fail: return r; } @@ -769,9 +931,9 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b case BUS_TRANSPORT_LOCAL: if (user) - r = sd_bus_open_user(bus); + r = sd_bus_default_user(bus); else - r = sd_bus_open_system(bus); + r = sd_bus_default_system(bus); break; @@ -790,32 +952,165 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b return r; } +int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { + int r; + + assert(transport >= 0); + assert(transport < _BUS_TRANSPORT_MAX); + assert(bus); + + assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL); + assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP); + + switch (transport) { + + case BUS_TRANSPORT_LOCAL: + if (user) + r = bus_open_user_systemd(bus); + else + r = bus_open_system_systemd(bus); + + break; + + case BUS_TRANSPORT_REMOTE: + r = sd_bus_open_system_remote(host, bus); + break; + + case BUS_TRANSPORT_CONTAINER: + r = sd_bus_open_system_container(host, bus); + break; + + default: + assert_not_reached("Hmm, unknown transport type."); + } + + return r; +} + +int bus_property_get_tristate( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + int *tristate = userdata; + + return sd_bus_message_append(reply, "b", *tristate > 0); +} + int bus_property_get_bool( sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, - sd_bus_error *error, - void *userdata) { + void *userdata, + sd_bus_error *error) { int b = *(bool*) userdata; return sd_bus_message_append_basic(reply, 'b', &b); } -int bus_property_get_uid( +#if __SIZEOF_SIZE_T__ != 8 +int bus_property_get_size( sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, - sd_bus_error *error, - void *userdata) { + void *userdata, + sd_bus_error *error) { + + uint64_t sz = *(size_t*) userdata; + + return sd_bus_message_append_basic(reply, 't', &sz); +} +#endif + +#if __SIZEOF_LONG__ != 8 +int bus_property_get_long( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + int64_t l = *(long*) userdata; + + return sd_bus_message_append_basic(reply, 'x', &l); +} + +int bus_property_get_ulong( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + uint64_t ul = *(unsigned long*) userdata; + + return sd_bus_message_append_basic(reply, 't', &ul); +} +#endif - assert_cc(sizeof(uint32_t) == sizeof(uid_t)); - assert_cc(sizeof(uint32_t) == sizeof(gid_t)); - assert_cc(sizeof(uint32_t) == sizeof(pid_t)); +int bus_log_parse_error(int r) { + log_error("Failed to parse message: %s", strerror(-r)); + return r; +} - return sd_bus_message_append_basic(reply, 'u', userdata); +int bus_log_create_error(int r) { + log_error("Failed to create message: %s", strerror(-r)); + return r; +} + +int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) { + assert(message); + assert(u); + + return sd_bus_message_read( + message, + "(ssssssouso)", + &u->id, + &u->description, + &u->load_state, + &u->active_state, + &u->sub_state, + &u->following, + &u->unit_path, + &u->job_id, + &u->job_type, + &u->job_path); +} + +int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) { + assert(m); + + if (r < 0) { + if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) + sd_bus_reply_method_errno(m, r, error); + + } else if (sd_bus_error_is_set(error)) { + if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) + sd_bus_reply_method_error(m, error); + } else + return r; + + log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s", + bus_message_type_to_string(m->header->type), + strna(m->sender), + strna(m->path), + strna(m->interface), + strna(m->member), + strna(m->root_container.signature), + bus_error_message(error, r)); + + return 1; }