1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-control.h"
35 #include "bus-bloom.h"
38 int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
45 if (bus_pid_changed(bus))
48 r = bus_ensure_running(bus);
52 *unique = bus->unique_name;
56 int sd_bus_request_name(sd_bus *bus, const char *name, int flags) {
57 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
67 if (!BUS_IS_OPEN(bus->state))
69 if (bus_pid_changed(bus))
73 struct kdbus_cmd_name *n;
77 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
78 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
80 memcpy(n->name, name, l+1);
82 #ifdef HAVE_VALGRIND_MEMCHECK_H
83 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
86 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
92 r = sd_bus_call_method(
94 "org.freedesktop.DBus",
96 "org.freedesktop.DBus",
106 r = sd_bus_message_read(reply, "u", &ret);
114 int sd_bus_release_name(sd_bus *bus, const char *name) {
115 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
123 if (!bus->bus_client)
125 if (!BUS_IS_OPEN(bus->state))
127 if (bus_pid_changed(bus))
130 if (bus->is_kernel) {
131 struct kdbus_cmd_name *n;
135 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
136 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
137 memcpy(n->name, name, l+1);
139 #ifdef HAVE_VALGRIND_MEMCHECK_H
140 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
142 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
148 r = sd_bus_call_method(
150 "org.freedesktop.DBus",
152 "org.freedesktop.DBus",
161 r = sd_bus_message_read(reply, "u", &ret);
169 int sd_bus_list_names(sd_bus *bus, char ***l) {
170 _cleanup_bus_message_unref_ sd_bus_message *reply1 = NULL, *reply2 = NULL;
178 if (!BUS_IS_OPEN(bus->state))
180 if (bus_pid_changed(bus))
183 r = sd_bus_call_method(
185 "org.freedesktop.DBus",
187 "org.freedesktop.DBus",
195 r = sd_bus_call_method(
197 "org.freedesktop.DBus",
199 "org.freedesktop.DBus",
200 "ListActivatableNames",
207 r = bus_message_read_strv_extend(reply1, &x);
213 r = bus_message_read_strv_extend(reply2, &x);
223 int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
224 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
232 if (!BUS_IS_OPEN(bus->state))
234 if (bus_pid_changed(bus))
237 r = sd_bus_call_method(
239 "org.freedesktop.DBus",
241 "org.freedesktop.DBus",
250 r = sd_bus_message_read(reply, "s", &found);
267 int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
268 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
278 if (!BUS_IS_OPEN(bus->state))
280 if (bus_pid_changed(bus))
283 r = sd_bus_call_method(
285 "org.freedesktop.DBus",
287 "org.freedesktop.DBus",
288 "GetConnectionUnixUser",
296 r = sd_bus_message_read(reply, "u", &u);
304 int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
305 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
315 if (!BUS_IS_OPEN(bus->state))
317 if (bus_pid_changed(bus))
320 r = sd_bus_call_method(
322 "org.freedesktop.DBus",
324 "org.freedesktop.DBus",
325 "GetConnectionUnixProcessID",
333 r = sd_bus_message_read(reply, "u", &u);
344 int bus_add_match_internal(
347 struct bus_match_component *components,
348 unsigned n_components,
356 if (bus->is_kernel) {
357 struct kdbus_cmd_match *m;
358 struct kdbus_item *item;
359 uint64_t bloom[BLOOM_SIZE/8];
361 const char *sender = NULL;
362 size_t sender_length = 0;
363 uint64_t src_id = KDBUS_MATCH_SRC_ID_ANY;
364 bool using_bloom = false;
369 sz = offsetof(struct kdbus_cmd_match, items);
371 for (i = 0; i < n_components; i++) {
372 struct bus_match_component *c = &components[i];
376 case BUS_MATCH_SENDER:
377 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
382 sender = c->value_str;
383 sender_length = strlen(sender);
384 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
389 case BUS_MATCH_MESSAGE_TYPE:
390 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8));
394 case BUS_MATCH_INTERFACE:
395 bloom_add_pair(bloom, "interface", c->value_str);
399 case BUS_MATCH_MEMBER:
400 bloom_add_pair(bloom, "member", c->value_str);
405 bloom_add_pair(bloom, "path", c->value_str);
409 case BUS_MATCH_PATH_NAMESPACE:
410 if (!streq(c->value_str, "/")) {
411 bloom_add_pair(bloom, "path-slash-prefix", c->value_str);
416 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
417 char buf[sizeof("arg")-1 + 2 + 1];
419 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
420 bloom_add_pair(bloom, buf, c->value_str);
425 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
426 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
428 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
429 bloom_add_pair(bloom, buf, c->value_str);
434 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
435 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
437 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
438 bloom_add_pair(bloom, buf, c->value_str);
443 case BUS_MATCH_DESTINATION:
444 /* The bloom filter does not include
445 the destination, since it is only
446 available for broadcast messages
447 which do not carry a destination
448 since they are undirected. */
452 case BUS_MATCH_VALUE:
454 case _BUS_MATCH_NODE_TYPE_MAX:
455 case _BUS_MATCH_NODE_TYPE_INVALID:
456 assert_not_reached("Invalid match type?");
461 sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE);
471 item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE;
472 item->type = KDBUS_MATCH_BLOOM;
473 memcpy(item->data64, bloom, BLOOM_SIZE);
475 item = KDBUS_ITEM_NEXT(item);
479 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
480 item->type = KDBUS_MATCH_SRC_NAME;
481 memcpy(item->str, sender, sender_length + 1);
484 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
489 return sd_bus_call_method(
491 "org.freedesktop.DBus",
493 "org.freedesktop.DBus",
504 int bus_remove_match_internal(
514 if (bus->is_kernel) {
515 struct kdbus_cmd_match m;
518 m.size = offsetof(struct kdbus_cmd_match, items);
521 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
526 return sd_bus_call_method(
528 "org.freedesktop.DBus",
530 "org.freedesktop.DBus",
541 int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
542 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
550 if (!BUS_IS_OPEN(bus->state))
552 if (bus_pid_changed(bus))
555 if (streq_ptr(name, bus->unique_name))
556 return sd_id128_get_machine(machine);
558 r = sd_bus_call_method(bus,
561 "org.freedesktop.DBus.Peer",
570 r = sd_bus_message_read(reply, "s", &mid);
574 return sd_id128_from_string(mid, machine);