X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-match.c;h=3a31aa0ebfc9cc6a79470314332b795c62ae7190;hb=fed1e721fd0c81e60c77120539f34e16c2585634;hp=5658c61ba789fba1529c99112bb4be8159f90b69;hpb=ef7b6c0190fefaacf6d8f8e1a6dda4ba8b98091b;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index 5658c61ba..3a31aa0eb 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -134,6 +134,7 @@ static bool value_node_test( enum bus_match_node_type parent_type, uint8_t value_u8, const char *value_str, + char **value_strv, sd_bus_message *m) { assert(node); @@ -179,17 +180,46 @@ static bool value_node_test( case BUS_MATCH_INTERFACE: case BUS_MATCH_MEMBER: case BUS_MATCH_PATH: - case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: - return streq_ptr(node->value.str, value_str); + case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: { + char **i; - case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: - return namespace_simple_pattern(node->value.str, value_str); + if (value_str) + return streq_ptr(node->value.str, value_str); + + STRV_FOREACH(i, value_strv) + if (streq_ptr(node->value.str, *i)) + return true; + + return false; + } + + case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: { + char **i; + + if (value_str) + return namespace_simple_pattern(node->value.str, value_str); + + STRV_FOREACH(i, value_strv) + if (namespace_simple_pattern(node->value.str, *i)) + return true; + return false; + } case BUS_MATCH_PATH_NAMESPACE: return path_simple_pattern(node->value.str, value_str); - case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: - return path_complex_pattern(node->value.str, value_str); + case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: { + char **i; + + if (value_str) + return path_complex_pattern(node->value.str, value_str); + + STRV_FOREACH(i, value_strv) + if (path_complex_pattern(node->value.str, *i)) + return true; + + return false; + } default: assert_not_reached("Invalid node type"); @@ -235,7 +265,7 @@ int bus_match_run( struct bus_match_node *node, sd_bus_message *m) { - + _cleanup_strv_free_ char **test_strv = NULL; const char *test_str = NULL; uint8_t test_u8 = 0; int r; @@ -343,15 +373,15 @@ int bus_match_run( break; case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: - test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str, &test_strv); break; case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: - test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str, &test_strv); break; case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: - test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str, &test_strv); break; default: @@ -365,7 +395,20 @@ int bus_match_run( if (test_str) found = hashmap_get(node->compare.children, test_str); - else if (node->type == BUS_MATCH_MESSAGE_TYPE) + else if (test_strv) { + char **i; + + STRV_FOREACH(i, test_strv) { + found = hashmap_get(node->compare.children, *i); + if (found) { + r = bus_match_run(bus, found, m); + if (r != 0) + return r; + } + } + + found = NULL; + } else if (node->type == BUS_MATCH_MESSAGE_TYPE) found = hashmap_get(node->compare.children, UINT_TO_PTR(test_u8)); else found = NULL; @@ -381,7 +424,7 @@ int bus_match_run( /* No hash table, so let's iterate manually... */ for (c = node->child; c; c = c->next) { - if (!value_node_test(c, node->type, test_u8, test_str, m)) + if (!value_node_test(c, node->type, test_u8, test_str, test_strv, m)) continue; r = bus_match_run(bus, c, m); @@ -748,6 +791,9 @@ int bus_match_parse( bool escaped = false, quoted; uint8_t u; + /* Avahi's match rules appear to include whitespace, skip over it */ + p += strspn(p, " "); + eq = strchr(p, '='); if (!eq) return -EINVAL;