static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) { _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL; AsyncPolkitQuery *q = userdata; int r; assert(bus); assert(reply); assert(q); q->slot = sd_bus_slot_unref(q->slot); q->reply = sd_bus_message_ref(reply); r = sd_bus_message_rewind(q->request, true); if (r < 0) { r = sd_bus_reply_method_errno(q->request, r, NULL); goto finish; } r = q->callback(bus, q->request, q->userdata, &error_buffer); r = bus_maybe_reply_error(q->request, r, &error_buffer); finish: async_polkit_query_free(q); return r; }
int bus_match_run( sd_bus *bus, struct bus_match_node *node, sd_bus_message *m) { const char *test_str = NULL; uint8_t test_u8 = 0; int r; assert(m); if (!node) return 0; if (bus && bus->match_callbacks_modified) return 0; /* Not these special semantics: when traversing the tree we * usually let bus_match_run() when called for a node * recursively invoke bus_match_run(). There's are two * exceptions here though, which are BUS_NODE_ROOT (which * cannot have a sibling), and BUS_NODE_VALUE (whose siblings * are invoked anyway by its parent. */ switch (node->type) { case BUS_MATCH_ROOT: /* Run all children. Since we cannot have any siblings * we won't call any. The children of the root node * are compares or leaves, they will automatically * call their siblings. */ return bus_match_run(bus, node->child, m); case BUS_MATCH_VALUE: /* Run all children. We don't execute any siblings, we * assume our caller does that. The children of value * nodes are compares or leaves, they will * automatically call their siblings */ assert(node->child); return bus_match_run(bus, node->child, m); case BUS_MATCH_LEAF: if (bus) { if (node->leaf.last_iteration == bus->iteration_counter) return 0; node->leaf.last_iteration = bus->iteration_counter; } r = sd_bus_message_rewind(m, true); if (r < 0) return r; /* Run the callback. And then invoke siblings. */ if (node->leaf.callback) { _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; } return bus_match_run(bus, node->next, m); case BUS_MATCH_MESSAGE_TYPE: test_u8 = m->header->type; break; case BUS_MATCH_SENDER: test_str = m->sender; /* FIXME: resolve test_str from a well-known to a unique name first */ break; case BUS_MATCH_DESTINATION: test_str = m->destination; break; case BUS_MATCH_INTERFACE: test_str = m->interface; break; case BUS_MATCH_MEMBER: test_str = m->member; break; case BUS_MATCH_PATH: case BUS_MATCH_PATH_NAMESPACE: test_str = m->path; break; case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG); break; case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH); break; case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: test_str = bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE); break; default: assert_not_reached("Unknown match type."); } if (BUS_MATCH_CAN_HASH(node->type)) { struct bus_match_node *found; /* Lookup via hash table, nice! So let's jump directly. */ if (test_str) found = hashmap_get(node->compare.children, test_str); else if (node->type == BUS_MATCH_MESSAGE_TYPE) found = hashmap_get(node->compare.children, UINT_TO_PTR(test_u8)); else found = NULL; if (found) { r = bus_match_run(bus, found, m); if (r != 0) return r; } } else { struct bus_match_node *c; /* 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)) continue; r = bus_match_run(bus, c, m); if (r != 0) return r; } } if (bus && bus->match_callbacks_modified) return 0; /* And now, let's invoke our siblings */ return bus_match_run(bus, node->next, m); }