void bus_match_dump(struct bus_match_node *node, unsigned level) { struct bus_match_node *c; _cleanup_free_ char *pfx = NULL; char buf[32]; if (!node) return; pfx = strrep(" ", level); printf("%s[%s]", strempty(pfx), bus_match_node_type_to_string(node->type, buf, sizeof(buf))); if (node->type == BUS_MATCH_VALUE) { if (node->parent->type == BUS_MATCH_MESSAGE_TYPE) printf(" <%u>\n", node->value.u8); else printf(" <%s>\n", node->value.str); } else if (node->type == BUS_MATCH_ROOT) puts(" root"); else if (node->type == BUS_MATCH_LEAF) printf(" %p/%p\n", node->leaf.callback, node->leaf.userdata); else putchar('\n'); if (BUS_MATCH_CAN_HASH(node->type)) { Iterator i; HASHMAP_FOREACH(c, node->compare.children, i) bus_match_dump(c, level + 1); } for (c = node->child; c; c = c->next) bus_match_dump(c, level + 1); }
int main(int argc, char *argv[]) { struct bus_match_node root; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; enum bus_match_node_type i; zero(root); root.type = BUS_MATCH_ROOT; assert_se(bus_match_add(&root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(1), NULL) >= 0); assert_se(bus_match_add(&root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(2), NULL) >= 0); assert_se(bus_match_add(&root, "arg3='test',sender='foo',type='signal',interface='bar',", filter, INT_TO_PTR(3), NULL) >= 0); assert_se(bus_match_add(&root, "arg3='test',sender='foo',type='method_call',interface='bar',", filter, INT_TO_PTR(4), NULL) >= 0); assert_se(bus_match_add(&root, "", filter, INT_TO_PTR(5), NULL) >= 0); assert_se(bus_match_add(&root, "interface='quux'", filter, INT_TO_PTR(6), NULL) >= 0); assert_se(bus_match_add(&root, "interface='bar'", filter, INT_TO_PTR(7), NULL) >= 0); assert_se(bus_match_add(&root, "member='waldo',path='/foo/bar'", filter, INT_TO_PTR(8), NULL) >= 0); assert_se(bus_match_add(&root, "path='/foo/bar'", filter, INT_TO_PTR(9), NULL) >= 0); assert_se(bus_match_add(&root, "path_namespace='/foo'", filter, INT_TO_PTR(10), NULL) >= 0); assert_se(bus_match_add(&root, "path_namespace='/foo/quux'", filter, INT_TO_PTR(11), NULL) >= 0); assert_se(bus_match_add(&root, "arg1='two'", filter, INT_TO_PTR(12), NULL) >= 0); assert_se(bus_match_add(&root, "member='waldo',arg2path='/prefix/'", filter, INT_TO_PTR(13), NULL) >= 0); assert_se(bus_match_add(&root, "member='waldo',path='/foo/bar',arg3namespace='prefix'", filter, INT_TO_PTR(14), NULL) >= 0); bus_match_dump(&root, 0); assert_se(sd_bus_message_new_signal(NULL, "/foo/bar", "bar", "waldo", &m) >= 0); assert_se(sd_bus_message_append(m, "ssss", "one", "two", "/prefix/three", "prefix.four") >= 0); assert_se(bus_message_seal(m, 1) >= 0); zero(mask); assert_se(bus_match_run(NULL, &root, 0, m) == 0); assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14 }, 8));
int main(int argc, char *argv[]) { struct bus_match_node root = { .type = BUS_MATCH_ROOT, }; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; enum bus_match_node_type i; sd_bus_slot slots[19]; int r; r = sd_bus_open_system(&bus); if (r < 0) return EXIT_TEST_SKIP; assert_se(match_add(slots, &root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar.x',", 1) >= 0); assert_se(match_add(slots, &root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar.x',", 2) >= 0); assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='signal',interface='bar.x',", 3) >= 0); assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='method_call',interface='bar.x',", 4) >= 0); assert_se(match_add(slots, &root, "", 5) >= 0); assert_se(match_add(slots, &root, "interface='quux.x'", 6) >= 0); assert_se(match_add(slots, &root, "interface='bar.x'", 7) >= 0); assert_se(match_add(slots, &root, "member='waldo',path='/foo/bar'", 8) >= 0); assert_se(match_add(slots, &root, "path='/foo/bar'", 9) >= 0); assert_se(match_add(slots, &root, "path_namespace='/foo'", 10) >= 0); assert_se(match_add(slots, &root, "path_namespace='/foo/quux'", 11) >= 0); assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0); assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0); assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0); assert_se(match_add(slots, &root, "arg4has='pi'", 15) >= 0); assert_se(match_add(slots, &root, "arg4has='pa'", 16) >= 0); assert_se(match_add(slots, &root, "arg4has='po'", 17) >= 0); assert_se(match_add(slots, &root, "arg4='pi'", 18) >= 0); bus_match_dump(&root, 0); assert_se(sd_bus_message_new_signal(bus, &m, "/foo/bar", "bar.x", "waldo") >= 0); assert_se(sd_bus_message_append(m, "ssssas", "one", "two", "/prefix/three", "prefix.four", 3, "pi", "pa", "po") >= 0); assert_se(bus_message_seal(m, 1, 0) >= 0); zero(mask); assert_se(bus_match_run(NULL, &root, m) == 0); assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14, 15, 16, 17 }, 11));
static int server_init(sd_bus **_bus) { sd_bus *bus = NULL; sd_id128_t id; int r; const char *unique; assert_se(_bus); r = sd_bus_open_user(&bus); if (r < 0) { log_error_errno(r, "Failed to connect to user bus: %m"); goto fail; } r = sd_bus_get_bus_id(bus, &id); if (r < 0) { log_error_errno(r, "Failed to get server ID: %m"); goto fail; } r = sd_bus_get_unique_name(bus, &unique); if (r < 0) { log_error_errno(r, "Failed to get unique name: %m"); goto fail; } log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id)); log_info("Unique ID: %s", unique); log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h')); r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0); if (r < 0) { log_error_errno(r, "Failed to acquire name: %m"); goto fail; } r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add object: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } bus_match_dump(&bus->match_callbacks, 0); *_bus = bus; return 0; fail: if (bus) sd_bus_unref(bus); return r; }