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 _public_
int sd_bus_get_unique_name(sd_bus
*bus
, const char **unique
) {
41 assert_return(bus
, -EINVAL
);
42 assert_return(unique
, -EINVAL
);
43 assert_return(!bus_pid_changed(bus
), -ECHILD
);
45 r
= bus_ensure_running(bus
);
49 *unique
= bus
->unique_name
;
53 static int bus_request_name_kernel(sd_bus
*bus
, const char *name
, unsigned flags
) {
54 struct kdbus_cmd_name
*n
;
62 n
= alloca0(offsetof(struct kdbus_cmd_name
, name
) + l
+ 1);
63 n
->size
= offsetof(struct kdbus_cmd_name
, name
) + l
+ 1;
64 kdbus_translate_request_name_flags(flags
, (uint64_t *) &n
->flags
);
65 memcpy(n
->name
, name
, l
+1);
67 #ifdef HAVE_VALGRIND_MEMCHECK_H
68 VALGRIND_MAKE_MEM_DEFINED(n
, n
->size
);
71 r
= ioctl(bus
->input_fd
, KDBUS_CMD_NAME_ACQUIRE
, n
);
75 if (n
->flags
& KDBUS_NAME_IN_QUEUE
)
81 static int bus_request_name_dbus1(sd_bus
*bus
, const char *name
, unsigned flags
) {
82 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
89 r
= sd_bus_call_method(
91 "org.freedesktop.DBus",
93 "org.freedesktop.DBus",
103 r
= sd_bus_message_read(reply
, "u", &ret
);
107 if (ret
== SD_BUS_NAME_ALREADY_OWNER
)
109 else if (ret
== SD_BUS_NAME_EXISTS
)
111 else if (ret
== SD_BUS_NAME_IN_QUEUE
)
119 _public_
int sd_bus_request_name(sd_bus
*bus
, const char *name
, unsigned flags
) {
120 assert_return(bus
, -EINVAL
);
121 assert_return(name
, -EINVAL
);
122 assert_return(bus
->bus_client
, -EINVAL
);
123 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
124 assert_return(!bus_pid_changed(bus
), -ECHILD
);
125 assert_return(!(flags
& ~(SD_BUS_NAME_ALLOW_REPLACEMENT
|SD_BUS_NAME_REPLACE_EXISTING
|SD_BUS_NAME_DO_NOT_QUEUE
)), -EINVAL
);
128 return bus_request_name_kernel(bus
, name
, flags
);
130 return bus_request_name_dbus1(bus
, name
, flags
);
133 static int bus_release_name_kernel(sd_bus
*bus
, const char *name
) {
134 struct kdbus_cmd_name
*n
;
142 n
= alloca0(offsetof(struct kdbus_cmd_name
, name
) + l
+ 1);
143 n
->size
= offsetof(struct kdbus_cmd_name
, name
) + l
+ 1;
144 memcpy(n
->name
, name
, l
+1);
146 #ifdef HAVE_VALGRIND_MEMCHECK_H
147 VALGRIND_MAKE_MEM_DEFINED(n
, n
->size
);
149 r
= ioctl(bus
->input_fd
, KDBUS_CMD_NAME_RELEASE
, n
);
156 static int bus_release_name_dbus1(sd_bus
*bus
, const char *name
) {
157 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
164 r
= sd_bus_call_method(
166 "org.freedesktop.DBus",
168 "org.freedesktop.DBus",
177 r
= sd_bus_message_read(reply
, "u", &ret
);
180 if (ret
== SD_BUS_NAME_NON_EXISTENT
)
182 if (ret
== SD_BUS_NAME_NOT_OWNER
)
183 return -EADDRNOTAVAIL
;
184 if (ret
== SD_BUS_NAME_RELEASED
)
190 _public_
int sd_bus_release_name(sd_bus
*bus
, const char *name
) {
191 assert_return(bus
, -EINVAL
);
192 assert_return(name
, -EINVAL
);
193 assert_return(bus
->bus_client
, -EINVAL
);
194 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
195 assert_return(!bus_pid_changed(bus
), -ECHILD
);
198 return bus_release_name_kernel(bus
, name
);
200 return bus_release_name_dbus1(bus
, name
);
203 static int bus_list_names_kernel(sd_bus
*bus
, char ***l
) {
204 _cleanup_free_
struct kdbus_cmd_name_list
*cmd
= NULL
;
205 struct kdbus_name_list
*name_list
;
206 struct kdbus_cmd_name
*name
;
210 cmd
= malloc0(sizeof(struct kdbus_cmd_name_list
));
214 cmd
->size
= sizeof(struct kdbus_cmd_name_list
);
215 cmd
->flags
= KDBUS_NAME_LIST_UNIQUE
| KDBUS_NAME_LIST_NAMES
;
217 r
= ioctl(sd_bus_get_fd(bus
), KDBUS_CMD_NAME_LIST
, cmd
);
221 name_list
= (struct kdbus_name_list
*) ((uint8_t *) bus
->kdbus_buffer
+ cmd
->offset
);
223 KDBUS_PART_FOREACH(name
, name_list
, names
) {
226 if (name
->size
> sizeof(*name
))
229 asprintf(&n
, ":1.%llu", (unsigned long long) name
->id
);
231 r
= strv_extend(&x
, n
);
236 r
= ioctl(sd_bus_get_fd(bus
), KDBUS_CMD_FREE
, &cmd
->offset
);
244 static int bus_list_names_dbus1(sd_bus
*bus
, char ***l
) {
245 _cleanup_bus_message_unref_ sd_bus_message
*reply1
= NULL
, *reply2
= NULL
;
249 r
= sd_bus_call_method(
251 "org.freedesktop.DBus",
253 "org.freedesktop.DBus",
261 r
= sd_bus_call_method(
263 "org.freedesktop.DBus",
265 "org.freedesktop.DBus",
266 "ListActivatableNames",
273 r
= bus_message_read_strv_extend(reply1
, &x
);
279 r
= bus_message_read_strv_extend(reply2
, &x
);
289 _public_
int sd_bus_list_names(sd_bus
*bus
, char ***l
) {
290 assert_return(bus
, -EINVAL
);
291 assert_return(l
, -EINVAL
);
292 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
293 assert_return(!bus_pid_changed(bus
), -ECHILD
);
296 return bus_list_names_kernel(bus
, l
);
298 return bus_list_names_dbus1(bus
, l
);
301 static int bus_get_owner_kdbus(
305 sd_bus_creds
**creds
) {
307 _cleanup_bus_creds_unref_ sd_bus_creds
*c
= NULL
;
308 struct kdbus_cmd_conn_info
*cmd
;
309 struct kdbus_conn_info
*conn_info
;
310 struct kdbus_item
*item
;
315 r
= bus_kernel_parse_unique_name(name
, &id
);
319 size
= offsetof(struct kdbus_cmd_conn_info
, name
);
323 size
= offsetof(struct kdbus_cmd_conn_info
, name
) + strlen(name
) + 1;
325 strcpy(cmd
->name
, name
);
329 r
= ioctl(bus
->input_fd
, KDBUS_CMD_CONN_INFO
, cmd
);
333 conn_info
= (struct kdbus_conn_info
*) ((uint8_t *) bus
->kdbus_buffer
+ cmd
->offset
);
339 if (mask
& SD_BUS_CREDS_UNIQUE_NAME
) {
340 if (asprintf(&c
->unique_name
, ":1.%llu", (unsigned long long) conn_info
->id
) < 0)
343 c
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
346 KDBUS_PART_FOREACH(item
, conn_info
, items
) {
348 switch (item
->type
) {
350 case KDBUS_ITEM_CREDS
:
351 m
= (SD_BUS_CREDS_UID
| SD_BUS_CREDS_GID
| SD_BUS_CREDS_PID
|
352 SD_BUS_CREDS_TID
| SD_BUS_CREDS_PID_STARTTIME
) & mask
;
355 c
->uid
= item
->creds
.uid
;
356 c
->pid
= item
->creds
.pid
;
357 c
->gid
= item
->creds
.gid
;
358 c
->tid
= item
->creds
.tid
;
359 c
->pid_starttime
= item
->creds
.starttime
;
364 case KDBUS_ITEM_PID_COMM
:
365 if (mask
& SD_BUS_CREDS_COMM
) {
366 c
->comm
= strdup(item
->str
);
372 c
->mask
|= SD_BUS_CREDS_COMM
;
376 case KDBUS_ITEM_TID_COMM
:
377 if (mask
& SD_BUS_CREDS_TID_COMM
) {
378 c
->tid_comm
= strdup(item
->str
);
384 c
->mask
|= SD_BUS_CREDS_TID_COMM
;
389 if (mask
& SD_BUS_CREDS_EXE
) {
390 c
->exe
= strdup(item
->str
);
396 c
->mask
|= SD_BUS_CREDS_EXE
;
400 case KDBUS_ITEM_CMDLINE
:
401 if (mask
& SD_BUS_CREDS_CMDLINE
) {
402 c
->cmdline_size
= item
->size
- KDBUS_PART_HEADER_SIZE
;
403 c
->cmdline
= memdup(item
->data
, c
->cmdline_size
);
409 c
->mask
|= SD_BUS_CREDS_CMDLINE
;
413 case KDBUS_ITEM_CGROUP
:
414 m
= (SD_BUS_CREDS_CGROUP
| SD_BUS_CREDS_UNIT
|
415 SD_BUS_CREDS_USER_UNIT
| SD_BUS_CREDS_SLICE
|
416 SD_BUS_CREDS_SESSION
| SD_BUS_CREDS_OWNER_UID
) & mask
;
419 c
->cgroup
= strdup(item
->str
);
429 case KDBUS_ITEM_CAPS
:
430 m
= (SD_BUS_CREDS_EFFECTIVE_CAPS
| SD_BUS_CREDS_PERMITTED_CAPS
|
431 SD_BUS_CREDS_INHERITABLE_CAPS
| SD_BUS_CREDS_BOUNDING_CAPS
) & mask
;
434 c
->capability_size
= item
->size
- KDBUS_PART_HEADER_SIZE
;
435 c
->capability
= memdup(item
->data
, c
->capability_size
);
436 if (!c
->capability
) {
445 case KDBUS_ITEM_SECLABEL
:
446 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
447 c
->label
= strdup(item
->str
);
453 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
457 case KDBUS_ITEM_AUDIT
:
458 m
= (SD_BUS_CREDS_AUDIT_SESSION_ID
| SD_BUS_CREDS_AUDIT_LOGIN_UID
) & mask
;
461 c
->audit_session_id
= item
->audit
.sessionid
;
462 c
->audit_login_uid
= item
->audit
.loginuid
;
467 case KDBUS_ITEM_NAMES
:
468 if (mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
469 c
->well_known_names_size
= item
->size
- KDBUS_PART_HEADER_SIZE
;
470 c
->well_known_names
= memdup(item
->data
, c
->well_known_names_size
);
471 if (!c
->well_known_names
) {
476 c
->mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
490 ioctl(bus
->input_fd
, KDBUS_CMD_FREE
, &cmd
->offset
);
494 static int bus_get_owner_dbus1(
498 sd_bus_creds
**creds
) {
500 _cleanup_bus_message_unref_ sd_bus_message
*reply_unique
= NULL
, *reply
= NULL
;
501 _cleanup_bus_creds_unref_ sd_bus_creds
*c
= NULL
;
502 const char *unique
= NULL
;
506 /* Only query the owner if the caller wants to know it or if
507 * the caller just wants to check whether a name exists */
508 if ((mask
& SD_BUS_CREDS_UNIQUE_NAME
) || mask
== 0) {
509 r
= sd_bus_call_method(
511 "org.freedesktop.DBus",
513 "org.freedesktop.DBus",
522 r
= sd_bus_message_read(reply_unique
, "s", &unique
);
532 if ((mask
& SD_BUS_CREDS_UNIQUE_NAME
) && unique
) {
533 c
->unique_name
= strdup(unique
);
537 c
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
540 if (mask
& (SD_BUS_CREDS_PID
|SD_BUS_CREDS_PID_STARTTIME
|SD_BUS_CREDS_GID
|
541 SD_BUS_CREDS_COMM
|SD_BUS_CREDS_EXE
|SD_BUS_CREDS_CMDLINE
|
542 SD_BUS_CREDS_CGROUP
|SD_BUS_CREDS_UNIT
|SD_BUS_CREDS_USER_UNIT
|SD_BUS_CREDS_SLICE
|SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_OWNER_UID
|
543 SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
|
544 SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
)) {
547 r
= sd_bus_call_method(
549 "org.freedesktop.DBus",
551 "org.freedesktop.DBus",
552 "GetConnectionUnixProcessID",
556 unique
? unique
: name
);
560 r
= sd_bus_message_read(reply
, "u", &u
);
565 if (mask
& SD_BUS_CREDS_PID
) {
567 c
->mask
|= SD_BUS_CREDS_PID
;
570 reply
= sd_bus_message_unref(reply
);
573 if (mask
& SD_BUS_CREDS_UID
) {
576 r
= sd_bus_call_method(
578 "org.freedesktop.DBus",
580 "org.freedesktop.DBus",
581 "GetConnectionUnixUser",
585 unique
? unique
: name
);
589 r
= sd_bus_message_read(reply
, "u", &u
);
594 c
->mask
|= SD_BUS_CREDS_UID
;
596 reply
= sd_bus_message_unref(reply
);
599 if (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
603 r
= sd_bus_call_method(
605 "org.freedesktop.DBus",
607 "org.freedesktop.DBus",
608 "GetConnectionSELinuxSecurityContext",
612 unique
? unique
: name
);
616 r
= sd_bus_message_read_array(reply
, 'y', &p
, &sz
);
620 c
->label
= strndup(p
, sz
);
624 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
627 r
= bus_creds_add_more(c
, mask
, pid
, 0);
640 _public_
int sd_bus_get_owner(
644 sd_bus_creds
**creds
) {
646 assert_return(bus
, -EINVAL
);
647 assert_return(name
, -EINVAL
);
648 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -ENOTSUP
);
649 assert_return(mask
== 0 || creds
, -EINVAL
);
650 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
651 assert_return(!bus_pid_changed(bus
), -ECHILD
);
654 return bus_get_owner_kdbus(bus
, name
, mask
, creds
);
656 return bus_get_owner_dbus1(bus
, name
, mask
, creds
);
659 static int add_name_change_match(sd_bus
*bus
,
662 const char *old_owner
,
663 const char *new_owner
) {
665 uint64_t name_id
= 0, old_owner_id
= 0, new_owner_id
= 0;
666 int is_name_id
= -1, r
;
667 struct kdbus_item
*item
;
671 /* If we encounter a match that could match against
672 * NameOwnerChanged messages, then we need to create
673 * KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE} and
674 * KDBUS_MATCH_ID_{ADD,REMOVE} matches for it, possibly
675 * multiple if the match is underspecified.
677 * The NameOwnerChanged signals take three parameters with
678 * unique or well-known names, but only some forms actually
681 * WELLKNOWN, "", UNIQUE → KDBUS_MATCH_NAME_ADD
682 * WELLKNOWN, UNIQUE, "" → KDBUS_MATCH_NAME_REMOVE
683 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_MATCH_NAME_CHANGE
684 * UNIQUE, "", UNIQUE → KDBUS_MATCH_ID_ADD
685 * UNIQUE, UNIQUE, "" → KDBUS_MATCH_ID_REMOVE
687 * For the latter two the two unique names must be identical.
692 is_name_id
= bus_kernel_parse_unique_name(name
, &name_id
);
698 r
= bus_kernel_parse_unique_name(old_owner
, &old_owner_id
);
703 if (is_name_id
> 0 && old_owner_id
!= name_id
)
708 r
= bus_kernel_parse_unique_name(new_owner
, &new_owner_id
);
713 if (is_name_id
> 0 && new_owner_id
!= name_id
)
717 if (is_name_id
<= 0) {
718 struct kdbus_cmd_match
*m
;
721 /* If the name argument is missing or is a well-known
722 * name, then add KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE}
725 l
= name
? strlen(name
) : 0;
727 sz
= ALIGN8(offsetof(struct kdbus_cmd_match
, items
) +
728 offsetof(struct kdbus_item
, name_change
) +
729 offsetof(struct kdbus_notify_name_change
, name
) +
735 m
->src_id
= KDBUS_SRC_ID_KERNEL
;
739 offsetof(struct kdbus_item
, name_change
) +
740 offsetof(struct kdbus_notify_name_change
, name
) +
743 item
->name_change
.old_id
= old_owner_id
;
744 item
->name_change
.new_id
= new_owner_id
;
747 strcpy(item
->name_change
.name
, name
);
749 /* If the old name is unset or empty, then
750 * this can match against added names */
751 if (!old_owner
|| old_owner
[0] == 0) {
752 item
->type
= KDBUS_MATCH_NAME_ADD
;
754 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
759 /* If the new name is unset or empty, then
760 * this can match against removed names */
761 if (!new_owner
|| new_owner
[0] == 0) {
762 item
->type
= KDBUS_MATCH_NAME_REMOVE
;
764 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
769 /* If the neither name is explicitly set to
770 * the empty string, then this can match
771 * agains changed names */
772 if (!(old_owner
&& old_owner
[0] == 0) &&
773 !(new_owner
&& new_owner
[0] == 0)) {
774 item
->type
= KDBUS_MATCH_NAME_CHANGE
;
776 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
782 if (is_name_id
!= 0) {
783 struct kdbus_cmd_match
*m
;
786 /* If the name argument is missing or is a unique
787 * name, then add KDBUS_MATCH_ID_{ADD,REMOVE} matches
790 sz
= ALIGN8(offsetof(struct kdbus_cmd_match
, items
) +
791 offsetof(struct kdbus_item
, id_change
) +
792 sizeof(struct kdbus_notify_id_change
));
797 m
->src_id
= KDBUS_SRC_ID_KERNEL
;
800 item
->size
= offsetof(struct kdbus_item
, id_change
) + sizeof(struct kdbus_notify_id_change
);
801 item
->id_change
.id
= name_id
;
803 /* If the old name is unset or empty, then this can
804 * match against added ids */
805 if (!old_owner
|| old_owner
[0] == 0) {
806 item
->type
= KDBUS_MATCH_ID_ADD
;
808 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
813 /* If thew new name is unset or empty, then this can
814 match against removed ids */
815 if (!new_owner
|| new_owner
[0] == 0) {
816 item
->type
= KDBUS_MATCH_ID_REMOVE
;
818 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
827 static int bus_add_match_internal_kernel(
830 struct bus_match_component
*components
,
831 unsigned n_components
,
834 struct kdbus_cmd_match
*m
;
835 struct kdbus_item
*item
;
836 uint64_t bloom
[BLOOM_SIZE
/8];
838 const char *sender
= NULL
;
839 size_t sender_length
= 0;
840 uint64_t src_id
= KDBUS_MATCH_SRC_ID_ANY
;
841 bool using_bloom
= false;
843 bool matches_name_change
= true;
844 const char *name_change_arg
[3] = {};
852 sz
= offsetof(struct kdbus_cmd_match
, items
);
854 for (i
= 0; i
< n_components
; i
++) {
855 struct bus_match_component
*c
= &components
[i
];
859 case BUS_MATCH_SENDER
:
860 if (!streq(c
->value_str
, "org.freedesktop.DBus"))
861 matches_name_change
= false;
863 r
= bus_kernel_parse_unique_name(c
->value_str
, &src_id
);
868 sender
= c
->value_str
;
869 sender_length
= strlen(sender
);
870 sz
+= ALIGN8(offsetof(struct kdbus_item
, str
) + sender_length
+ 1);
875 case BUS_MATCH_MESSAGE_TYPE
:
876 if (c
->value_u8
!= SD_BUS_MESSAGE_SIGNAL
)
877 matches_name_change
= false;
879 bloom_add_pair(bloom
, "message-type", bus_message_type_to_string(c
->value_u8
));
883 case BUS_MATCH_INTERFACE
:
884 if (!streq(c
->value_str
, "org.freedesktop.DBus"))
885 matches_name_change
= false;
887 bloom_add_pair(bloom
, "interface", c
->value_str
);
891 case BUS_MATCH_MEMBER
:
892 if (!streq(c
->value_str
, "NameOwnerChanged"))
893 matches_name_change
= false;
895 bloom_add_pair(bloom
, "member", c
->value_str
);
900 if (!streq(c
->value_str
, "/org/freedesktop/DBus"))
901 matches_name_change
= false;
903 bloom_add_pair(bloom
, "path", c
->value_str
);
907 case BUS_MATCH_PATH_NAMESPACE
:
908 if (!streq(c
->value_str
, "/")) {
909 bloom_add_pair(bloom
, "path-slash-prefix", c
->value_str
);
914 case BUS_MATCH_ARG
...BUS_MATCH_ARG_LAST
: {
915 char buf
[sizeof("arg")-1 + 2 + 1];
917 if (c
->type
- BUS_MATCH_ARG
< 3)
918 name_change_arg
[c
->type
- BUS_MATCH_ARG
] = c
->value_str
;
920 snprintf(buf
, sizeof(buf
), "arg%u", c
->type
- BUS_MATCH_ARG
);
921 bloom_add_pair(bloom
, buf
, c
->value_str
);
926 case BUS_MATCH_ARG_PATH
...BUS_MATCH_ARG_PATH_LAST
: {
927 char buf
[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
929 snprintf(buf
, sizeof(buf
), "arg%u-slash-prefix", c
->type
- BUS_MATCH_ARG_PATH
);
930 bloom_add_pair(bloom
, buf
, c
->value_str
);
935 case BUS_MATCH_ARG_NAMESPACE
...BUS_MATCH_ARG_NAMESPACE_LAST
: {
936 char buf
[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
938 snprintf(buf
, sizeof(buf
), "arg%u-dot-prefix", c
->type
- BUS_MATCH_ARG_NAMESPACE
);
939 bloom_add_pair(bloom
, buf
, c
->value_str
);
944 case BUS_MATCH_DESTINATION
:
945 /* The bloom filter does not include
946 the destination, since it is only
947 available for broadcast messages
948 which do not carry a destination
949 since they are undirected. */
953 case BUS_MATCH_VALUE
:
955 case _BUS_MATCH_NODE_TYPE_MAX
:
956 case _BUS_MATCH_NODE_TYPE_INVALID
:
957 assert_not_reached("Invalid match type?");
962 sz
+= ALIGN8(offsetof(struct kdbus_item
, data64
) + BLOOM_SIZE
);
972 item
->size
= offsetof(struct kdbus_item
, data64
) + BLOOM_SIZE
;
973 item
->type
= KDBUS_MATCH_BLOOM
;
974 memcpy(item
->data64
, bloom
, BLOOM_SIZE
);
976 item
= KDBUS_PART_NEXT(item
);
980 item
->size
= offsetof(struct kdbus_item
, str
) + sender_length
+ 1;
981 item
->type
= KDBUS_MATCH_SRC_NAME
;
982 memcpy(item
->str
, sender
, sender_length
+ 1);
985 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_ADD
, m
);
989 if (matches_name_change
) {
991 /* If this match could theoretically match
992 * NameOwnerChanged messages, we need to
993 * install a second non-bloom filter explitly
996 r
= add_name_change_match(bus
, cookie
, name_change_arg
[0], name_change_arg
[1], name_change_arg
[2]);
1004 static int bus_add_match_internal_dbus1(
1006 const char *match
) {
1011 return sd_bus_call_method(
1013 "org.freedesktop.DBus",
1015 "org.freedesktop.DBus",
1023 int bus_add_match_internal(
1026 struct bus_match_component
*components
,
1027 unsigned n_components
,
1034 return bus_add_match_internal_kernel(bus
, match
, components
, n_components
, cookie
);
1036 return bus_add_match_internal_dbus1(bus
, match
);
1039 static int bus_remove_match_internal_kernel(
1044 struct kdbus_cmd_match m
;
1051 m
.size
= offsetof(struct kdbus_cmd_match
, items
);
1054 r
= ioctl(bus
->input_fd
, KDBUS_CMD_MATCH_REMOVE
, &m
);
1061 static int bus_remove_match_internal_dbus1(
1063 const char *match
) {
1068 return sd_bus_call_method(
1070 "org.freedesktop.DBus",
1072 "org.freedesktop.DBus",
1080 int bus_remove_match_internal(
1089 return bus_remove_match_internal_kernel(bus
, match
, cookie
);
1091 return bus_remove_match_internal_dbus1(bus
, match
);
1094 _public_
int sd_bus_get_owner_machine_id(sd_bus
*bus
, const char *name
, sd_id128_t
*machine
) {
1095 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
1099 assert_return(bus
, -EINVAL
);
1100 assert_return(name
, -EINVAL
);
1101 assert_return(machine
, -EINVAL
);
1102 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
1103 assert_return(!bus_pid_changed(bus
), -ECHILD
);
1105 if (streq_ptr(name
, bus
->unique_name
))
1106 return sd_id128_get_machine(machine
);
1108 r
= sd_bus_message_new_method_call(
1112 "org.freedesktop.DBus.Peer",
1113 "GetMachineId", &m
);
1117 r
= sd_bus_message_set_no_auto_start(m
, true);
1121 r
= sd_bus_call(bus
, m
, 0, NULL
, &reply
);
1125 r
= sd_bus_message_read(reply
, "s", &mid
);
1129 return sd_id128_from_string(mid
, machine
);