static int driver_remove_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { struct bus_match_component *components = NULL; _cleanup_free_ char *normalized = NULL; Context *context = userdata; unsigned n_components = 0; Client *c = NULL; Match *m = NULL; char *arg0; uint64_t id; int r; assert(bus); assert(message); assert(context); r = sd_bus_message_read(message, "s", &arg0); if (r < 0) return r; r = bus_kernel_parse_unique_name(message->sender, &id); if (r < 0) return r; c = hashmap_get(context->clients, &id); if (!c) return sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "You have not registered any matches."); r = bus_match_parse(arg0, &components, &n_components); if (r < 0) { r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0); goto finish; } normalized = bus_match_to_string(components, n_components); if (!normalized) { r = -ENOMEM; goto finish; } m = hashmap_get(c->matches, normalized); if (!m) { r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule \"%s\" not found.", normalized); goto finish; } bus_remove_match_internal_kernel(bus, id, m->cookie); match_free(m); r = sd_bus_reply_method_return(message, NULL); finish: bus_match_parse_free(components, n_components); if (c->n_matches <= 0) client_free(c); return r; }
static void test_match_scope(const char *match, enum bus_match_scope scope) { struct bus_match_component *components = NULL; unsigned n_components = 0; assert_se(bus_match_parse(match, &components, &n_components) >= 0); assert_se(bus_match_get_scope(components, n_components) == scope); bus_match_parse_free(components, n_components); }
static int match_add(sd_bus_slot *slots, struct bus_match_node *root, const char *match, int value) { struct bus_match_component *components = NULL; unsigned n_components = 0; sd_bus_slot *s; int r; s = slots + value; zero(*s); r = bus_match_parse(match, &components, &n_components); if (r < 0) return r; s->userdata = INT_TO_PTR(value); s->match_callback.callback = filter; r = bus_match_add(root, components, n_components, &s->match_callback); bus_match_parse_free(components, n_components); return r; }
static int driver_add_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { struct bus_match_component *components = NULL; Context *context = userdata; unsigned n_components = 0; Match *m = NULL; Client *c = NULL; char *arg0; uint64_t id; int r; assert(bus); assert(message); assert(context); r = sd_bus_message_read(message, "s", &arg0); if (r < 0) return r; r = bus_kernel_parse_unique_name(message->sender, &id); if (r < 0) return r; r = client_acquire(context, id, &c); if (r == -ENOBUFS) return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u clients", CLIENTS_MAX); if (r < 0) return r; if (c->n_matches >= MATCHES_MAX) { r = sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u matches per client", MATCHES_MAX); goto fail; } r = bus_match_parse(arg0, &components, &n_components); if (r < 0) { r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0); goto fail; } r = match_new(c, components, n_components, &m); if (r < 0) goto fail; r = bus_add_match_internal_kernel(bus, id, components, n_components, m->cookie); if (r < 0) goto fail; bus_match_parse_free(components, n_components); return sd_bus_reply_method_return(message, NULL); fail: bus_match_parse_free(components, n_components); match_free(m); if (c->n_matches <= 0) client_free(c); return r; }