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/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message
*m
, char type
, const void *p
, const void **stored
);
40 static void *adjust_pointer(const void *p
, void *old_base
, size_t sz
, void *new_base
) {
45 if (old_base
== new_base
)
48 if ((uint8_t*) p
< (uint8_t*) old_base
)
51 if ((uint8_t*) p
>= (uint8_t*) old_base
+ sz
)
54 return (uint8_t*) new_base
+ ((uint8_t*) p
- (uint8_t*) old_base
);
57 static void message_free_part(sd_bus_message
*m
, struct bus_body_part
*part
) {
61 if (part
->memfd
>= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m
->bus
, part
->memfd
, part
->data
, part
->mapped
);
69 assert_se(munmap(part
->data
, part
->mapped
) == 0);
71 close_nointr_nofail(part
->memfd
);
74 } else if (part
->munmap_this
)
75 munmap(part
->data
, part
->mapped
);
76 else if (part
->free_this
)
83 static void message_reset_parts(sd_bus_message
*m
) {
84 struct bus_body_part
*part
;
89 while (m
->n_body_parts
> 0) {
90 struct bus_body_part
*next
= part
->next
;
91 message_free_part(m
, part
);
98 m
->cached_rindex_part
= NULL
;
99 m
->cached_rindex_part_begin
= 0;
102 static void message_reset_containers(sd_bus_message
*m
) {
107 for (i
= 0; i
< m
->n_containers
; i
++)
108 free(m
->containers
[i
].signature
);
111 m
->containers
= NULL
;
114 m
->root_container
.index
= 0;
117 static void message_free(sd_bus_message
*m
) {
123 message_reset_parts(m
);
128 if (m
->release_kdbus
)
129 ioctl(m
->bus
->input_fd
, KDBUS_CMD_MSG_RELEASE
, m
->kdbus
);
132 sd_bus_unref(m
->bus
);
135 close_many(m
->fds
, m
->n_fds
);
139 if (m
->iovec
!= m
->iovec_fixed
)
142 free(m
->cmdline_array
);
144 message_reset_containers(m
);
145 free(m
->root_container
.signature
);
147 free(m
->peeked_signature
);
155 static void *message_extend_fields(sd_bus_message
*m
, size_t align
, size_t sz
) {
157 size_t old_size
, new_size
, start
;
164 old_size
= sizeof(struct bus_header
) + m
->header
->fields_size
;
165 start
= ALIGN_TO(old_size
, align
);
166 new_size
= start
+ sz
;
168 if (old_size
== new_size
)
169 return (uint8_t*) m
->header
+ old_size
;
171 if (new_size
> (size_t) ((uint32_t) -1))
174 if (m
->free_header
) {
175 np
= realloc(m
->header
, ALIGN8(new_size
));
179 /* Initially, the header is allocated as part of of
180 * the sd_bus_message itself, let's replace it by
183 np
= malloc(ALIGN8(new_size
));
187 memcpy(np
, m
->header
, sizeof(struct bus_header
));
190 /* Zero out padding */
191 if (start
> old_size
)
192 memset((uint8_t*) np
+ old_size
, 0, start
- old_size
);
196 m
->header
->fields_size
= new_size
- sizeof(struct bus_header
);
198 /* Adjust quick access pointers */
199 m
->path
= adjust_pointer(m
->path
, op
, old_size
, m
->header
);
200 m
->interface
= adjust_pointer(m
->interface
, op
, old_size
, m
->header
);
201 m
->member
= adjust_pointer(m
->member
, op
, old_size
, m
->header
);
202 m
->destination
= adjust_pointer(m
->destination
, op
, old_size
, m
->header
);
203 m
->sender
= adjust_pointer(m
->sender
, op
, old_size
, m
->header
);
204 m
->error
.name
= adjust_pointer(m
->error
.name
, op
, old_size
, m
->header
);
206 m
->free_header
= true;
208 return (uint8_t*) np
+ start
;
215 static int message_append_field_string(
228 if (l
> (size_t) (uint32_t) -1)
231 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232 p
= message_extend_fields(m
, 8, 4 + 4 + l
+ 1);
241 ((uint32_t*) p
)[1] = l
;
242 memcpy(p
+ 8, s
, l
+ 1);
245 *ret
= (char*) p
+ 8;
250 static int message_append_field_signature(
265 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266 p
= message_extend_fields(m
, 8, 4 + 1 + l
+ 1);
272 p
[2] = SD_BUS_TYPE_SIGNATURE
;
275 memcpy(p
+ 5, s
, l
+ 1);
278 *ret
= (const char*) p
+ 5;
283 static int message_append_field_uint32(sd_bus_message
*m
, uint8_t h
, uint32_t x
) {
288 /* field id byte + signature length + signature 'u' + NUL + value */
289 p
= message_extend_fields(m
, 8, 4 + 4);
295 p
[2] = SD_BUS_TYPE_UINT32
;
298 ((uint32_t*) p
)[1] = x
;
303 int bus_message_from_header(
308 const struct ucred
*ucred
,
311 sd_bus_message
**ret
) {
314 struct bus_header
*h
;
317 assert(buffer
|| length
<= 0);
318 assert(fds
|| n_fds
<= 0);
321 if (length
< sizeof(struct bus_header
))
331 if (h
->type
== _SD_BUS_MESSAGE_TYPE_INVALID
)
334 if (h
->endian
!= SD_BUS_LITTLE_ENDIAN
&&
335 h
->endian
!= SD_BUS_BIG_ENDIAN
)
338 a
= ALIGN(sizeof(sd_bus_message
)) + ALIGN(extra
);
341 label_sz
= strlen(label
);
359 m
->uid_valid
= m
->gid_valid
= true;
363 m
->label
= (char*) m
+ ALIGN(sizeof(sd_bus_message
)) + ALIGN(extra
);
364 memcpy(m
->label
, label
, label_sz
+ 1);
371 int bus_message_from_malloc(
376 const struct ucred
*ucred
,
378 sd_bus_message
**ret
) {
383 r
= bus_message_from_header(buffer
, length
, fds
, n_fds
, ucred
, label
, 0, &m
);
387 if (length
!= BUS_MESSAGE_SIZE(m
)) {
393 m
->body
.data
= (uint8_t*) buffer
+ sizeof(struct bus_header
) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m
));
394 m
->body
.size
= length
- sizeof(struct bus_header
) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m
));
395 m
->body
.sealed
= true;
399 m
->iovec
= m
->iovec_fixed
;
400 m
->iovec
[0].iov_base
= buffer
;
401 m
->iovec
[0].iov_len
= length
;
403 r
= bus_message_parse_fields(m
);
407 /* We take possession of the memory and fds now */
408 m
->free_header
= true;
419 static sd_bus_message
*message_new(sd_bus
*bus
, uint8_t type
) {
422 m
= malloc0(ALIGN(sizeof(sd_bus_message
)) + sizeof(struct bus_header
));
427 m
->header
= (struct bus_header
*) ((uint8_t*) m
+ ALIGN(sizeof(struct sd_bus_message
)));
428 m
->header
->endian
= SD_BUS_NATIVE_ENDIAN
;
429 m
->header
->type
= type
;
430 m
->header
->version
= bus
? bus
->message_version
: 1;
431 m
->allow_fds
= !bus
|| bus
->can_fds
|| (bus
->state
!= BUS_HELLO
&& bus
->state
!= BUS_RUNNING
);
434 m
->bus
= sd_bus_ref(bus
);
439 int sd_bus_message_new_signal(
442 const char *interface
,
444 sd_bus_message
**m
) {
457 if (bus
&& bus
->state
== BUS_UNSET
)
460 t
= message_new(bus
, SD_BUS_MESSAGE_TYPE_SIGNAL
);
464 t
->header
->flags
|= SD_BUS_MESSAGE_NO_REPLY_EXPECTED
;
466 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_PATH
, SD_BUS_TYPE_OBJECT_PATH
, path
, &t
->path
);
469 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_INTERFACE
, SD_BUS_TYPE_STRING
, interface
, &t
->interface
);
472 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_MEMBER
, SD_BUS_TYPE_STRING
, member
, &t
->member
);
480 sd_bus_message_unref(t
);
484 int sd_bus_message_new_method_call(
486 const char *destination
,
488 const char *interface
,
490 sd_bus_message
**m
) {
501 if (bus
&& bus
->state
== BUS_UNSET
)
504 t
= message_new(bus
, SD_BUS_MESSAGE_TYPE_METHOD_CALL
);
508 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_PATH
, SD_BUS_TYPE_OBJECT_PATH
, path
, &t
->path
);
511 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_MEMBER
, SD_BUS_TYPE_STRING
, member
, &t
->member
);
516 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_INTERFACE
, SD_BUS_TYPE_STRING
, interface
, &t
->interface
);
522 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_DESTINATION
, SD_BUS_TYPE_STRING
, destination
, &t
->destination
);
535 static int message_new_reply(
537 sd_bus_message
*call
,
539 sd_bus_message
**m
) {
548 if (call
->header
->type
!= SD_BUS_MESSAGE_TYPE_METHOD_CALL
)
552 if (bus
&& bus
->state
== BUS_UNSET
)
555 t
= message_new(bus
, type
);
559 t
->header
->flags
|= SD_BUS_MESSAGE_NO_REPLY_EXPECTED
;
560 t
->reply_serial
= BUS_MESSAGE_SERIAL(call
);
562 r
= message_append_field_uint32(t
, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL
, t
->reply_serial
);
567 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_DESTINATION
, SD_BUS_TYPE_STRING
, call
->sender
, &t
->destination
);
572 t
->dont_send
= !!(call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
);
582 int sd_bus_message_new_method_return(
584 sd_bus_message
*call
,
585 sd_bus_message
**m
) {
587 return message_new_reply(bus
, call
, SD_BUS_MESSAGE_TYPE_METHOD_RETURN
, m
);
590 int sd_bus_message_new_method_error(
592 sd_bus_message
*call
,
593 const sd_bus_error
*e
,
594 sd_bus_message
**m
) {
599 if (!sd_bus_error_is_set(e
))
604 r
= message_new_reply(bus
, call
, SD_BUS_MESSAGE_TYPE_METHOD_ERROR
, &t
);
608 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_ERROR_NAME
, SD_BUS_TYPE_STRING
, e
->name
, &t
->error
.name
);
613 r
= message_append_basic(t
, SD_BUS_TYPE_STRING
, e
->message
, (const void**) &t
->error
.message
);
626 int bus_message_new_synthetic_error(
629 const sd_bus_error
*e
,
630 sd_bus_message
**m
) {
635 assert(sd_bus_error_is_set(e
));
638 t
= message_new(bus
, SD_BUS_MESSAGE_TYPE_METHOD_ERROR
);
642 t
->header
->flags
|= SD_BUS_MESSAGE_NO_REPLY_EXPECTED
;
643 t
->reply_serial
= serial
;
645 r
= message_append_field_uint32(t
, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL
, t
->reply_serial
);
649 if (bus
&& bus
->unique_name
) {
650 r
= message_append_field_string(t
, SD_BUS_MESSAGE_HEADER_DESTINATION
, SD_BUS_TYPE_STRING
, bus
->unique_name
, &t
->destination
);
663 sd_bus_message
* sd_bus_message_ref(sd_bus_message
*m
) {
667 assert(m
->n_ref
> 0);
673 sd_bus_message
* sd_bus_message_unref(sd_bus_message
*m
) {
677 assert(m
->n_ref
> 0);
686 int sd_bus_message_get_type(sd_bus_message
*m
, uint8_t *type
) {
692 *type
= m
->header
->type
;
696 int sd_bus_message_get_serial(sd_bus_message
*m
, uint64_t *serial
) {
701 if (m
->header
->serial
== 0)
704 *serial
= BUS_MESSAGE_SERIAL(m
);
708 int sd_bus_message_get_reply_serial(sd_bus_message
*m
, uint64_t *serial
) {
713 if (m
->reply_serial
== 0)
716 *serial
= m
->reply_serial
;
720 int sd_bus_message_get_no_reply(sd_bus_message
*m
) {
724 return m
->header
->type
== SD_BUS_MESSAGE_TYPE_METHOD_CALL
? !!(m
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
) : 0;
727 const char *sd_bus_message_get_path(sd_bus_message
*m
) {
734 const char *sd_bus_message_get_interface(sd_bus_message
*m
) {
741 const char *sd_bus_message_get_member(sd_bus_message
*m
) {
747 const char *sd_bus_message_get_destination(sd_bus_message
*m
) {
751 return m
->destination
;
754 const char *sd_bus_message_get_sender(sd_bus_message
*m
) {
761 const sd_bus_error
*sd_bus_message_get_error(sd_bus_message
*m
) {
765 if (!sd_bus_error_is_set(&m
->error
))
771 int sd_bus_message_get_uid(sd_bus_message
*m
, uid_t
*uid
) {
783 int sd_bus_message_get_gid(sd_bus_message
*m
, gid_t
*gid
) {
795 int sd_bus_message_get_pid(sd_bus_message
*m
, pid_t
*pid
) {
807 int sd_bus_message_get_tid(sd_bus_message
*m
, pid_t
*tid
) {
819 int sd_bus_message_get_pid_starttime(sd_bus_message
*m
, uint64_t *usec
) {
824 if (m
->pid_starttime
<= 0)
827 *usec
= m
->pid_starttime
;
831 int sd_bus_message_get_selinux_context(sd_bus_message
*m
, const char **ret
) {
841 int sd_bus_message_get_monotonic_timestamp(sd_bus_message
*m
, uint64_t *usec
) {
846 if (m
->monotonic
<= 0)
849 *usec
= m
->monotonic
;
853 int sd_bus_message_get_realtime_timestamp(sd_bus_message
*m
, uint64_t *usec
) {
858 if (m
->realtime
<= 0)
865 int sd_bus_message_get_comm(sd_bus_message
*m
, const char **ret
) {
877 int sd_bus_message_get_tid_comm(sd_bus_message
*m
, const char **ret
) {
889 int sd_bus_message_get_exe(sd_bus_message
*m
, const char **ret
) {
901 int sd_bus_message_get_cgroup(sd_bus_message
*m
, const char **ret
) {
913 int sd_bus_message_get_unit(sd_bus_message
*m
, const char **ret
) {
924 r
= cg_path_get_unit(m
->cgroup
, &m
->unit
);
933 int sd_bus_message_get_user_unit(sd_bus_message
*m
, const char **ret
) {
944 r
= cg_path_get_user_unit(m
->cgroup
, &m
->user_unit
);
953 int sd_bus_message_get_session(sd_bus_message
*m
, const char **ret
) {
964 r
= cg_path_get_session(m
->cgroup
, &m
->session
);
973 int sd_bus_message_get_owner_uid(sd_bus_message
*m
, uid_t
*uid
) {
981 return cg_path_get_owner_uid(m
->cgroup
, uid
);
984 int sd_bus_message_get_cmdline(sd_bus_message
*m
, char ***cmdline
) {
995 for (p
= m
->cmdline
, n
= 0; p
< m
->cmdline
+ m
->cmdline_length
; p
++)
999 m
->cmdline_array
= new(char*, n
+ 1);
1000 if (!m
->cmdline_array
)
1003 for (p
= m
->cmdline
, i
= 0, first
= true; p
< m
->cmdline
+ m
->cmdline_length
; p
++) {
1005 m
->cmdline_array
[i
++] = (char*) p
;
1010 m
->cmdline_array
[i
] = NULL
;
1011 *cmdline
= m
->cmdline_array
;
1016 int sd_bus_message_get_audit_sessionid(sd_bus_message
*m
, uint32_t *sessionid
) {
1024 *sessionid
= m
->audit
->sessionid
;
1028 int sd_bus_message_get_audit_loginuid(sd_bus_message
*m
, uid_t
*uid
) {
1036 *uid
= m
->audit
->loginuid
;
1040 int sd_bus_message_has_effective_cap(sd_bus_message
*m
, int capability
) {
1050 sz
= m
->capability_size
/ 4;
1051 if ((unsigned) capability
>= sz
*8)
1054 return !!(m
->capability
[2 * sz
+ (capability
/ 8)] & (1 << (capability
% 8)));
1057 int sd_bus_message_is_signal(sd_bus_message
*m
, const char *interface
, const char *member
) {
1061 if (m
->header
->type
!= SD_BUS_MESSAGE_TYPE_SIGNAL
)
1064 if (interface
&& (!m
->interface
|| !streq(m
->interface
, interface
)))
1067 if (member
&& (!m
->member
|| !streq(m
->member
, member
)))
1073 int sd_bus_message_is_method_call(sd_bus_message
*m
, const char *interface
, const char *member
) {
1077 if (m
->header
->type
!= SD_BUS_MESSAGE_TYPE_METHOD_CALL
)
1080 if (interface
&& (!m
->interface
|| !streq(m
->interface
, interface
)))
1083 if (member
&& (!m
->member
|| !streq(m
->member
, member
)))
1089 int sd_bus_message_is_method_error(sd_bus_message
*m
, const char *name
) {
1093 if (m
->header
->type
!= SD_BUS_MESSAGE_TYPE_METHOD_ERROR
)
1096 if (name
&& (!m
->error
.name
|| !streq(m
->error
.name
, name
)))
1102 int sd_bus_message_set_no_reply(sd_bus_message
*m
, int b
) {
1107 if (m
->header
->type
!= SD_BUS_MESSAGE_TYPE_METHOD_CALL
)
1111 m
->header
->flags
|= SD_BUS_MESSAGE_NO_REPLY_EXPECTED
;
1113 m
->header
->flags
&= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED
;
1118 static struct bus_container
*message_get_container(sd_bus_message
*m
) {
1121 if (m
->n_containers
== 0)
1122 return &m
->root_container
;
1124 assert(m
->containers
);
1125 return m
->containers
+ m
->n_containers
- 1;
1128 struct bus_body_part
*message_append_part(sd_bus_message
*m
) {
1129 struct bus_body_part
*part
;
1136 if (m
->n_body_parts
<= 0) {
1140 assert(m
->body_end
);
1142 part
= new0(struct bus_body_part
, 1);
1148 m
->body_end
->next
= part
;
1158 static void part_zero(struct bus_body_part
*part
, size_t sz
) {
1163 /* All other fields can be left in their defaults */
1164 assert(!part
->data
);
1165 assert(part
->memfd
< 0);
1168 part
->is_zero
= true;
1169 part
->sealed
= true;
1172 static int part_make_space(
1173 struct sd_bus_message
*m
,
1174 struct bus_body_part
*part
,
1183 assert(!part
->sealed
);
1188 if (!part
->data
&& part
->memfd
< 0)
1189 part
->memfd
= bus_kernel_pop_memfd(m
->bus
, &part
->data
, &part
->mapped
);
1191 if (part
->memfd
>= 0) {
1194 r
= ioctl(part
->memfd
, KDBUS_CMD_MEMFD_SIZE_SET
, &u
);
1200 if (!part
->data
|| sz
> part
->mapped
) {
1201 size_t psz
= PAGE_ALIGN(sz
> 0 ? sz
: 1);
1203 if (part
->mapped
<= 0)
1204 n
= mmap(NULL
, psz
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, part
->memfd
, 0);
1206 n
= mremap(part
->data
, part
->mapped
, psz
, MREMAP_MAYMOVE
);
1208 if (n
== MAP_FAILED
) {
1215 part
->munmap_this
= true;
1218 n
= realloc(part
->data
, sz
);
1225 part
->free_this
= true;
1229 *q
= part
->data
? (uint8_t*) part
->data
+ part
->size
: NULL
;
1235 static void message_extend_containers(sd_bus_message
*m
, size_t expand
) {
1236 struct bus_container
*c
;
1243 /* Update counters */
1244 for (c
= m
->containers
; c
< m
->containers
+ m
->n_containers
; c
++)
1246 *c
->array_size
+= expand
;
1249 static void *message_extend_body(sd_bus_message
*m
, size_t align
, size_t sz
) {
1250 struct bus_body_part
*part
= NULL
;
1251 size_t start_body
, end_body
, padding
, start_part
, end_part
, added
;
1263 start_body
= ALIGN_TO((size_t) m
->header
->body_size
, align
);
1264 end_body
= start_body
+ sz
;
1266 padding
= start_body
- m
->header
->body_size
;
1267 added
= padding
+ sz
;
1269 /* Check for 32bit overflows */
1270 if (end_body
> (size_t) ((uint32_t) -1)) {
1276 m
->n_body_parts
<= 0 ||
1277 m
->body_end
->sealed
||
1278 padding
!= ALIGN_TO(m
->body_end
->size
, align
) - m
->body_end
->size
;
1282 part
= message_append_part(m
);
1286 part_zero(part
, padding
);
1289 part
= message_append_part(m
);
1293 r
= part_make_space(m
, part
, sz
, &p
);
1297 struct bus_container
*c
;
1305 start_part
= ALIGN_TO(part
->size
, align
);
1306 end_part
= start_part
+ sz
;
1308 r
= part_make_space(m
, part
, end_part
, &p
);
1313 memset(p
, 0, padding
);
1314 p
= (uint8_t*) p
+ padding
;
1317 /* Readjust pointers */
1318 for (c
= m
->containers
; c
< m
->containers
+ m
->n_containers
; c
++)
1319 c
->array_size
= adjust_pointer(c
->array_size
, op
, os
, part
->data
);
1321 m
->error
.message
= (const char*) adjust_pointer(m
->error
.message
, op
, os
, part
->data
);
1324 m
->header
->body_size
= end_body
;
1325 message_extend_containers(m
, added
);
1330 int message_append_basic(sd_bus_message
*m
, char type
, const void *p
, const void **stored
) {
1331 struct bus_container
*c
;
1345 if (!bus_type_is_basic(type
))
1350 c
= message_get_container(m
);
1352 if (c
->signature
&& c
->signature
[c
->index
]) {
1353 /* Container signature is already set */
1355 if (c
->signature
[c
->index
] != type
)
1360 /* Maybe we can append to the signature? But only if this is the top-level container*/
1361 if (c
->enclosing
!= 0)
1364 e
= strextend(&c
->signature
, CHAR_TO_STR(type
), NULL
);
1373 case SD_BUS_TYPE_STRING
:
1374 case SD_BUS_TYPE_OBJECT_PATH
:
1377 sz
= 4 + strlen(p
) + 1;
1380 case SD_BUS_TYPE_SIGNATURE
:
1383 sz
= 1 + strlen(p
) + 1;
1386 case SD_BUS_TYPE_BOOLEAN
:
1389 assert_cc(sizeof(int) == sizeof(uint32_t));
1395 case SD_BUS_TYPE_UNIX_FD
: {
1398 if (!m
->allow_fds
) {
1411 fd
= fcntl(z
, F_DUPFD_CLOEXEC
, 3);
1417 f
= realloc(m
->fds
, sizeof(int) * (m
->n_fds
+ 1));
1432 align
= bus_type_get_alignment(type
);
1433 sz
= bus_type_get_size(type
);
1440 a
= message_extend_body(m
, align
, sz
);
1446 if (type
== SD_BUS_TYPE_STRING
|| type
== SD_BUS_TYPE_OBJECT_PATH
) {
1447 *(uint32_t*) a
= sz
- 5;
1448 memcpy((uint8_t*) a
+ 4, p
, sz
- 4);
1451 *stored
= (const uint8_t*) a
+ 4;
1453 } else if (type
== SD_BUS_TYPE_SIGNATURE
) {
1454 *(uint8_t*) a
= sz
- 1;
1455 memcpy((uint8_t*) a
+ 1, p
, sz
- 1);
1458 *stored
= (const uint8_t*) a
+ 1;
1459 } else if (type
== SD_BUS_TYPE_UNIX_FD
) {
1460 *(uint32_t*) a
= fdi
;
1474 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1481 close_nointr_nofail(fd
);
1486 int sd_bus_message_append_basic(sd_bus_message
*m
, char type
, const void *p
) {
1487 return message_append_basic(m
, type
, p
, NULL
);
1490 int sd_bus_message_append_string_space(sd_bus_message
*m
, size_t size
, char **s
) {
1491 struct bus_container
*c
;
1503 c
= message_get_container(m
);
1505 if (c
->signature
&& c
->signature
[c
->index
]) {
1506 /* Container signature is already set */
1508 if (c
->signature
[c
->index
] != SD_BUS_TYPE_STRING
)
1513 /* Maybe we can append to the signature? But only if this is the top-level container*/
1514 if (c
->enclosing
!= 0)
1517 e
= strextend(&c
->signature
, CHAR_TO_STR(SD_BUS_TYPE_STRING
), NULL
);
1524 a
= message_extend_body(m
, 4, 4 + size
+ 1);
1528 *(uint32_t*) a
= size
;
1533 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1539 static int bus_message_open_array(
1541 struct bus_container
*c
,
1542 const char *contents
,
1543 uint32_t **array_size
) {
1549 struct bus_body_part
*o
;
1556 if (!signature_is_single(contents
))
1559 alignment
= bus_type_get_alignment(contents
[0]);
1563 if (c
->signature
&& c
->signature
[c
->index
]) {
1565 /* Verify the existing signature */
1567 if (c
->signature
[c
->index
] != SD_BUS_TYPE_ARRAY
)
1570 if (!startswith(c
->signature
+ c
->index
+ 1, contents
))
1573 nindex
= c
->index
+ 1 + strlen(contents
);
1577 if (c
->enclosing
!= 0)
1580 /* Extend the existing signature */
1582 e
= strextend(&c
->signature
, CHAR_TO_STR(SD_BUS_TYPE_ARRAY
), contents
, NULL
);
1588 nindex
= e
- c
->signature
;
1591 a
= message_extend_body(m
, 4, 4);
1596 op
= m
->body_end
->data
;
1597 os
= m
->body_end
->size
;
1599 /* Add alignment between size and first element */
1600 if (!message_extend_body(m
, alignment
, 0))
1603 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1606 /* location of array size might have changed so let's readjust a */
1607 if (o
== m
->body_end
)
1608 a
= adjust_pointer(a
, op
, os
, m
->body_end
->data
);
1615 static int bus_message_open_variant(
1617 struct bus_container
*c
,
1618 const char *contents
) {
1627 if (!signature_is_single(contents
))
1630 if (*contents
== SD_BUS_TYPE_DICT_ENTRY_BEGIN
)
1633 if (c
->signature
&& c
->signature
[c
->index
]) {
1635 if (c
->signature
[c
->index
] != SD_BUS_TYPE_VARIANT
)
1641 if (c
->enclosing
!= 0)
1644 e
= strextend(&c
->signature
, CHAR_TO_STR(SD_BUS_TYPE_VARIANT
), NULL
);
1651 l
= strlen(contents
);
1652 a
= message_extend_body(m
, 1, 1 + l
+ 1);
1657 memcpy((uint8_t*) a
+ 1, contents
, l
+ 1);
1659 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1665 static int bus_message_open_struct(
1667 struct bus_container
*c
,
1668 const char *contents
) {
1676 if (!signature_is_valid(contents
, false))
1679 if (c
->signature
&& c
->signature
[c
->index
]) {
1682 l
= strlen(contents
);
1684 if (c
->signature
[c
->index
] != SD_BUS_TYPE_STRUCT_BEGIN
||
1685 !startswith(c
->signature
+ c
->index
+ 1, contents
) ||
1686 c
->signature
[c
->index
+ 1 + l
] != SD_BUS_TYPE_STRUCT_END
)
1689 nindex
= c
->index
+ 1 + l
+ 1;
1693 if (c
->enclosing
!= 0)
1696 e
= strextend(&c
->signature
, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN
), contents
, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END
), NULL
);
1702 nindex
= e
- c
->signature
;
1705 /* Align contents to 8 byte boundary */
1706 if (!message_extend_body(m
, 8, 0))
1709 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1715 static int bus_message_open_dict_entry(
1717 struct bus_container
*c
,
1718 const char *contents
) {
1726 if (!signature_is_pair(contents
))
1729 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1732 if (c
->signature
&& c
->signature
[c
->index
]) {
1735 l
= strlen(contents
);
1737 if (c
->signature
[c
->index
] != SD_BUS_TYPE_DICT_ENTRY_BEGIN
||
1738 !startswith(c
->signature
+ c
->index
+ 1, contents
) ||
1739 c
->signature
[c
->index
+ 1 + l
] != SD_BUS_TYPE_DICT_ENTRY_END
)
1742 nindex
= c
->index
+ 1 + l
+ 1;
1746 /* Align contents to 8 byte boundary */
1747 if (!message_extend_body(m
, 8, 0))
1750 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1756 int sd_bus_message_open_container(
1759 const char *contents
) {
1761 struct bus_container
*c
, *w
;
1762 uint32_t *array_size
= NULL
;
1776 /* Make sure we have space for one more container */
1777 w
= realloc(m
->containers
, sizeof(struct bus_container
) * (m
->n_containers
+ 1));
1785 c
= message_get_container(m
);
1787 signature
= strdup(contents
);
1793 /* Save old index in the parent container, in case we have to
1794 * abort this container */
1795 c
->saved_index
= c
->index
;
1796 before
= m
->header
->body_size
;
1798 if (type
== SD_BUS_TYPE_ARRAY
)
1799 r
= bus_message_open_array(m
, c
, contents
, &array_size
);
1800 else if (type
== SD_BUS_TYPE_VARIANT
)
1801 r
= bus_message_open_variant(m
, c
, contents
);
1802 else if (type
== SD_BUS_TYPE_STRUCT
)
1803 r
= bus_message_open_struct(m
, c
, contents
);
1804 else if (type
== SD_BUS_TYPE_DICT_ENTRY
)
1805 r
= bus_message_open_dict_entry(m
, c
, contents
);
1814 /* OK, let's fill it in */
1815 w
+= m
->n_containers
++;
1816 w
->enclosing
= type
;
1817 w
->signature
= signature
;
1819 w
->array_size
= array_size
;
1821 w
->begin
= m
->rindex
;
1826 int sd_bus_message_close_container(sd_bus_message
*m
) {
1827 struct bus_container
*c
;
1833 if (m
->n_containers
<= 0)
1838 c
= message_get_container(m
);
1839 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
1840 if (c
->signature
&& c
->signature
[c
->index
] != 0)
1855 static int type_stack_push(TypeStack
*stack
, unsigned max
, unsigned *i
, const char *types
, unsigned n_struct
, unsigned n_array
) {
1862 stack
[*i
].types
= types
;
1863 stack
[*i
].n_struct
= n_struct
;
1864 stack
[*i
].n_array
= n_array
;
1870 static int type_stack_pop(TypeStack
*stack
, unsigned max
, unsigned *i
, const char **types
, unsigned *n_struct
, unsigned *n_array
) {
1881 *types
= stack
[*i
].types
;
1882 *n_struct
= stack
[*i
].n_struct
;
1883 *n_array
= stack
[*i
].n_array
;
1888 int bus_message_append_ap(
1893 unsigned n_array
, n_struct
;
1894 TypeStack stack
[BUS_CONTAINER_DEPTH
];
1895 unsigned stack_ptr
= 0;
1903 n_array
= (unsigned) -1;
1904 n_struct
= strlen(types
);
1909 if (n_array
== 0 || (n_array
== (unsigned) -1 && n_struct
== 0)) {
1910 r
= type_stack_pop(stack
, ELEMENTSOF(stack
), &stack_ptr
, &types
, &n_struct
, &n_array
);
1916 r
= sd_bus_message_close_container(m
);
1924 if (n_array
!= (unsigned) -1)
1933 case SD_BUS_TYPE_BYTE
: {
1936 x
= (uint8_t) va_arg(ap
, int);
1937 r
= sd_bus_message_append_basic(m
, *t
, &x
);
1941 case SD_BUS_TYPE_BOOLEAN
:
1942 case SD_BUS_TYPE_INT32
:
1943 case SD_BUS_TYPE_UINT32
:
1944 case SD_BUS_TYPE_UNIX_FD
: {
1947 /* We assume a boolean is the same as int32_t */
1948 assert_cc(sizeof(int32_t) == sizeof(int));
1950 x
= va_arg(ap
, uint32_t);
1951 r
= sd_bus_message_append_basic(m
, *t
, &x
);
1955 case SD_BUS_TYPE_INT16
:
1956 case SD_BUS_TYPE_UINT16
: {
1959 x
= (uint16_t) va_arg(ap
, int);
1960 r
= sd_bus_message_append_basic(m
, *t
, &x
);
1964 case SD_BUS_TYPE_INT64
:
1965 case SD_BUS_TYPE_UINT64
:
1966 case SD_BUS_TYPE_DOUBLE
: {
1969 x
= va_arg(ap
, uint64_t);
1970 r
= sd_bus_message_append_basic(m
, *t
, &x
);
1974 case SD_BUS_TYPE_STRING
:
1975 case SD_BUS_TYPE_OBJECT_PATH
:
1976 case SD_BUS_TYPE_SIGNATURE
: {
1979 x
= va_arg(ap
, const char*);
1980 r
= sd_bus_message_append_basic(m
, *t
, x
);
1984 case SD_BUS_TYPE_ARRAY
: {
1987 r
= signature_element_length(t
+ 1, &k
);
1993 memcpy(s
, t
+ 1, k
);
1996 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, s
);
2001 if (n_array
== (unsigned) -1) {
2006 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
2012 n_array
= va_arg(ap
, unsigned);
2017 case SD_BUS_TYPE_VARIANT
: {
2020 s
= va_arg(ap
, const char*);
2024 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_VARIANT
, s
);
2028 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
2033 n_struct
= strlen(s
);
2034 n_array
= (unsigned) -1;
2039 case SD_BUS_TYPE_STRUCT_BEGIN
:
2040 case SD_BUS_TYPE_DICT_ENTRY_BEGIN
: {
2043 r
= signature_element_length(t
, &k
);
2050 memcpy(s
, t
+ 1, k
- 2);
2053 r
= sd_bus_message_open_container(m
, *t
== SD_BUS_TYPE_STRUCT_BEGIN
? SD_BUS_TYPE_STRUCT
: SD_BUS_TYPE_DICT_ENTRY
, s
);
2058 if (n_array
== (unsigned) -1) {
2063 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
2069 n_array
= (unsigned) -1;
2085 int sd_bus_message_append(sd_bus_message
*m
, const char *types
, ...) {
2098 va_start(ap
, types
);
2099 r
= bus_message_append_ap(m
, types
, ap
);
2105 int sd_bus_message_append_array_space(sd_bus_message
*m
, char type
, size_t size
, void **ptr
) {
2114 if (!bus_type_is_trivial(type
))
2116 if (!ptr
&& size
> 0)
2121 align
= bus_type_get_alignment(type
);
2122 sz
= bus_type_get_size(type
);
2124 assert_se(align
> 0);
2130 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, CHAR_TO_STR(type
));
2134 a
= message_extend_body(m
, align
, size
);
2138 r
= sd_bus_message_close_container(m
);
2146 int sd_bus_message_append_array(sd_bus_message
*m
, char type
, const void *ptr
, size_t size
) {
2150 if (!ptr
&& size
> 0)
2153 r
= sd_bus_message_append_array_space(m
, type
, size
, &p
);
2158 memcpy(p
, ptr
, size
);
2163 int sd_bus_message_append_array_memfd(sd_bus_message
*m
, char type
, sd_memfd
*memfd
) {
2164 _cleanup_close_
int copy_fd
= -1;
2165 struct bus_body_part
*part
;
2177 if (!bus_type_is_trivial(type
))
2182 r
= sd_memfd_set_sealed(memfd
, true);
2186 copy_fd
= sd_memfd_dup_fd(memfd
);
2190 r
= sd_memfd_get_size(memfd
, &size
);
2194 align
= bus_type_get_alignment(type
);
2195 sz
= bus_type_get_size(type
);
2197 assert_se(align
> 0);
2203 if (size
> (uint64_t) (uint32_t) -1)
2206 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, CHAR_TO_STR(type
));
2210 a
= message_extend_body(m
, align
, 0);
2214 part
= message_append_part(m
);
2218 part
->memfd
= copy_fd
;
2219 part
->sealed
= true;
2223 message_extend_containers(m
, size
);
2224 m
->header
->body_size
+= size
;
2226 return sd_bus_message_close_container(m
);
2229 int sd_bus_message_append_string_memfd(sd_bus_message
*m
, sd_memfd
*memfd
) {
2230 _cleanup_close_
int copy_fd
= -1;
2231 struct bus_body_part
*part
;
2232 struct bus_container
*c
;
2246 r
= sd_memfd_set_sealed(memfd
, true);
2250 copy_fd
= sd_memfd_dup_fd(memfd
);
2254 r
= sd_memfd_get_size(memfd
, &size
);
2258 /* We require this to be NUL terminated */
2262 if (size
> (uint64_t) (uint32_t) -1)
2265 c
= message_get_container(m
);
2266 if (c
->signature
&& c
->signature
[c
->index
]) {
2267 /* Container signature is already set */
2269 if (c
->signature
[c
->index
] != SD_BUS_TYPE_STRING
)
2274 /* Maybe we can append to the signature? But only if this is the top-level container*/
2275 if (c
->enclosing
!= 0)
2278 e
= strextend(&c
->signature
, CHAR_TO_STR(SD_BUS_TYPE_STRING
), NULL
);
2285 a
= message_extend_body(m
, 4, 4);
2289 *(uint32_t*) a
= size
- 1;
2291 part
= message_append_part(m
);
2295 part
->memfd
= copy_fd
;
2296 part
->sealed
= true;
2300 message_extend_containers(m
, size
);
2301 m
->header
->body_size
+= size
;
2303 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2309 int bus_body_part_map(struct bus_body_part
*part
) {
2318 if (part
->size
<= 0)
2321 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2322 if (part
->memfd
< 0 && part
->is_zero
&& part
->size
< 8) {
2323 static const uint8_t zeroes
[7] = { };
2324 part
->data
= (void*) zeroes
;
2328 psz
= PAGE_ALIGN(part
->size
);
2330 if (part
->memfd
>= 0)
2331 p
= mmap(NULL
, psz
, PROT_READ
, MAP_SHARED
, part
->memfd
, 0);
2332 else if (part
->is_zero
)
2333 p
= mmap(NULL
, psz
, PROT_READ
, MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
2337 if (p
== MAP_FAILED
)
2342 part
->munmap_this
= true;
2347 void bus_body_part_unmap(struct bus_body_part
*part
) {
2351 if (part
->memfd
< 0)
2357 if (!part
->munmap_this
)
2360 assert_se(munmap(part
->data
, part
->mapped
) == 0);
2364 part
->munmap_this
= false;
2369 static int buffer_peek(const void *p
, uint32_t sz
, size_t *rindex
, size_t align
, size_t nbytes
, void **r
) {
2370 size_t k
, start
, end
;
2375 start
= ALIGN_TO((size_t) *rindex
, align
);
2376 end
= start
+ nbytes
;
2381 /* Verify that padding is 0 */
2382 for (k
= *rindex
; k
< start
; k
++)
2383 if (((const uint8_t*) p
)[k
] != 0)
2387 *r
= (uint8_t*) p
+ start
;
2394 static bool message_end_of_array(sd_bus_message
*m
, size_t index
) {
2395 struct bus_container
*c
;
2399 c
= message_get_container(m
);
2403 return index
>= c
->begin
+ BUS_MESSAGE_BSWAP32(m
, *c
->array_size
);
2406 static struct bus_body_part
* find_part(sd_bus_message
*m
, size_t index
, size_t sz
, void **p
) {
2407 struct bus_body_part
*part
;
2413 if (m
->cached_rindex_part
&& index
>= m
->cached_rindex_part_begin
) {
2414 part
= m
->cached_rindex_part
;
2415 begin
= m
->cached_rindex_part_begin
;
2425 if (index
+ sz
<= begin
+ part
->size
) {
2427 r
= bus_body_part_map(part
);
2432 *p
= (uint8_t*) part
->data
+ index
- begin
;
2434 m
->cached_rindex_part
= part
;
2435 m
->cached_rindex_part_begin
= begin
;
2440 begin
+= part
->size
;
2447 static int message_peek_body(
2454 size_t k
, start
, end
, padding
;
2455 struct bus_body_part
*part
;
2462 if (message_end_of_array(m
, *rindex
))
2465 start
= ALIGN_TO((size_t) *rindex
, align
);
2466 padding
= start
- *rindex
;
2467 end
= start
+ nbytes
;
2469 if (end
> BUS_MESSAGE_BODY_SIZE(m
))
2472 part
= find_part(m
, *rindex
, padding
, (void**) &q
);
2477 /* Verify padding */
2478 for (k
= 0; k
< padding
; k
++)
2483 part
= find_part(m
, start
, nbytes
, (void**) &q
);
2495 static bool validate_nul(const char *s
, size_t l
) {
2497 /* Check for NUL chars in the string */
2498 if (memchr(s
, 0, l
))
2501 /* Check for NUL termination */
2508 static bool validate_string(const char *s
, size_t l
) {
2510 if (!validate_nul(s
, l
))
2513 /* Check if valid UTF8 */
2514 if (!utf8_is_valid(s
))
2520 static bool validate_signature(const char *s
, size_t l
) {
2522 if (!validate_nul(s
, l
))
2525 /* Check if valid signature */
2526 if (!signature_is_valid(s
, true))
2532 static bool validate_object_path(const char *s
, size_t l
) {
2534 if (!validate_nul(s
, l
))
2537 if (!object_path_is_valid(s
))
2543 int sd_bus_message_read_basic(sd_bus_message
*m
, char type
, void *p
) {
2544 struct bus_container
*c
;
2552 if (!bus_type_is_basic(type
))
2557 c
= message_get_container(m
);
2559 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2562 if (c
->signature
[c
->index
] != type
)
2567 case SD_BUS_TYPE_STRING
:
2568 case SD_BUS_TYPE_OBJECT_PATH
: {
2573 r
= message_peek_body(m
, &rindex
, 4, 4, &q
);
2577 l
= BUS_MESSAGE_BSWAP32(m
, *(uint32_t*) q
);
2578 r
= message_peek_body(m
, &rindex
, 1, l
+1, &q
);
2584 if (type
== SD_BUS_TYPE_OBJECT_PATH
) {
2585 if (!validate_object_path(q
, l
))
2588 if (!validate_string(q
, l
))
2593 *(const char**) p
= q
;
2597 case SD_BUS_TYPE_SIGNATURE
: {
2602 r
= message_peek_body(m
, &rindex
, 1, 1, &q
);
2607 r
= message_peek_body(m
, &rindex
, 1, l
+1, &q
);
2613 if (!validate_signature(q
, l
))
2617 *(const char**) p
= q
;
2625 align
= bus_type_get_alignment(type
);
2626 sz
= bus_type_get_size(type
);
2627 assert(align
> 0 && sz
> 0);
2630 r
= message_peek_body(m
, &rindex
, align
, sz
, &q
);
2636 case SD_BUS_TYPE_BYTE
:
2637 *(uint8_t*) p
= *(uint8_t*) q
;
2640 case SD_BUS_TYPE_BOOLEAN
:
2641 *(int*) p
= !!*(uint32_t*) q
;
2644 case SD_BUS_TYPE_INT16
:
2645 case SD_BUS_TYPE_UINT16
:
2646 *(uint16_t*) p
= BUS_MESSAGE_BSWAP16(m
, *(uint16_t*) q
);
2649 case SD_BUS_TYPE_INT32
:
2650 case SD_BUS_TYPE_UINT32
:
2651 *(uint32_t*) p
= BUS_MESSAGE_BSWAP32(m
, *(uint32_t*) q
);
2654 case SD_BUS_TYPE_INT64
:
2655 case SD_BUS_TYPE_UINT64
:
2656 case SD_BUS_TYPE_DOUBLE
:
2657 *(uint64_t*) p
= BUS_MESSAGE_BSWAP64(m
, *(uint64_t*) q
);
2660 case SD_BUS_TYPE_UNIX_FD
: {
2663 j
= BUS_MESSAGE_BSWAP32(m
, *(uint32_t*) q
);
2667 *(int*) p
= m
->fds
[j
];
2672 assert_not_reached("Unknown basic type...");
2681 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2687 static int bus_message_enter_array(
2689 struct bus_container
*c
,
2690 const char *contents
,
2691 uint32_t **array_size
) {
2702 if (!signature_is_single(contents
))
2705 alignment
= bus_type_get_alignment(contents
[0]);
2709 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2712 if (c
->signature
[c
->index
] != SD_BUS_TYPE_ARRAY
)
2715 if (!startswith(c
->signature
+ c
->index
+ 1, contents
))
2719 r
= message_peek_body(m
, &rindex
, 4, 4, &q
);
2723 if (BUS_MESSAGE_BSWAP32(m
, *(uint32_t*) q
) > BUS_ARRAY_MAX_SIZE
)
2726 r
= message_peek_body(m
, &rindex
, alignment
, 0, NULL
);
2732 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2733 c
->index
+= 1 + strlen(contents
);
2737 *array_size
= (uint32_t*) q
;
2742 static int bus_message_enter_variant(
2744 struct bus_container
*c
,
2745 const char *contents
) {
2756 if (!signature_is_single(contents
))
2759 if (*contents
== SD_BUS_TYPE_DICT_ENTRY_BEGIN
)
2762 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2765 if (c
->signature
[c
->index
] != SD_BUS_TYPE_VARIANT
)
2769 r
= message_peek_body(m
, &rindex
, 1, 1, &q
);
2774 r
= message_peek_body(m
, &rindex
, 1, l
+1, &q
);
2780 if (!validate_signature(q
, l
))
2783 if (!streq(q
, contents
))
2786 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2794 static int bus_message_enter_struct(
2796 struct bus_container
*c
,
2797 const char *contents
) {
2806 if (!signature_is_valid(contents
, false))
2809 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2812 l
= strlen(contents
);
2814 if (c
->signature
[c
->index
] != SD_BUS_TYPE_STRUCT_BEGIN
||
2815 !startswith(c
->signature
+ c
->index
+ 1, contents
) ||
2816 c
->signature
[c
->index
+ 1 + l
] != SD_BUS_TYPE_STRUCT_END
)
2819 r
= message_peek_body(m
, &m
->rindex
, 8, 0, NULL
);
2823 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2824 c
->index
+= 1 + l
+ 1;
2829 static int bus_message_enter_dict_entry(
2831 struct bus_container
*c
,
2832 const char *contents
) {
2841 if (!signature_is_pair(contents
))
2844 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2847 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2850 l
= strlen(contents
);
2852 if (c
->signature
[c
->index
] != SD_BUS_TYPE_DICT_ENTRY_BEGIN
||
2853 !startswith(c
->signature
+ c
->index
+ 1, contents
) ||
2854 c
->signature
[c
->index
+ 1 + l
] != SD_BUS_TYPE_DICT_ENTRY_END
)
2857 r
= message_peek_body(m
, &m
->rindex
, 8, 0, NULL
);
2861 if (c
->enclosing
!= SD_BUS_TYPE_ARRAY
)
2862 c
->index
+= 1 + l
+ 1;
2867 int sd_bus_message_enter_container(sd_bus_message
*m
, char type
, const char *contents
) {
2868 struct bus_container
*c
, *w
;
2869 uint32_t *array_size
= NULL
;
2882 * We enforce a global limit on container depth, that is much
2883 * higher than the 32 structs and 32 arrays the specification
2884 * mandates. This is simpler to implement for us, and we need
2885 * this only to ensure our container array doesn't grow
2886 * without bounds. We are happy to return any data from a
2887 * message as long as the data itself is valid, even if the
2888 * overall message might be not.
2890 * Note that the message signature is validated when
2891 * parsing the headers, and that validation does check the
2894 * Note that the specification defines no limits on the depth
2895 * of stacked variants, but we do.
2897 if (m
->n_containers
>= BUS_CONTAINER_DEPTH
)
2900 w
= realloc(m
->containers
, sizeof(struct bus_container
) * (m
->n_containers
+ 1));
2905 c
= message_get_container(m
);
2907 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
2910 signature
= strdup(contents
);
2914 c
->saved_index
= c
->index
;
2917 if (type
== SD_BUS_TYPE_ARRAY
)
2918 r
= bus_message_enter_array(m
, c
, contents
, &array_size
);
2919 else if (type
== SD_BUS_TYPE_VARIANT
)
2920 r
= bus_message_enter_variant(m
, c
, contents
);
2921 else if (type
== SD_BUS_TYPE_STRUCT
)
2922 r
= bus_message_enter_struct(m
, c
, contents
);
2923 else if (type
== SD_BUS_TYPE_DICT_ENTRY
)
2924 r
= bus_message_enter_dict_entry(m
, c
, contents
);
2933 /* OK, let's fill it in */
2934 w
+= m
->n_containers
++;
2935 w
->enclosing
= type
;
2936 w
->signature
= signature
;
2938 w
->array_size
= array_size
;
2940 w
->begin
= m
->rindex
;
2945 int sd_bus_message_exit_container(sd_bus_message
*m
) {
2946 struct bus_container
*c
;
2952 if (m
->n_containers
<= 0)
2955 c
= message_get_container(m
);
2956 if (c
->enclosing
== SD_BUS_TYPE_ARRAY
) {
2959 l
= BUS_MESSAGE_BSWAP32(m
, *c
->array_size
);
2960 if (c
->begin
+ l
!= m
->rindex
)
2964 if (c
->signature
&& c
->signature
[c
->index
] != 0)
2974 static void message_quit_container(sd_bus_message
*m
) {
2975 struct bus_container
*c
;
2979 assert(m
->n_containers
> 0);
2981 c
= message_get_container(m
);
2984 assert(m
->rindex
>= c
->before
);
2985 m
->rindex
= c
->before
;
2987 /* Free container */
2991 /* Correct index of new top-level container */
2992 c
= message_get_container(m
);
2993 c
->index
= c
->saved_index
;
2996 int sd_bus_message_peek_type(sd_bus_message
*m
, char *type
, const char **contents
) {
2997 struct bus_container
*c
;
3005 c
= message_get_container(m
);
3007 if (!c
->signature
|| c
->signature
[c
->index
] == 0)
3010 if (message_end_of_array(m
, m
->rindex
))
3013 if (bus_type_is_basic(c
->signature
[c
->index
])) {
3017 *type
= c
->signature
[c
->index
];
3021 if (c
->signature
[c
->index
] == SD_BUS_TYPE_ARRAY
) {
3027 r
= signature_element_length(c
->signature
+c
->index
+1, &l
);
3033 sig
= strndup(c
->signature
+ c
->index
+ 1, l
);
3037 free(m
->peeked_signature
);
3038 m
->peeked_signature
= sig
;
3044 *type
= SD_BUS_TYPE_ARRAY
;
3049 if (c
->signature
[c
->index
] == SD_BUS_TYPE_STRUCT_BEGIN
||
3050 c
->signature
[c
->index
] == SD_BUS_TYPE_DICT_ENTRY_BEGIN
) {
3056 r
= signature_element_length(c
->signature
+c
->index
, &l
);
3061 sig
= strndup(c
->signature
+ c
->index
+ 1, l
- 2);
3065 free(m
->peeked_signature
);
3066 m
->peeked_signature
= sig
;
3072 *type
= c
->signature
[c
->index
] == SD_BUS_TYPE_STRUCT_BEGIN
? SD_BUS_TYPE_STRUCT
: SD_BUS_TYPE_DICT_ENTRY
;
3077 if (c
->signature
[c
->index
] == SD_BUS_TYPE_VARIANT
) {
3083 r
= message_peek_body(m
, &rindex
, 1, 1, &q
);
3090 r
= message_peek_body(m
, &rindex
, 1, l
+1, &q
);
3096 if (!validate_signature(q
, l
))
3103 *type
= SD_BUS_TYPE_VARIANT
;
3112 *type
= c
->enclosing
;
3118 int sd_bus_message_rewind(sd_bus_message
*m
, int complete
) {
3119 struct bus_container
*c
;
3127 message_reset_containers(m
);
3129 m
->root_container
.index
= 0;
3131 c
= message_get_container(m
);
3133 c
= message_get_container(m
);
3136 m
->rindex
= c
->begin
;
3139 return !isempty(c
->signature
);
3141 static int message_read_ap(
3146 unsigned n_array
, n_struct
;
3147 TypeStack stack
[BUS_CONTAINER_DEPTH
];
3148 unsigned stack_ptr
= 0;
3156 /* Ideally, we'd just call ourselves recursively on every
3157 * complex type. However, the state of a va_list that is
3158 * passed to a function is undefined after that function
3159 * returns. This means we need to docode the va_list linearly
3160 * in a single stackframe. We hence implement our own
3161 * home-grown stack in an array. */
3163 n_array
= (unsigned) -1;
3164 n_struct
= strlen(types
);
3169 if (n_array
== 0 || (n_array
== (unsigned) -1 && n_struct
== 0)) {
3170 r
= type_stack_pop(stack
, ELEMENTSOF(stack
), &stack_ptr
, &types
, &n_struct
, &n_array
);
3176 r
= sd_bus_message_exit_container(m
);
3184 if (n_array
!= (unsigned) -1)
3193 case SD_BUS_TYPE_BYTE
:
3194 case SD_BUS_TYPE_BOOLEAN
:
3195 case SD_BUS_TYPE_INT16
:
3196 case SD_BUS_TYPE_UINT16
:
3197 case SD_BUS_TYPE_INT32
:
3198 case SD_BUS_TYPE_UINT32
:
3199 case SD_BUS_TYPE_INT64
:
3200 case SD_BUS_TYPE_UINT64
:
3201 case SD_BUS_TYPE_DOUBLE
:
3202 case SD_BUS_TYPE_STRING
:
3203 case SD_BUS_TYPE_OBJECT_PATH
:
3204 case SD_BUS_TYPE_SIGNATURE
:
3205 case SD_BUS_TYPE_UNIX_FD
: {
3208 p
= va_arg(ap
, void*);
3209 r
= sd_bus_message_read_basic(m
, *t
, p
);
3218 case SD_BUS_TYPE_ARRAY
: {
3221 r
= signature_element_length(t
+ 1, &k
);
3227 memcpy(s
, t
+ 1, k
);
3230 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, s
);
3237 if (n_array
== (unsigned) -1) {
3242 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
3248 n_array
= va_arg(ap
, unsigned);
3253 case SD_BUS_TYPE_VARIANT
: {
3256 s
= va_arg(ap
, const char *);
3260 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, s
);
3266 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
3271 n_struct
= strlen(s
);
3272 n_array
= (unsigned) -1;
3277 case SD_BUS_TYPE_STRUCT_BEGIN
:
3278 case SD_BUS_TYPE_DICT_ENTRY_BEGIN
: {
3281 r
= signature_element_length(t
, &k
);
3287 memcpy(s
, t
+ 1, k
- 2);
3290 r
= sd_bus_message_enter_container(m
, *t
== SD_BUS_TYPE_STRUCT_BEGIN
? SD_BUS_TYPE_STRUCT
: SD_BUS_TYPE_DICT_ENTRY
, s
);
3297 if (n_array
== (unsigned) -1) {
3302 r
= type_stack_push(stack
, ELEMENTSOF(stack
), &stack_ptr
, types
, n_struct
, n_array
);
3308 n_array
= (unsigned) -1;
3321 int sd_bus_message_read(sd_bus_message
*m
, const char *types
, ...) {
3332 va_start(ap
, types
);
3333 r
= message_read_ap(m
, types
, ap
);
3339 int sd_bus_message_read_array(sd_bus_message
*m
, char type
, const void **ptr
, size_t *size
) {
3340 struct bus_container
*c
;
3350 if (!bus_type_is_trivial(type
))
3356 if (BUS_MESSAGE_NEED_BSWAP(m
))
3359 align
= bus_type_get_alignment(type
);
3363 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, CHAR_TO_STR(type
));
3367 c
= message_get_container(m
);
3368 sz
= BUS_MESSAGE_BSWAP32(m
, *c
->array_size
);
3370 r
= message_peek_body(m
, &m
->rindex
, align
, sz
, &p
);
3378 r
= sd_bus_message_exit_container(m
);
3382 *ptr
= (const void*) p
;
3388 message_quit_container(m
);
3392 static int message_peek_fields(
3403 return buffer_peek(BUS_MESSAGE_FIELDS(m
), BUS_MESSAGE_FIELDS_SIZE(m
), rindex
, align
, nbytes
, ret
);
3406 static int message_peek_field_uint32(
3417 r
= message_peek_fields(m
, ri
, 4, 4, &q
);
3422 *ret
= BUS_MESSAGE_BSWAP32(m
, *(uint32_t*) q
);
3427 static int message_peek_field_string(
3429 bool (*validate
)(const char *p
),
3440 r
= message_peek_field_uint32(m
, ri
, &l
);
3444 r
= message_peek_fields(m
, ri
, 1, l
+1, &q
);
3449 if (!validate_nul(q
, l
))
3455 if (!validate_string(q
, l
))
3465 static int message_peek_field_signature(
3477 r
= message_peek_fields(m
, ri
, 1, 1, &q
);
3482 r
= message_peek_fields(m
, ri
, 1, l
+1, &q
);
3486 if (!validate_signature(q
, l
))
3495 static int message_skip_fields(
3498 uint32_t array_size
,
3499 const char **signature
) {
3501 size_t original_index
;
3508 original_index
= *ri
;
3514 if (array_size
!= (uint32_t) -1 &&
3515 array_size
<= *ri
- original_index
)
3522 if (t
== SD_BUS_TYPE_STRING
) {
3524 r
= message_peek_field_string(m
, NULL
, ri
, NULL
);
3530 } else if (t
== SD_BUS_TYPE_OBJECT_PATH
) {
3532 r
= message_peek_field_string(m
, object_path_is_valid
, ri
, NULL
);
3538 } else if (t
== SD_BUS_TYPE_SIGNATURE
) {
3540 r
= message_peek_field_signature(m
, ri
, NULL
);
3546 } else if (bus_type_is_basic(t
)) {
3549 align
= bus_type_get_alignment(t
);
3550 k
= bus_type_get_size(t
);
3551 assert(align
> 0 && k
> 0);
3553 r
= message_peek_fields(m
, ri
, align
, k
, NULL
);
3559 } else if (t
== SD_BUS_TYPE_ARRAY
) {
3561 r
= signature_element_length(*signature
+1, &l
);
3571 strncpy(sig
, *signature
+ 1, l
-1);
3574 alignment
= bus_type_get_alignment(sig
[0]);
3578 r
= message_peek_field_uint32(m
, ri
, &nas
);
3581 if (nas
> BUS_ARRAY_MAX_SIZE
)
3584 r
= message_peek_fields(m
, ri
, alignment
, 0, NULL
);
3588 r
= message_skip_fields(m
, ri
, nas
, (const char**) &s
);
3593 (*signature
) += 1 + l
;
3595 } else if (t
== SD_BUS_TYPE_VARIANT
) {
3598 r
= message_peek_field_signature(m
, ri
, &s
);
3602 r
= message_skip_fields(m
, ri
, (uint32_t) -1, (const char**) &s
);
3608 } else if (t
== SD_BUS_TYPE_STRUCT
||
3609 t
== SD_BUS_TYPE_DICT_ENTRY
) {
3611 r
= signature_element_length(*signature
, &l
);
3618 strncpy(sig
, *signature
+ 1, l
-1);
3621 r
= message_skip_fields(m
, ri
, (uint32_t) -1, (const char**) &s
);
3632 int bus_message_parse_fields(sd_bus_message
*m
) {
3635 uint32_t unix_fds
= 0;
3639 for (ri
= 0; ri
< BUS_MESSAGE_FIELDS_SIZE(m
); ) {
3640 const char *signature
;
3643 r
= message_peek_fields(m
, &ri
, 8, 1, (void**) &header
);
3647 r
= message_peek_field_signature(m
, &ri
, &signature
);
3652 case _SD_BUS_MESSAGE_HEADER_INVALID
:
3655 case SD_BUS_MESSAGE_HEADER_PATH
:
3660 if (!streq(signature
, "o"))
3663 r
= message_peek_field_string(m
, object_path_is_valid
, &ri
, &m
->path
);
3666 case SD_BUS_MESSAGE_HEADER_INTERFACE
:
3671 if (!streq(signature
, "s"))
3674 r
= message_peek_field_string(m
, interface_name_is_valid
, &ri
, &m
->interface
);
3677 case SD_BUS_MESSAGE_HEADER_MEMBER
:
3682 if (!streq(signature
, "s"))
3685 r
= message_peek_field_string(m
, member_name_is_valid
, &ri
, &m
->member
);
3688 case SD_BUS_MESSAGE_HEADER_ERROR_NAME
:
3693 if (!streq(signature
, "s"))
3696 r
= message_peek_field_string(m
, error_name_is_valid
, &ri
, &m
->error
.name
);
3699 case SD_BUS_MESSAGE_HEADER_DESTINATION
:
3704 if (!streq(signature
, "s"))
3707 r
= message_peek_field_string(m
, service_name_is_valid
, &ri
, &m
->destination
);
3710 case SD_BUS_MESSAGE_HEADER_SENDER
:
3715 if (!streq(signature
, "s"))
3718 r
= message_peek_field_string(m
, service_name_is_valid
, &ri
, &m
->sender
);
3722 case SD_BUS_MESSAGE_HEADER_SIGNATURE
: {
3726 if (m
->root_container
.signature
)
3729 if (!streq(signature
, "g"))
3732 r
= message_peek_field_signature(m
, &ri
, &s
);
3740 free(m
->root_container
.signature
);
3741 m
->root_container
.signature
= c
;
3745 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL
:
3746 if (m
->reply_serial
!= 0)
3749 if (!streq(signature
, "u"))
3752 r
= message_peek_field_uint32(m
, &ri
, &m
->reply_serial
);
3756 if (m
->reply_serial
== 0)
3761 case SD_BUS_MESSAGE_HEADER_UNIX_FDS
:
3765 if (!streq(signature
, "u"))
3768 r
= message_peek_field_uint32(m
, &ri
, &unix_fds
);
3778 r
= message_skip_fields(m
, &ri
, (uint32_t) -1, (const char **) &signature
);
3785 if (m
->n_fds
!= unix_fds
)
3788 if (isempty(m
->root_container
.signature
) != (BUS_MESSAGE_BODY_SIZE(m
) == 0))
3791 switch (m
->header
->type
) {
3793 case SD_BUS_MESSAGE_TYPE_SIGNAL
:
3794 if (!m
->path
|| !m
->interface
|| !m
->member
)
3798 case SD_BUS_MESSAGE_TYPE_METHOD_CALL
:
3800 if (!m
->path
|| !m
->member
)
3805 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN
:
3807 if (m
->reply_serial
== 0)
3811 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR
:
3813 if (m
->reply_serial
== 0 || !m
->error
.name
)
3818 /* Try to read the error message, but if we can't it's a non-issue */
3819 if (m
->header
->type
== SD_BUS_MESSAGE_TYPE_METHOD_ERROR
)
3820 sd_bus_message_read(m
, "s", &m
->error
.message
);
3825 int bus_message_seal(sd_bus_message
*m
, uint64_t serial
) {
3826 struct bus_body_part
*part
;
3836 if (m
->n_containers
> 0)
3842 /* If there's a non-trivial signature set, then add it in here */
3843 if (!isempty(m
->root_container
.signature
)) {
3844 r
= message_append_field_signature(m
, SD_BUS_MESSAGE_HEADER_SIGNATURE
, m
->root_container
.signature
, NULL
);
3850 r
= message_append_field_uint32(m
, SD_BUS_MESSAGE_HEADER_UNIX_FDS
, m
->n_fds
);
3855 /* Add padding at the end of the fields part, since we know
3856 * the body needs to start at an 8 byte alignment. We made
3857 * sure we allocated enough space for this, so all we need to
3858 * do here is to zero it out. */
3859 l
= BUS_MESSAGE_FIELDS_SIZE(m
);
3862 memset((uint8_t*) BUS_MESSAGE_FIELDS(m
) + l
, 0, a
);
3864 /* If this is something we can send as memfd, then let's seal
3865 the memfd now. Note that we can send memfds as payload only
3866 for directed messages, and not for broadcasts. */
3867 if (m
->destination
&& m
->bus
&& m
->bus
->use_memfd
) {
3868 MESSAGE_FOREACH_PART(part
, i
, m
)
3869 if (part
->memfd
>= 0 && !part
->sealed
&& (part
->size
> MEMFD_MIN_SIZE
|| m
->bus
->use_memfd
< 0)) {
3870 bus_body_part_unmap(part
);
3872 if (ioctl(part
->memfd
, KDBUS_CMD_MEMFD_SEAL_SET
, 1) >= 0)
3873 part
->sealed
= true;
3877 m
->header
->serial
= serial
;
3883 int sd_bus_message_set_destination(sd_bus_message
*m
, const char *destination
) {
3893 return message_append_field_string(m
, SD_BUS_MESSAGE_HEADER_DESTINATION
, SD_BUS_TYPE_STRING
, destination
, &m
->destination
);
3896 int bus_message_dump(sd_bus_message
*m
) {
3897 const char *u
= NULL
, *uu
= NULL
, *s
= NULL
;
3898 char **cmdline
= NULL
;
3901 uid_t owner
, audit_loginuid
;
3902 uint32_t audit_sessionid
;
3906 printf("Message %p\n"
3913 "\tfields_size=%u\n"
3918 "\tdestination=%s\n"
3921 "\treply_serial=%u\n"
3923 "\terror.message=%s\n"
3925 "\tn_body_parts=%u\n",
3932 BUS_MESSAGE_SERIAL(m
),
3933 BUS_MESSAGE_FIELDS_SIZE(m
),
3934 BUS_MESSAGE_BODY_SIZE(m
),
3936 strna(m
->interface
),
3938 strna(m
->destination
),
3940 strna(m
->root_container
.signature
),
3942 strna(m
->error
.name
),
3943 strna(m
->error
.message
),
3948 printf("\tpid=%lu\n", (unsigned long) m
->pid
);
3950 printf("\ttid=%lu\n", (unsigned long) m
->tid
);
3952 printf("\tuid=%lu\n", (unsigned long) m
->uid
);
3954 printf("\tgid=%lu\n", (unsigned long) m
->gid
);
3955 if (m
->pid_starttime
!= 0)
3956 printf("\tpid_starttime=%llu\n", (unsigned long long) m
->pid_starttime
);
3957 if (m
->monotonic
!= 0)
3958 printf("\tmonotonic=%llu\n", (unsigned long long) m
->monotonic
);
3959 if (m
->realtime
!= 0)
3960 printf("\trealtime=%llu\n", (unsigned long long) m
->realtime
);
3962 printf("\texe=[%s]\n", m
->exe
);
3964 printf("\tcomm=[%s]\n", m
->comm
);
3966 printf("\ttid_comm=[%s]\n", m
->tid_comm
);
3968 printf("\tlabel=[%s]\n", m
->label
);
3970 printf("\tcgroup=[%s]\n", m
->cgroup
);
3972 sd_bus_message_get_unit(m
, &u
);
3974 printf("\tunit=[%s]\n", u
);
3975 sd_bus_message_get_user_unit(m
, &uu
);
3977 printf("\tuser_unit=[%s]\n", uu
);
3978 sd_bus_message_get_session(m
, &s
);
3980 printf("\tsession=[%s]\n", s
);
3981 if (sd_bus_message_get_owner_uid(m
, &owner
) >= 0)
3982 printf("\towner_uid=%lu\n", (unsigned long) owner
);
3983 if (sd_bus_message_get_audit_loginuid(m
, &audit_loginuid
) >= 0)
3984 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid
);
3985 if (sd_bus_message_get_audit_sessionid(m
, &audit_sessionid
) >= 0)
3986 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid
);
3988 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m
, 5));
3990 if (sd_bus_message_get_cmdline(m
, &cmdline
) >= 0) {
3993 fputs("\tcmdline=[", stdout
);
3994 STRV_FOREACH(c
, cmdline
) {
4001 fputs("]\n", stdout
);
4004 r
= sd_bus_message_rewind(m
, true);
4006 log_error("Failed to rewind: %s", strerror(-r
));
4010 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m
->root_container
.signature
));
4013 _cleanup_free_
char *prefix
= NULL
;
4014 const char *contents
= NULL
;
4029 r
= sd_bus_message_peek_type(m
, &type
, &contents
);
4031 log_error("Failed to peek type: %s", strerror(-r
));
4038 r
= sd_bus_message_exit_container(m
);
4040 log_error("Failed to exit container: %s", strerror(-r
));
4046 prefix
= strrep("\t", level
);
4050 if (type
== SD_BUS_TYPE_ARRAY
)
4051 printf("%s} END_ARRAY \n", prefix
);
4052 else if (type
== SD_BUS_TYPE_VARIANT
)
4053 printf("%s} END_VARIANT\n", prefix
);
4054 else if (type
== SD_BUS_TYPE_STRUCT
)
4055 printf("%s} END_STRUCT\n", prefix
);
4056 else if (type
== SD_BUS_TYPE_DICT_ENTRY
)
4057 printf("%s} END_DICT_ENTRY\n", prefix
);
4062 prefix
= strrep("\t", level
);
4066 if (bus_type_is_container(type
) > 0) {
4067 r
= sd_bus_message_enter_container(m
, type
, contents
);
4069 log_error("Failed to enter container: %s", strerror(-r
));
4073 if (type
== SD_BUS_TYPE_ARRAY
)
4074 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix
, contents
);
4075 else if (type
== SD_BUS_TYPE_VARIANT
)
4076 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix
, contents
);
4077 else if (type
== SD_BUS_TYPE_STRUCT
)
4078 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix
, contents
);
4079 else if (type
== SD_BUS_TYPE_DICT_ENTRY
)
4080 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix
, contents
);
4087 r
= sd_bus_message_read_basic(m
, type
, &basic
);
4089 log_error("Failed to get basic: %s", strerror(-r
));
4095 case SD_BUS_TYPE_BYTE
:
4096 printf("%sBYTE: %u\n", prefix
, basic
.u8
);
4099 case SD_BUS_TYPE_BOOLEAN
:
4100 printf("%sBOOLEAN: %s\n", prefix
, yes_no(basic
.i
));
4103 case SD_BUS_TYPE_INT16
:
4104 printf("%sINT16: %i\n", prefix
, basic
.s16
);
4107 case SD_BUS_TYPE_UINT16
:
4108 printf("%sUINT16: %u\n", prefix
, basic
.u16
);
4111 case SD_BUS_TYPE_INT32
:
4112 printf("%sINT32: %i\n", prefix
, basic
.s32
);
4115 case SD_BUS_TYPE_UINT32
:
4116 printf("%sUINT32: %u\n", prefix
, basic
.u32
);
4119 case SD_BUS_TYPE_INT64
:
4120 printf("%sINT64: %lli\n", prefix
, (long long) basic
.s64
);
4123 case SD_BUS_TYPE_UINT64
:
4124 printf("%sUINT64: %llu\n", prefix
, (unsigned long long) basic
.u64
);
4127 case SD_BUS_TYPE_DOUBLE
:
4128 printf("%sDOUBLE: %g\n", prefix
, basic
.d64
);
4131 case SD_BUS_TYPE_STRING
:
4132 printf("%sSTRING: \"%s\"\n", prefix
, basic
.string
);
4135 case SD_BUS_TYPE_OBJECT_PATH
:
4136 printf("%sOBJECT_PATH: \"%s\"\n", prefix
, basic
.string
);
4139 case SD_BUS_TYPE_SIGNATURE
:
4140 printf("%sSIGNATURE: \"%s\"\n", prefix
, basic
.string
);
4143 case SD_BUS_TYPE_UNIX_FD
:
4144 printf("%sUNIX_FD: %i\n", prefix
, basic
.i
);
4148 assert_not_reached("Unknown basic type.");
4152 printf("} END_MESSAGE\n");
4156 int bus_message_get_blob(sd_bus_message
*m
, void **buffer
, size_t *sz
) {
4160 struct bus_body_part
*part
;
4166 total
= BUS_MESSAGE_SIZE(m
);
4172 e
= mempcpy(p
, m
->header
, BUS_MESSAGE_BODY_BEGIN(m
));
4173 MESSAGE_FOREACH_PART(part
, i
, m
)
4174 e
= mempcpy(e
, part
->data
, part
->size
);
4176 assert(total
== (size_t) ((uint8_t*) e
- (uint8_t*) p
));
4184 int bus_message_read_strv_extend(sd_bus_message
*m
, char ***l
) {
4190 r
= sd_bus_message_enter_container(m
, 'a', "s");
4197 r
= sd_bus_message_read_basic(m
, 's', &s
);
4203 r
= strv_extend(l
, s
);
4208 r
= sd_bus_message_exit_container(m
);
4215 const char* bus_message_get_arg(sd_bus_message
*m
, unsigned i
) {
4217 const char *t
= NULL
;
4222 r
= sd_bus_message_rewind(m
, true);
4226 for (j
= 0; j
<= i
; j
++) {
4229 r
= sd_bus_message_peek_type(m
, &type
, NULL
);
4233 if (type
!= SD_BUS_TYPE_STRING
&&
4234 type
!= SD_BUS_TYPE_OBJECT_PATH
&&
4235 type
!= SD_BUS_TYPE_SIGNATURE
)
4238 r
= sd_bus_message_read_basic(m
, type
, &t
);
4246 bool bus_header_is_complete(struct bus_header
*h
, size_t size
) {
4252 if (size
< sizeof(struct bus_header
))
4255 full
= sizeof(struct bus_header
) +
4256 (h
->endian
== SD_BUS_NATIVE_ENDIAN
? h
->fields_size
: bswap_32(h
->fields_size
));
4258 return size
>= full
;
4261 int bus_header_message_size(struct bus_header
*h
, size_t *sum
) {
4267 if (h
->endian
== SD_BUS_NATIVE_ENDIAN
) {
4268 fs
= h
->fields_size
;
4270 } else if (h
->endian
== SD_BUS_REVERSE_ENDIAN
) {
4271 fs
= bswap_32(h
->fields_size
);
4272 bs
= bswap_32(h
->body_size
);
4276 *sum
= sizeof(struct bus_header
) + ALIGN8(fs
) + bs
;
4280 int bus_message_to_errno(sd_bus_message
*m
) {
4283 if (m
->header
->type
!= SD_BUS_MESSAGE_TYPE_METHOD_ERROR
)
4286 return bus_error_to_errno(&m
->error
);