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/>.
28 #include "time-util.h"
29 #include "cgroup-util.h"
32 #include "bus-message.h"
33 #include "bus-internal.h"
35 #include "bus-signature.h"
37 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39 static void reset_containers(sd_bus_message *m) {
44 for (i = 0; i < m->n_containers; i++)
45 free(m->containers[i].signature);
51 m->root_container.index = 0;
54 static void message_free(sd_bus_message *m) {
70 close_many(m->fds, m->n_fds);
74 free(m->cmdline_array);
77 free(m->root_container.signature);
79 free(m->peeked_signature);
87 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
95 start = ALIGN_TO((size_t) *sz, align);
99 return (uint8_t*) *p + start;
101 if (n > (size_t) ((uint32_t) -1))
108 /* Zero out padding */
110 memset((uint8_t*) k + *sz, 0, start - *sz);
115 return (uint8_t*) k + start;
118 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
124 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
128 if (o != m->fields) {
129 /* Adjust quick access pointers */
132 m->path = (const char*) m->fields + (m->path - (const char*) o);
134 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
136 m->member = (const char*) m->fields + (m->member - (const char*) o);
138 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
140 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
142 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
145 m->free_fields = true;
150 static int message_append_field_string(
163 if (l > (size_t) (uint32_t) -1)
166 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
167 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
176 ((uint32_t*) p)[1] = l;
177 memcpy(p + 8, s, l + 1);
180 *ret = (const char*) p + 8;
185 static int message_append_field_signature(
200 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
201 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
207 p[2] = SD_BUS_TYPE_SIGNATURE;
210 memcpy(p + 5, s, l + 1);
213 *ret = (const char*) p + 5;
218 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
223 /* field id byte + signature length + signature 'u' + NUL + value */
224 p = message_extend_fields(m, 8, 4 + 4);
230 p[2] = SD_BUS_TYPE_UINT32;
233 ((uint32_t*) p)[1] = x;
238 int bus_message_from_header(
243 const struct ucred *ucred,
246 sd_bus_message **ret) {
249 struct bus_header *h;
252 assert(buffer || length <= 0);
253 assert(fds || n_fds <= 0);
256 if (length < sizeof(struct bus_header))
266 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
269 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
270 h->endian != SD_BUS_BIG_ENDIAN)
273 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
276 label_sz = strlen(label);
294 m->uid_valid = m->gid_valid = true;
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
299 memcpy(m->label, label, label_sz + 1);
306 int bus_message_from_malloc(
311 const struct ucred *ucred,
313 sd_bus_message **ret) {
318 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
322 if (length != BUS_MESSAGE_SIZE(m)) {
327 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
328 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
331 m->iovec[0].iov_base = buffer;
332 m->iovec[0].iov_len = length;
334 r = bus_message_parse_fields(m);
338 /* We take possession of the memory and fds now */
339 m->free_header = true;
350 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
353 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
358 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
359 m->header->endian = SD_BUS_NATIVE_ENDIAN;
360 m->header->type = type;
361 m->header->version = bus ? bus->message_version : 1;
362 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
367 int sd_bus_message_new_signal(
370 const char *interface,
372 sd_bus_message **m) {
385 if (bus && bus->state == BUS_UNSET)
388 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
392 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
394 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
397 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
400 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
408 sd_bus_message_unref(t);
412 int sd_bus_message_new_method_call(
414 const char *destination,
416 const char *interface,
418 sd_bus_message **m) {
429 if (bus && bus->state == BUS_UNSET)
432 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
436 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
439 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
444 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
450 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
463 static int message_new_reply(
465 sd_bus_message *call,
467 sd_bus_message **m) {
476 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
480 if (bus && bus->state == BUS_UNSET)
483 t = message_new(bus, type);
487 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
488 t->reply_serial = BUS_MESSAGE_SERIAL(call);
490 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
495 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
500 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
510 int sd_bus_message_new_method_return(
512 sd_bus_message *call,
513 sd_bus_message **m) {
515 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
518 int sd_bus_message_new_method_error(
520 sd_bus_message *call,
521 const sd_bus_error *e,
522 sd_bus_message **m) {
527 if (!sd_bus_error_is_set(e))
532 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
536 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
541 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
554 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
558 assert(m->n_ref > 0);
564 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
568 assert(m->n_ref > 0);
577 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
583 *type = m->header->type;
587 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
592 if (m->header->serial == 0)
595 *serial = BUS_MESSAGE_SERIAL(m);
599 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
604 if (m->reply_serial == 0)
607 *serial = m->reply_serial;
611 int sd_bus_message_get_no_reply(sd_bus_message *m) {
615 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
618 const char *sd_bus_message_get_path(sd_bus_message *m) {
625 const char *sd_bus_message_get_interface(sd_bus_message *m) {
632 const char *sd_bus_message_get_member(sd_bus_message *m) {
638 const char *sd_bus_message_get_destination(sd_bus_message *m) {
642 return m->destination;
645 const char *sd_bus_message_get_sender(sd_bus_message *m) {
652 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
656 if (!sd_bus_error_is_set(&m->error))
662 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
674 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
686 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
698 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
710 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
715 if (m->pid_starttime <= 0)
718 *usec = m->pid_starttime;
722 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
732 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
737 if (m->monotonic <= 0)
740 *usec = m->monotonic;
744 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
749 if (m->realtime <= 0)
756 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
768 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
780 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
792 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
804 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
815 r = cg_path_get_unit(m->cgroup, &m->unit);
824 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
835 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
844 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
855 r = cg_path_get_session(m->cgroup, &m->session);
864 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
875 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
879 m->cmdline_array = new(char*, n + 1);
880 if (!m->cmdline_array)
883 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
885 m->cmdline_array[i++] = (char*) p;
890 m->cmdline_array[i] = NULL;
891 *cmdline = m->cmdline_array;
896 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
900 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
903 if (interface && (!m->interface || !streq(m->interface, interface)))
906 if (member && (!m->member || !streq(m->member, member)))
912 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
916 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
919 if (interface && (!m->interface || !streq(m->interface, interface)))
922 if (member && (!m->member || !streq(m->member, member)))
928 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
932 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
935 if (name && (!m->error.name || !streq(m->error.name, name)))
941 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
946 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
950 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
952 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
957 static struct bus_container *message_get_container(sd_bus_message *m) {
960 if (m->n_containers == 0)
961 return &m->root_container;
963 assert(m->containers);
964 return m->containers + m->n_containers - 1;
967 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
970 struct bus_container *c;
976 added = m->header->body_size;
978 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
982 added = m->header->body_size - added;
984 for (c = m->containers; c < m->containers + m->n_containers; c++)
986 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
987 *c->array_size += added;
991 if (m->error.message)
992 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1000 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1001 struct bus_container *c;
1016 if (!bus_type_is_basic(type))
1019 c = message_get_container(m);
1021 if (c->signature && c->signature[c->index]) {
1022 /* Container signature is already set */
1024 if (c->signature[c->index] != type)
1027 /* Maybe we can append to the signature? But only if this is the top-level container*/
1028 if (c->enclosing != 0)
1031 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1038 case SD_BUS_TYPE_STRING:
1039 case SD_BUS_TYPE_OBJECT_PATH:
1042 sz = 4 + strlen(p) + 1;
1045 case SD_BUS_TYPE_SIGNATURE:
1048 sz = 1 + strlen(p) + 1;
1051 case SD_BUS_TYPE_BOOLEAN:
1054 assert_cc(sizeof(int) == sizeof(uint32_t));
1060 case SD_BUS_TYPE_UNIX_FD: {
1063 if (!m->allow_fds) {
1076 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1082 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1096 align = bus_type_get_alignment(type);
1097 sz = bus_type_get_size(type);
1104 a = message_extend_body(m, align, sz);
1110 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1111 *(uint32_t*) a = sz - 5;
1112 memcpy((uint8_t*) a + 4, p, sz - 4);
1115 *stored = (const uint8_t*) a + 4;
1117 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1118 *(uint8_t*) a = sz - 1;
1119 memcpy((uint8_t*) a + 1, p, sz - 1);
1122 *stored = (const uint8_t*) a + 1;
1123 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1124 *(uint32_t*) a = fdi;
1138 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1144 /* Truncate extended signature again */
1146 c->signature[c->index] = 0;
1149 close_nointr_nofail(fd);
1154 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1155 return message_append_basic(m, type, p, NULL);
1158 static int bus_message_open_array(
1160 struct bus_container *c,
1161 const char *contents,
1162 uint32_t **array_size) {
1175 if (!signature_is_single(contents))
1178 alignment = bus_type_get_alignment(contents[0]);
1182 if (c->signature && c->signature[c->index]) {
1184 /* Verify the existing signature */
1186 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1189 if (!startswith(c->signature + c->index + 1, contents))
1192 nindex = c->index + 1 + strlen(contents);
1194 if (c->enclosing != 0)
1197 /* Extend the existing signature */
1199 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1203 nindex = e - c->signature;
1206 saved = m->header->body_size;
1207 a = message_extend_body(m, 4, 4);
1209 /* Truncate extended signature again */
1211 c->signature[c->index] = 0;
1217 if (!message_extend_body(m, alignment, 0)) {
1218 /* Add alignment between size and first element */
1220 c->signature[c->index] = 0;
1222 m->header->body_size = saved;
1226 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1229 /* m->body might have changed so let's readjust a */
1230 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1237 static int bus_message_open_variant(
1239 struct bus_container *c,
1240 const char *contents) {
1250 if (!signature_is_single(contents))
1253 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1256 if (c->signature && c->signature[c->index]) {
1258 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1262 if (c->enclosing != 0)
1265 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1270 l = strlen(contents);
1271 a = message_extend_body(m, 1, 1 + l + 1);
1273 /* Truncate extended signature again */
1275 c->signature[c->index] = 0;
1281 memcpy((uint8_t*) a + 1, contents, l + 1);
1283 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1289 static int bus_message_open_struct(
1291 struct bus_container *c,
1292 const char *contents) {
1301 if (!signature_is_valid(contents, false))
1304 if (c->signature && c->signature[c->index]) {
1307 l = strlen(contents);
1309 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1310 !startswith(c->signature + c->index + 1, contents) ||
1311 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1314 nindex = c->index + 1 + l + 1;
1316 if (c->enclosing != 0)
1319 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1323 nindex = e - c->signature;
1326 /* Align contents to 8 byte boundary */
1327 if (!message_extend_body(m, 8, 0)) {
1329 c->signature[c->index] = 0;
1334 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1340 static int bus_message_open_dict_entry(
1342 struct bus_container *c,
1343 const char *contents) {
1351 if (!signature_is_pair(contents))
1354 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1357 if (c->signature && c->signature[c->index]) {
1360 l = strlen(contents);
1362 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1363 !startswith(c->signature + c->index + 1, contents) ||
1364 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1367 nindex = c->index + 1 + l + 1;
1371 /* Align contents to 8 byte boundary */
1372 if (!message_extend_body(m, 8, 0))
1375 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1381 int sd_bus_message_open_container(
1384 const char *contents) {
1386 struct bus_container *c, *w;
1387 uint32_t *array_size = NULL;
1398 /* Make sure we have space for one more container */
1399 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1404 c = message_get_container(m);
1406 signature = strdup(contents);
1410 if (type == SD_BUS_TYPE_ARRAY)
1411 r = bus_message_open_array(m, c, contents, &array_size);
1412 else if (type == SD_BUS_TYPE_VARIANT)
1413 r = bus_message_open_variant(m, c, contents);
1414 else if (type == SD_BUS_TYPE_STRUCT)
1415 r = bus_message_open_struct(m, c, contents);
1416 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1417 r = bus_message_open_dict_entry(m, c, contents);
1426 /* OK, let's fill it in */
1427 w += m->n_containers++;
1428 w->enclosing = type;
1429 w->signature = signature;
1431 w->array_size = array_size;
1437 int sd_bus_message_close_container(sd_bus_message *m) {
1438 struct bus_container *c;
1444 if (m->n_containers <= 0)
1447 c = message_get_container(m);
1448 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1449 if (c->signature && c->signature[c->index] != 0)
1465 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1472 stack[*i].types = types;
1473 stack[*i].n_struct = n_struct;
1474 stack[*i].n_array = n_array;
1480 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1491 *types = stack[*i].types;
1492 *n_struct = stack[*i].n_struct;
1493 *n_array = stack[*i].n_array;
1498 int bus_message_append_ap(
1503 unsigned n_array, n_struct;
1504 TypeStack stack[BUS_CONTAINER_DEPTH];
1505 unsigned stack_ptr = 0;
1513 n_array = (unsigned) -1;
1514 n_struct = strlen(types);
1519 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1520 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1526 r = sd_bus_message_close_container(m);
1534 if (n_array != (unsigned) -1)
1543 case SD_BUS_TYPE_BYTE: {
1546 x = (uint8_t) va_arg(ap, int);
1547 r = sd_bus_message_append_basic(m, *t, &x);
1551 case SD_BUS_TYPE_BOOLEAN:
1552 case SD_BUS_TYPE_INT32:
1553 case SD_BUS_TYPE_UINT32:
1554 case SD_BUS_TYPE_UNIX_FD: {
1557 /* We assume a boolean is the same as int32_t */
1558 assert_cc(sizeof(int32_t) == sizeof(int));
1560 x = va_arg(ap, uint32_t);
1561 r = sd_bus_message_append_basic(m, *t, &x);
1565 case SD_BUS_TYPE_INT16:
1566 case SD_BUS_TYPE_UINT16: {
1569 x = (uint16_t) va_arg(ap, int);
1570 r = sd_bus_message_append_basic(m, *t, &x);
1574 case SD_BUS_TYPE_INT64:
1575 case SD_BUS_TYPE_UINT64:
1576 case SD_BUS_TYPE_DOUBLE: {
1579 x = va_arg(ap, uint64_t);
1580 r = sd_bus_message_append_basic(m, *t, &x);
1584 case SD_BUS_TYPE_STRING:
1585 case SD_BUS_TYPE_OBJECT_PATH:
1586 case SD_BUS_TYPE_SIGNATURE: {
1589 x = va_arg(ap, const char*);
1590 r = sd_bus_message_append_basic(m, *t, x);
1594 case SD_BUS_TYPE_ARRAY: {
1597 r = signature_element_length(t + 1, &k);
1603 memcpy(s, t + 1, k);
1606 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1611 if (n_array == (unsigned) -1) {
1616 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1622 n_array = va_arg(ap, unsigned);
1627 case SD_BUS_TYPE_VARIANT: {
1630 s = va_arg(ap, const char*);
1634 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1638 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1643 n_struct = strlen(s);
1644 n_array = (unsigned) -1;
1649 case SD_BUS_TYPE_STRUCT_BEGIN:
1650 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1653 r = signature_element_length(t, &k);
1660 memcpy(s, t + 1, k - 2);
1663 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1668 if (n_array == (unsigned) -1) {
1673 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1679 n_array = (unsigned) -1;
1695 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1706 va_start(ap, types);
1707 r = bus_message_append_ap(m, types, ap);
1713 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1719 start = ALIGN_TO((size_t) *rindex, align);
1725 /* Verify that padding is 0 */
1726 for (k = *rindex; k < start; k++)
1727 if (((const uint8_t*) p)[k] != 0)
1731 *r = (uint8_t*) p + start;
1738 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1739 struct bus_container *c;
1743 c = message_get_container(m);
1747 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1750 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1755 if (message_end_of_array(m, *rindex))
1758 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1761 static bool validate_nul(const char *s, size_t l) {
1763 /* Check for NUL chars in the string */
1764 if (memchr(s, 0, l))
1767 /* Check for NUL termination */
1774 static bool validate_string(const char *s, size_t l) {
1776 if (!validate_nul(s, l))
1779 /* Check if valid UTF8 */
1780 if (!utf8_is_valid(s))
1786 static bool validate_signature(const char *s, size_t l) {
1788 if (!validate_nul(s, l))
1791 /* Check if valid signature */
1792 if (!signature_is_valid(s, true))
1798 static bool validate_object_path(const char *s, size_t l) {
1800 if (!validate_nul(s, l))
1803 if (!object_path_is_valid(s))
1809 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1810 struct bus_container *c;
1818 if (!bus_type_is_basic(type))
1823 c = message_get_container(m);
1825 if (!c->signature || c->signature[c->index] == 0)
1828 if (c->signature[c->index] != type)
1833 case SD_BUS_TYPE_STRING:
1834 case SD_BUS_TYPE_OBJECT_PATH: {
1839 r = message_peek_body(m, &rindex, 4, 4, &q);
1843 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1844 r = message_peek_body(m, &rindex, 1, l+1, &q);
1850 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1851 if (!validate_object_path(q, l))
1854 if (!validate_string(q, l))
1859 *(const char**) p = q;
1863 case SD_BUS_TYPE_SIGNATURE: {
1868 r = message_peek_body(m, &rindex, 1, 1, &q);
1873 r = message_peek_body(m, &rindex, 1, l+1, &q);
1879 if (!validate_signature(q, l))
1883 *(const char**) p = q;
1891 align = bus_type_get_alignment(type);
1892 sz = bus_type_get_size(type);
1893 assert(align > 0 && sz > 0);
1896 r = message_peek_body(m, &rindex, align, sz, &q);
1902 case SD_BUS_TYPE_BYTE:
1903 *(uint8_t*) p = *(uint8_t*) q;
1906 case SD_BUS_TYPE_BOOLEAN:
1907 *(int*) p = !!*(uint32_t*) q;
1910 case SD_BUS_TYPE_INT16:
1911 case SD_BUS_TYPE_UINT16:
1912 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1915 case SD_BUS_TYPE_INT32:
1916 case SD_BUS_TYPE_UINT32:
1917 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1920 case SD_BUS_TYPE_INT64:
1921 case SD_BUS_TYPE_UINT64:
1922 case SD_BUS_TYPE_DOUBLE:
1923 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1926 case SD_BUS_TYPE_UNIX_FD: {
1929 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1933 *(int*) p = m->fds[j];
1938 assert_not_reached("Unknown basic type...");
1947 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1953 static int bus_message_enter_array(
1955 struct bus_container *c,
1956 const char *contents,
1957 uint32_t **array_size) {
1968 if (!signature_is_single(contents))
1971 alignment = bus_type_get_alignment(contents[0]);
1975 if (!c->signature || c->signature[c->index] == 0)
1978 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1981 if (!startswith(c->signature + c->index + 1, contents))
1985 r = message_peek_body(m, &rindex, 4, 4, &q);
1989 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1992 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1998 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1999 c->index += 1 + strlen(contents);
2003 *array_size = (uint32_t*) q;
2008 static int bus_message_enter_variant(
2010 struct bus_container *c,
2011 const char *contents) {
2022 if (!signature_is_single(contents))
2025 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2028 if (!c->signature || c->signature[c->index] == 0)
2031 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2035 r = message_peek_body(m, &rindex, 1, 1, &q);
2040 r = message_peek_body(m, &rindex, 1, l+1, &q);
2046 if (!validate_signature(q, l))
2049 if (!streq(q, contents))
2052 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2060 static int bus_message_enter_struct(
2062 struct bus_container *c,
2063 const char *contents) {
2072 if (!signature_is_valid(contents, false))
2075 if (!c->signature || c->signature[c->index] == 0)
2078 l = strlen(contents);
2080 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2081 !startswith(c->signature + c->index + 1, contents) ||
2082 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2085 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2089 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2090 c->index += 1 + l + 1;
2095 static int bus_message_enter_dict_entry(
2097 struct bus_container *c,
2098 const char *contents) {
2107 if (!signature_is_pair(contents))
2110 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2113 if (!c->signature || c->signature[c->index] == 0)
2116 l = strlen(contents);
2118 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2119 !startswith(c->signature + c->index + 1, contents) ||
2120 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2123 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2127 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2128 c->index += 1 + l + 1;
2133 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2134 struct bus_container *c, *w;
2135 uint32_t *array_size = NULL;
2147 * We enforce a global limit on container depth, that is much
2148 * higher than the 32 structs and 32 arrays the specification
2149 * mandates. This is simpler to implement for us, and we need
2150 * this only to ensure our container array doesn't grow
2151 * without bounds. We are happy to return any data from a
2152 * message as long as the data itself is valid, even if the
2153 * overall message might be not.
2155 * Note that the message signature is validated when
2156 * parsing the headers, and that validation does check the
2159 * Note that the specification defines no limits on the depth
2160 * of stacked variants, but we do.
2162 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2165 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2170 c = message_get_container(m);
2172 if (!c->signature || c->signature[c->index] == 0)
2175 signature = strdup(contents);
2179 if (type == SD_BUS_TYPE_ARRAY)
2180 r = bus_message_enter_array(m, c, contents, &array_size);
2181 else if (type == SD_BUS_TYPE_VARIANT)
2182 r = bus_message_enter_variant(m, c, contents);
2183 else if (type == SD_BUS_TYPE_STRUCT)
2184 r = bus_message_enter_struct(m, c, contents);
2185 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2186 r = bus_message_enter_dict_entry(m, c, contents);
2195 /* OK, let's fill it in */
2196 w += m->n_containers++;
2197 w->enclosing = type;
2198 w->signature = signature;
2200 w->array_size = array_size;
2201 w->begin = m->rindex;
2206 int sd_bus_message_exit_container(sd_bus_message *m) {
2207 struct bus_container *c;
2213 if (m->n_containers <= 0)
2216 c = message_get_container(m);
2217 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2220 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2221 if (c->begin + l != m->rindex)
2225 if (c->signature && c->signature[c->index] != 0)
2235 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2236 struct bus_container *c;
2244 c = message_get_container(m);
2246 if (!c->signature || c->signature[c->index] == 0)
2249 if (message_end_of_array(m, m->rindex))
2252 if (bus_type_is_basic(c->signature[c->index])) {
2256 *type = c->signature[c->index];
2260 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2266 r = signature_element_length(c->signature+c->index+1, &l);
2272 sig = strndup(c->signature + c->index + 1, l);
2276 free(m->peeked_signature);
2277 m->peeked_signature = sig;
2283 *type = SD_BUS_TYPE_ARRAY;
2288 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2289 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2295 r = signature_element_length(c->signature+c->index, &l);
2300 sig = strndup(c->signature + c->index + 1, l - 2);
2304 free(m->peeked_signature);
2305 m->peeked_signature = sig;
2311 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2316 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2322 r = message_peek_body(m, &rindex, 1, 1, &q);
2329 r = message_peek_body(m, &rindex, 1, l+1, &q);
2335 if (!validate_signature(q, l))
2342 *type = SD_BUS_TYPE_VARIANT;
2351 *type = c->enclosing;
2357 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2358 struct bus_container *c;
2366 reset_containers(m);
2368 m->root_container.index = 0;
2370 c = message_get_container(m);
2372 c = message_get_container(m);
2375 m->rindex = c->begin;
2378 return !isempty(c->signature);
2380 static int message_read_ap(
2385 unsigned n_array, n_struct;
2386 TypeStack stack[BUS_CONTAINER_DEPTH];
2387 unsigned stack_ptr = 0;
2395 /* Ideally, we'd just call ourselves recursively on every
2396 * complex type. However, the state of a va_list that is
2397 * passed to a function is undefined after that function
2398 * returns. This means we need to docode the va_list linearly
2399 * in a single stackframe. We hence implement our own
2400 * home-grown stack in an array. */
2402 n_array = (unsigned) -1;
2403 n_struct = strlen(types);
2408 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2409 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2415 r = sd_bus_message_exit_container(m);
2423 if (n_array != (unsigned) -1)
2432 case SD_BUS_TYPE_BYTE:
2433 case SD_BUS_TYPE_BOOLEAN:
2434 case SD_BUS_TYPE_INT16:
2435 case SD_BUS_TYPE_UINT16:
2436 case SD_BUS_TYPE_INT32:
2437 case SD_BUS_TYPE_UINT32:
2438 case SD_BUS_TYPE_INT64:
2439 case SD_BUS_TYPE_UINT64:
2440 case SD_BUS_TYPE_DOUBLE:
2441 case SD_BUS_TYPE_STRING:
2442 case SD_BUS_TYPE_OBJECT_PATH:
2443 case SD_BUS_TYPE_SIGNATURE:
2444 case SD_BUS_TYPE_UNIX_FD: {
2447 p = va_arg(ap, void*);
2448 r = sd_bus_message_read_basic(m, *t, p);
2457 case SD_BUS_TYPE_ARRAY: {
2460 r = signature_element_length(t + 1, &k);
2466 memcpy(s, t + 1, k);
2469 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2476 if (n_array == (unsigned) -1) {
2481 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2487 n_array = va_arg(ap, unsigned);
2492 case SD_BUS_TYPE_VARIANT: {
2495 s = va_arg(ap, const char *);
2499 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2505 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2510 n_struct = strlen(s);
2511 n_array = (unsigned) -1;
2516 case SD_BUS_TYPE_STRUCT_BEGIN:
2517 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2520 r = signature_element_length(t, &k);
2526 memcpy(s, t + 1, k - 2);
2529 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2536 if (n_array == (unsigned) -1) {
2541 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2547 n_array = (unsigned) -1;
2560 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2571 va_start(ap, types);
2572 r = message_read_ap(m, types, ap);
2578 static int message_peek_fields(
2589 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2592 static int message_peek_field_uint32(
2603 r = message_peek_fields(m, ri, 4, 4, &q);
2608 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2613 static int message_peek_field_string(
2615 bool (*validate)(const char *p),
2626 r = message_peek_field_uint32(m, ri, &l);
2630 r = message_peek_fields(m, ri, 1, l+1, &q);
2635 if (!validate_nul(q, l))
2641 if (!validate_string(q, l))
2651 static int message_peek_field_signature(
2663 r = message_peek_fields(m, ri, 1, 1, &q);
2668 r = message_peek_fields(m, ri, 1, l+1, &q);
2672 if (!validate_signature(q, l))
2681 static int message_skip_fields(
2684 uint32_t array_size,
2685 const char **signature) {
2687 size_t original_index;
2694 original_index = *ri;
2700 if (array_size != (uint32_t) -1 &&
2701 array_size <= *ri - original_index)
2708 if (t == SD_BUS_TYPE_STRING) {
2710 r = message_peek_field_string(m, NULL, ri, NULL);
2716 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2718 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2724 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2726 r = message_peek_field_signature(m, ri, NULL);
2732 } else if (bus_type_is_basic(t)) {
2735 align = bus_type_get_alignment(t);
2736 k = bus_type_get_size(t);
2737 assert(align > 0 && k > 0);
2739 r = message_peek_fields(m, ri, align, k, NULL);
2745 } else if (t == SD_BUS_TYPE_ARRAY) {
2747 r = signature_element_length(*signature+1, &l);
2757 strncpy(sig, *signature + 1, l-1);
2760 alignment = bus_type_get_alignment(sig[0]);
2764 r = message_peek_field_uint32(m, ri, &nas);
2767 if (nas > BUS_ARRAY_MAX_SIZE)
2770 r = message_peek_fields(m, ri, alignment, 0, NULL);
2774 r = message_skip_fields(m, ri, nas, (const char**) &s);
2779 (*signature) += 1 + l;
2781 } else if (t == SD_BUS_TYPE_VARIANT) {
2784 r = message_peek_field_signature(m, ri, &s);
2788 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2794 } else if (t == SD_BUS_TYPE_STRUCT ||
2795 t == SD_BUS_TYPE_DICT_ENTRY) {
2797 r = signature_element_length(*signature, &l);
2804 strncpy(sig, *signature + 1, l-1);
2807 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2818 int bus_message_parse_fields(sd_bus_message *m) {
2821 uint32_t unix_fds = 0;
2825 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2826 const char *signature;
2829 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2833 r = message_peek_field_signature(m, &ri, &signature);
2838 case _SD_BUS_MESSAGE_HEADER_INVALID:
2841 case SD_BUS_MESSAGE_HEADER_PATH:
2846 if (!streq(signature, "o"))
2849 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2852 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2857 if (!streq(signature, "s"))
2860 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2863 case SD_BUS_MESSAGE_HEADER_MEMBER:
2868 if (!streq(signature, "s"))
2871 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2874 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2879 if (!streq(signature, "s"))
2882 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2885 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2890 if (!streq(signature, "s"))
2893 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2896 case SD_BUS_MESSAGE_HEADER_SENDER:
2901 if (!streq(signature, "s"))
2904 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2908 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2912 if (m->root_container.signature)
2915 if (!streq(signature, "g"))
2918 r = message_peek_field_signature(m, &ri, &s);
2926 free(m->root_container.signature);
2927 m->root_container.signature = c;
2931 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2932 if (m->reply_serial != 0)
2935 if (!streq(signature, "u"))
2938 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2942 if (m->reply_serial == 0)
2947 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2951 if (!streq(signature, "u"))
2954 r = message_peek_field_uint32(m, &ri, &unix_fds);
2964 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2971 if (m->n_fds != unix_fds)
2974 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2977 switch (m->header->type) {
2979 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2980 if (!m->path || !m->interface || !m->member)
2984 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2986 if (!m->path || !m->member)
2991 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2993 if (m->reply_serial == 0)
2997 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2999 if (m->reply_serial == 0 || !m->error.name)
3004 /* Try to read the error message, but if we can't it's a non-issue */
3005 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3006 sd_bus_message_read(m, "s", &m->error.message);
3011 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3020 if (m->n_containers > 0)
3023 /* If there's a non-trivial signature set, then add it in here */
3024 if (!isempty(m->root_container.signature)) {
3025 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3031 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3036 l = BUS_MESSAGE_FIELDS_SIZE(m);
3040 /* Add padding at the end, since we know the body
3041 * needs to start at an 8 byte alignment. */
3044 p = message_extend_fields(m, 1, a);
3049 m->header->fields_size -= a;
3052 m->header->serial = serial;
3058 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3068 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3071 int bus_message_dump(sd_bus_message *m) {
3072 const char *u = NULL, *uu = NULL, *s = NULL;
3073 char **cmdline = NULL;
3079 printf("Message %p\n"
3086 "\tfields_size=%u\n"
3091 "\tdestination=%s\n"
3094 "\treply_serial=%u\n"
3096 "\terror.message=%s\n"
3104 BUS_MESSAGE_SERIAL(m),
3105 BUS_MESSAGE_FIELDS_SIZE(m),
3106 BUS_MESSAGE_BODY_SIZE(m),
3108 strna(m->interface),
3110 strna(m->destination),
3112 strna(m->root_container.signature),
3114 strna(m->error.name),
3115 strna(m->error.message),
3119 printf("\tpid=%lu\n", (unsigned long) m->pid);
3121 printf("\ttid=%lu\n", (unsigned long) m->tid);
3123 printf("\tuid=%lu\n", (unsigned long) m->uid);
3125 printf("\tgid=%lu\n", (unsigned long) m->gid);
3126 if (m->pid_starttime != 0)
3127 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3128 if (m->monotonic != 0)
3129 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3130 if (m->realtime != 0)
3131 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3133 printf("\texe=[%s]\n", m->exe);
3135 printf("\tcomm=[%s]\n", m->comm);
3137 printf("\ttid_comm=[%s]\n", m->tid_comm);
3139 printf("\tlabel=[%s]\n", m->label);
3141 printf("\tcgroup=[%s]\n", m->cgroup);
3143 sd_bus_message_get_unit(m, &u);
3145 printf("\tunit=[%s]\n", u);
3146 sd_bus_message_get_user_unit(m, &uu);
3148 printf("\tuser_unit=[%s]\n", uu);
3149 sd_bus_message_get_session(m, &s);
3151 printf("\tsession=[%s]\n", s);
3153 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3156 fputs("\tcmdline=[", stdout);
3157 STRV_FOREACH(c, cmdline) {
3164 fputs("]\n", stdout);
3167 r = sd_bus_message_rewind(m, true);
3169 log_error("Failed to rewind: %s", strerror(-r));
3173 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3176 _cleanup_free_ char *prefix = NULL;
3177 const char *contents = NULL;
3192 r = sd_bus_message_peek_type(m, &type, &contents);
3194 log_error("Failed to peek type: %s", strerror(-r));
3201 r = sd_bus_message_exit_container(m);
3203 log_error("Failed to exit container: %s", strerror(-r));
3209 prefix = strrep("\t", level);
3213 if (type == SD_BUS_TYPE_ARRAY)
3214 printf("%s} END_ARRAY \n", prefix);
3215 else if (type == SD_BUS_TYPE_VARIANT)
3216 printf("%s} END_VARIANT\n", prefix);
3217 else if (type == SD_BUS_TYPE_STRUCT)
3218 printf("%s} END_STRUCT\n", prefix);
3219 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3220 printf("%s} END_DICT_ENTRY\n", prefix);
3225 prefix = strrep("\t", level);
3229 if (bus_type_is_container(type) > 0) {
3230 r = sd_bus_message_enter_container(m, type, contents);
3232 log_error("Failed to enter container: %s", strerror(-r));
3236 if (type == SD_BUS_TYPE_ARRAY)
3237 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3238 else if (type == SD_BUS_TYPE_VARIANT)
3239 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3240 else if (type == SD_BUS_TYPE_STRUCT)
3241 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3242 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3243 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3250 r = sd_bus_message_read_basic(m, type, &basic);
3252 log_error("Failed to get basic: %s", strerror(-r));
3258 case SD_BUS_TYPE_BYTE:
3259 printf("%sBYTE: %u\n", prefix, basic.u8);
3262 case SD_BUS_TYPE_BOOLEAN:
3263 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3266 case SD_BUS_TYPE_INT16:
3267 printf("%sINT16: %i\n", prefix, basic.s16);
3270 case SD_BUS_TYPE_UINT16:
3271 printf("%sUINT16: %u\n", prefix, basic.u16);
3274 case SD_BUS_TYPE_INT32:
3275 printf("%sINT32: %i\n", prefix, basic.s32);
3278 case SD_BUS_TYPE_UINT32:
3279 printf("%sUINT32: %u\n", prefix, basic.u32);
3282 case SD_BUS_TYPE_INT64:
3283 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3286 case SD_BUS_TYPE_UINT64:
3287 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3290 case SD_BUS_TYPE_DOUBLE:
3291 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3294 case SD_BUS_TYPE_STRING:
3295 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3298 case SD_BUS_TYPE_OBJECT_PATH:
3299 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3302 case SD_BUS_TYPE_SIGNATURE:
3303 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3306 case SD_BUS_TYPE_UNIX_FD:
3307 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3311 assert_not_reached("Unknown basic type.");
3315 printf("} END_MESSAGE\n");
3319 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3327 total = BUS_MESSAGE_SIZE(m);
3333 e = mempcpy(p, m->header, sizeof(*m->header));
3336 e = mempcpy(e, m->fields, m->header->fields_size);
3338 if (m->header->fields_size % 8 != 0)
3339 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3343 e = mempcpy(e, m->body, m->header->body_size);
3345 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3353 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3359 r = sd_bus_message_enter_container(m, 'a', "s");
3366 r = sd_bus_message_read_basic(m, 's', &s);
3372 r = strv_extend(l, s);
3377 r = sd_bus_message_exit_container(m);
3384 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3386 const char *t = NULL;
3391 r = sd_bus_message_rewind(m, true);
3395 for (j = 0; j <= i; j++) {
3398 r = sd_bus_message_peek_type(m, &type, NULL);
3402 if (type != SD_BUS_TYPE_STRING &&
3403 type != SD_BUS_TYPE_OBJECT_PATH &&
3404 type != SD_BUS_TYPE_SIGNATURE)
3407 r = sd_bus_message_read_basic(m, type, &t);
3415 int bus_header_size(struct bus_header *h, size_t *sum) {
3421 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3422 fs = h->fields_size;
3424 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3425 fs = bswap_32(h->fields_size);
3426 bs = bswap_32(h->body_size);
3430 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;