chiark / gitweb /
Prep v228: Add remaining updates from upstream (3/3)
[elogind.git] / src / libelogind / sd-bus / bus-objects.c
index a3d9e552d1abe01e9d315309c27f296b7e8bc86a..4b9c05d09ce15c9b53b57c7fb296274d0bb1efca 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "strv.h"
-#include "set.h"
+#include "alloc-util.h"
 #include "bus-internal.h"
+#include "bus-introspect.h"
 #include "bus-message.h"
-#include "bus-type.h"
+#include "bus-objects.h"
 #include "bus-signature.h"
-#include "bus-introspect.h"
-#include "bus-util.h"
 #include "bus-slot.h"
-#include "bus-objects.h"
+#include "bus-type.h"
+#include "bus-util.h"
+#include "set.h"
+#include "string-util.h"
+#include "strv.h"
 
 static int node_vtable_get_userdata(
                 sd_bus *bus,
@@ -169,11 +171,18 @@ static int add_enumerated_to_set(
         return 0;
 }
 
+enum {
+        /* if set, add_subtree() works recursively */
+        CHILDREN_RECURSIVE              = (1U << 1),
+        /* if set, add_subtree() scans object-manager hierarchies recursively */
+        CHILDREN_SUBHIERARCHIES         = (1U << 0),
+};
+
 static int add_subtree_to_set(
                 sd_bus *bus,
                 const char *prefix,
                 struct node *n,
-                bool skip_subhierarchies,
+                unsigned int flags,
                 Set *s,
                 sd_bus_error *error) {
 
@@ -205,8 +214,9 @@ static int add_subtree_to_set(
                 if (r < 0 && r != -EEXIST)
                         return r;
 
-                if (!skip_subhierarchies || !i->object_managers) {
-                        r = add_subtree_to_set(bus, prefix, i, skip_subhierarchies, s, error);
+                if ((flags & CHILDREN_RECURSIVE) &&
+                    ((flags & CHILDREN_SUBHIERARCHIES) || !i->object_managers)) {
+                        r = add_subtree_to_set(bus, prefix, i, flags, s, error);
                         if (r < 0)
                                 return r;
                         if (bus->nodes_modified)
@@ -221,7 +231,7 @@ static int get_child_nodes(
                 sd_bus *bus,
                 const char *prefix,
                 struct node *n,
-                bool skip_subhierarchies,
+                unsigned int flags,
                 Set **_s,
                 sd_bus_error *error) {
 
@@ -237,7 +247,7 @@ static int get_child_nodes(
         if (!s)
                 return -ENOMEM;
 
-        r = add_subtree_to_set(bus, prefix, n, skip_subhierarchies, s, error);
+        r = add_subtree_to_set(bus, prefix, n, flags, s, error);
         if (r < 0) {
                 set_free_free(s);
                 return r;
@@ -750,6 +760,9 @@ static int vtable_append_all_properties(
                 if (v->flags & SD_BUS_VTABLE_HIDDEN)
                         continue;
 
+                if (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)
+                        continue;
+
                 r = vtable_append_one_property(bus, reply, path, c, v, userdata, error);
                 if (r < 0)
                         return r;
@@ -904,7 +917,7 @@ static int process_introspect(
         assert(n);
         assert(found_object);
 
-        r = get_child_nodes(bus, m->path, n, false, &s, &error);
+        r = get_child_nodes(bus, m->path, n, 0, &s, &error);
         if (r < 0)
                 return bus_maybe_reply_error(m, r, &error);
         if (bus->nodes_modified)
@@ -1170,16 +1183,12 @@ static int process_get_managed_objects(
         if (require_fallback || !n->object_managers)
                 return 0;
 
-        r = get_child_nodes(bus, m->path, n, true, &s, &error);
+        r = get_child_nodes(bus, m->path, n, CHILDREN_RECURSIVE, &s, &error);
         if (r < 0)
                 return r;
         if (bus->nodes_modified)
                 return 0;
 
-        r = set_put_strdup(s, m->path);
-        if (r < 0)
-                return r;
-
         r = sd_bus_message_new_method_return(m, &reply);
         if (r < 0)
                 return r;
@@ -1571,25 +1580,14 @@ _public_ int sd_bus_add_fallback(
         return bus_add_object(bus, slot, true, prefix, callback, userdata);
 }
 
-static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) {
+static void vtable_member_hash_func(const void *a, struct siphash *state) {
         const struct vtable_member *m = a;
-        uint8_t hash_key2[HASH_KEY_SIZE];
-        unsigned long ret;
 
         assert(m);
 
-        ret = string_hash_func(m->path, hash_key);
-
-        /* Use a slightly different hash key for the interface */
-        memcpy(hash_key2, hash_key, HASH_KEY_SIZE);
-        hash_key2[0]++;
-        ret ^= string_hash_func(m->interface, hash_key2);
-
-        /* And an even different one for the  member */
-        hash_key2[0]++;
-        ret ^= string_hash_func(m->member, hash_key2);
-
-        return ret;
+        string_hash_func(m->path, state);
+        string_hash_func(m->interface, state);
+        string_hash_func(m->member, state);
 }
 
 static int vtable_member_compare_func(const void *a, const void *b) {
@@ -1745,8 +1743,9 @@ static int add_object_vtable_internal(
                         if (!member_name_is_valid(v->x.property.member) ||
                             !signature_is_single(v->x.property.signature, false) ||
                             !(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) ||
-                            v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
+                            (v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ||
                             (!!(v->flags & SD_BUS_VTABLE_PROPERTY_CONST) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) > 1 ||
+                            ((v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) && (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)) ||
                             (v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) {
                                 r = -EINVAL;
                                 goto fail;