X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-match.c;h=f7fca5f573de962ec250927bff15a84d648b6a3a;hp=95e625be096167ba987550fb230c15e0bec963ff;hb=c1b9d935725103e95901f347b8981647ce4dd546;hpb=c78196699d3d805b2237896a1d2b8efeec6068d0;ds=sidebyside diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index 95e625be0..f7fca5f57 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -22,6 +22,8 @@ #include "bus-internal.h" #include "bus-message.h" #include "bus-match.h" +#include "bus-error.h" +#include "bus-util.h" /* Example: * @@ -60,7 +62,7 @@ */ static inline bool BUS_MATCH_IS_COMPARE(enum bus_match_node_type t) { - return t >= BUS_MATCH_MESSAGE_TYPE && t <= BUS_MATCH_ARG_NAMESPACE_LAST; + return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_NAMESPACE_LAST; } static inline bool BUS_MATCH_CAN_HASH(enum bus_match_node_type t) { @@ -142,6 +144,22 @@ static bool value_node_test( case BUS_MATCH_SENDER: case BUS_MATCH_DESTINATION: + if (streq_ptr(node->value.str, value_str)) + return true; + + /* FIXME: So here's an ugliness: if the match is for a + * well-known name then we cannot actually check this + * correctly here. This doesn't matter much for dbus1 + * where no false positives exist, hence we just + * ignore this case here. For kdbus the messages + * should contain all well-known names of the sender, + * hence we can fix things there correctly. */ + + if (node->value.str[0] != ':' && value_str && value_str[0] == ':') + return true; + + return false; + case BUS_MATCH_INTERFACE: case BUS_MATCH_MEMBER: case BUS_MATCH_PATH: @@ -256,7 +274,10 @@ int bus_match_run( /* Run the callback. And then invoke siblings. */ if (node->leaf.callback) { - r = node->leaf.callback(bus, m, node->leaf.userdata); + _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + + r = node->leaf.callback(bus, m, node->leaf.userdata, &error_buffer); + r = bus_maybe_reply_error(m, r, &error_buffer); if (r != 0) return r; } @@ -555,22 +576,22 @@ static int bus_match_find_leaf( enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n) { assert(k); - if (n == 4 && memcmp(k, "type", 4) == 0) + if (n == 4 && startswith(k, "type")) return BUS_MATCH_MESSAGE_TYPE; - if (n == 6 && memcmp(k, "sender", 6) == 0) + if (n == 6 && startswith(k, "sender")) return BUS_MATCH_SENDER; - if (n == 11 && memcmp(k, "destination", 11) == 0) + if (n == 11 && startswith(k, "destination")) return BUS_MATCH_DESTINATION; - if (n == 9 && memcmp(k, "interface", 9) == 0) + if (n == 9 && startswith(k, "interface")) return BUS_MATCH_INTERFACE; - if (n == 6 && memcmp(k, "member", 6) == 0) + if (n == 6 && startswith(k, "member")) return BUS_MATCH_MEMBER; - if (n == 4 && memcmp(k, "path", 4) == 0) + if (n == 4 && startswith(k, "path")) return BUS_MATCH_PATH; - if (n == 14 && memcmp(k, "path_namespace", 14) == 0) + if (n == 14 && startswith(k, "path_namespace")) return BUS_MATCH_PATH_NAMESPACE; - if (n == 4 && memcmp(k, "arg", 3) == 0) { + if (n == 4 && startswith(k, "arg")) { int j; j = undecchar(k[3]); @@ -580,7 +601,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG + j; } - if (n == 5 && memcmp(k, "arg", 3) == 0) { + if (n == 5 && startswith(k, "arg")) { int a, b; enum bus_match_node_type t; @@ -596,7 +617,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 8 && memcmp(k, "arg", 3) == 0 && memcmp(k + 4, "path", 4) == 0) { + if (n == 8 && startswith(k, "arg") && startswith(k + 4, "path")) { int j; j = undecchar(k[3]); @@ -606,7 +627,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_PATH + j; } - if (n == 9 && memcmp(k, "arg", 3) == 0 && memcmp(k + 5, "path", 4) == 0) { + if (n == 9 && startswith(k, "arg") && startswith(k + 5, "path")) { enum bus_match_node_type t; int a, b; @@ -622,7 +643,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } - if (n == 13 && memcmp(k, "arg", 3) == 0 && memcmp(k + 4, "namespace", 9) == 0) { + if (n == 13 && startswith(k, "arg") && startswith(k + 4, "namespace")) { int j; j = undecchar(k[3]); @@ -632,7 +653,7 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return BUS_MATCH_ARG_NAMESPACE + j; } - if (n == 14 && memcmp(k, "arg", 3) == 0 && memcmp(k + 5, "namespace", 9) == 0) { + if (n == 14 && startswith(k, "arg") && startswith(k + 5, "namespace")) { enum bus_match_node_type t; int a, b; @@ -768,7 +789,7 @@ int bus_match_parse( } /* Order the whole thing, so that we always generate the same tree */ - qsort(components, n_components, sizeof(struct bus_match_component), match_component_compare); + qsort_safe(components, n_components, sizeof(struct bus_match_component), match_component_compare); /* Check for duplicates */ for (i = 0; i+1 < n_components; i++)