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"
31 #include "bus-message.h"
32 #include "bus-internal.h"
34 #include "bus-signature.h"
36 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
38 static void reset_containers(sd_bus_message *m) {
43 for (i = 0; i < m->n_containers; i++)
44 free(m->containers[i].signature);
50 m->root_container.index = 0;
53 static void message_free(sd_bus_message *m) {
69 close_many(m->fds, m->n_fds);
73 free(m->cmdline_array);
76 free(m->root_container.signature);
78 free(m->peeked_signature);
82 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
90 start = ALIGN_TO((size_t) *sz, align);
94 return (uint8_t*) *p + start;
96 if (n > (size_t) ((uint32_t) -1))
103 /* Zero out padding */
105 memset((uint8_t*) k + *sz, 0, start - *sz);
110 return (uint8_t*) k + start;
113 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
119 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
123 if (o != m->fields) {
124 /* Adjust quick access pointers */
127 m->path = (const char*) m->fields + (m->path - (const char*) o);
129 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
131 m->member = (const char*) m->fields + (m->member - (const char*) o);
133 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
135 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
137 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
140 m->free_fields = true;
145 static int message_append_field_string(
158 if (l > (size_t) (uint32_t) -1)
161 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
162 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
171 ((uint32_t*) p)[1] = l;
172 memcpy(p + 8, s, l + 1);
175 *ret = (const char*) p + 8;
180 static int message_append_field_signature(
195 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
196 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
202 p[2] = SD_BUS_TYPE_SIGNATURE;
205 memcpy(p + 5, s, l + 1);
208 *ret = (const char*) p + 5;
213 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
218 /* field id byte + signature length + signature 'u' + NUL + value */
219 p = message_extend_fields(m, 8, 4 + 4);
225 p[2] = SD_BUS_TYPE_UINT32;
228 ((uint32_t*) p)[1] = x;
233 int bus_message_from_header(
238 const struct ucred *ucred,
241 sd_bus_message **ret) {
244 struct bus_header *h;
247 assert(buffer || length <= 0);
248 assert(fds || n_fds <= 0);
251 if (length < sizeof(struct bus_header))
261 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
264 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
265 h->endian != SD_BUS_BIG_ENDIAN)
268 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
271 label_sz = strlen(label);
289 m->uid_valid = m->gid_valid = true;
293 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
294 memcpy(m->label, label, label_sz + 1);
301 int bus_message_from_malloc(
306 const struct ucred *ucred,
308 sd_bus_message **ret) {
313 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
317 if (length != BUS_MESSAGE_SIZE(m)) {
322 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
323 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
326 m->iovec[0].iov_base = buffer;
327 m->iovec[0].iov_len = length;
329 r = bus_message_parse_fields(m);
333 /* We take possession of the memory and fds now */
334 m->free_header = true;
345 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
348 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
353 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
354 m->header->endian = SD_BUS_NATIVE_ENDIAN;
355 m->header->type = type;
356 m->header->version = bus ? bus->message_version : 1;
357 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
362 int sd_bus_message_new_signal(
365 const char *interface,
367 sd_bus_message **m) {
380 if (bus && bus->state == BUS_UNSET)
383 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
387 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
389 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
392 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
395 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
403 sd_bus_message_unref(t);
407 int sd_bus_message_new_method_call(
409 const char *destination,
411 const char *interface,
413 sd_bus_message **m) {
424 if (bus && bus->state == BUS_UNSET)
427 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
431 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
434 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
439 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
445 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
458 static int message_new_reply(
460 sd_bus_message *call,
462 sd_bus_message **m) {
471 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
475 if (bus && bus->state == BUS_UNSET)
478 t = message_new(bus, type);
482 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
483 t->reply_serial = BUS_MESSAGE_SERIAL(call);
485 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
490 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
495 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
505 int sd_bus_message_new_method_return(
507 sd_bus_message *call,
508 sd_bus_message **m) {
510 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
513 int sd_bus_message_new_method_error(
515 sd_bus_message *call,
516 const sd_bus_error *e,
517 sd_bus_message **m) {
522 if (!sd_bus_error_is_set(e))
527 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
531 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
536 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
549 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
553 assert(m->n_ref > 0);
559 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
563 assert(m->n_ref > 0);
572 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
578 *type = m->header->type;
582 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
587 if (m->header->serial == 0)
590 *serial = BUS_MESSAGE_SERIAL(m);
594 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
599 if (m->reply_serial == 0)
602 *serial = m->reply_serial;
606 int sd_bus_message_get_no_reply(sd_bus_message *m) {
610 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
613 const char *sd_bus_message_get_path(sd_bus_message *m) {
620 const char *sd_bus_message_get_interface(sd_bus_message *m) {
627 const char *sd_bus_message_get_member(sd_bus_message *m) {
633 const char *sd_bus_message_get_destination(sd_bus_message *m) {
637 return m->destination;
640 const char *sd_bus_message_get_sender(sd_bus_message *m) {
647 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
651 if (!sd_bus_error_is_set(&m->error))
657 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
667 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
677 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
687 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
697 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
700 if (m->pid_starttime <= 0)
703 *usec = m->pid_starttime;
707 const char *sd_bus_message_get_selinux_context(sd_bus_message *m) {
714 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
718 if (m->monotonic <= 0)
721 *usec = m->monotonic;
725 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
729 if (m->realtime <= 0)
736 const char *sd_bus_message_get_comm(sd_bus_message *m) {
743 const char *sd_bus_message_get_tid_comm(sd_bus_message *m) {
750 const char *sd_bus_message_get_exe(sd_bus_message *m) {
757 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
768 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
772 m->cmdline_array = new(char*, n + 1);
773 if (!m->cmdline_array)
776 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
778 m->cmdline_array[i++] = (char*) p;
783 m->cmdline_array[i] = NULL;
784 *cmdline = m->cmdline_array;
789 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
793 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
796 if (interface && (!m->interface || !streq(m->interface, interface)))
799 if (member && (!m->member || !streq(m->member, member)))
805 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
809 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
812 if (interface && (!m->interface || !streq(m->interface, interface)))
815 if (member && (!m->member || !streq(m->member, member)))
821 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
825 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
828 if (name && (!m->error.name || !streq(m->error.name, name)))
834 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
839 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
843 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
845 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
850 static struct bus_container *message_get_container(sd_bus_message *m) {
853 if (m->n_containers == 0)
854 return &m->root_container;
856 assert(m->containers);
857 return m->containers + m->n_containers - 1;
860 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
863 struct bus_container *c;
869 added = m->header->body_size;
871 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
875 added = m->header->body_size - added;
877 for (c = m->containers; c < m->containers + m->n_containers; c++)
879 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
880 *c->array_size += added;
884 if (m->error.message)
885 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
893 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
894 struct bus_container *c;
909 if (!bus_type_is_basic(type))
912 c = message_get_container(m);
914 if (c->signature && c->signature[c->index]) {
915 /* Container signature is already set */
917 if (c->signature[c->index] != type)
920 /* Maybe we can append to the signature? But only if this is the top-level container*/
921 if (c->enclosing != 0)
924 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
931 case SD_BUS_TYPE_STRING:
932 case SD_BUS_TYPE_OBJECT_PATH:
935 sz = 4 + strlen(p) + 1;
938 case SD_BUS_TYPE_SIGNATURE:
941 sz = 1 + strlen(p) + 1;
944 case SD_BUS_TYPE_BOOLEAN:
947 assert_cc(sizeof(int) == sizeof(uint32_t));
953 case SD_BUS_TYPE_UNIX_FD: {
969 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
975 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
989 align = bus_type_get_alignment(type);
990 sz = bus_type_get_size(type);
997 a = message_extend_body(m, align, sz);
1003 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1004 *(uint32_t*) a = sz - 5;
1005 memcpy((uint8_t*) a + 4, p, sz - 4);
1008 *stored = (const uint8_t*) a + 4;
1010 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1011 *(uint8_t*) a = sz - 1;
1012 memcpy((uint8_t*) a + 1, p, sz - 1);
1015 *stored = (const uint8_t*) a + 1;
1016 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1017 *(uint32_t*) a = fdi;
1031 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1037 /* Truncate extended signature again */
1039 c->signature[c->index] = 0;
1042 close_nointr_nofail(fd);
1047 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1048 return message_append_basic(m, type, p, NULL);
1051 static int bus_message_open_array(
1053 struct bus_container *c,
1054 const char *contents,
1055 uint32_t **array_size) {
1068 if (!signature_is_single(contents))
1071 alignment = bus_type_get_alignment(contents[0]);
1075 if (c->signature && c->signature[c->index]) {
1077 /* Verify the existing signature */
1079 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1082 if (!startswith(c->signature + c->index + 1, contents))
1085 nindex = c->index + 1 + strlen(contents);
1087 if (c->enclosing != 0)
1090 /* Extend the existing signature */
1092 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1096 nindex = e - c->signature;
1099 saved = m->header->body_size;
1100 a = message_extend_body(m, 4, 4);
1102 /* Truncate extended signature again */
1104 c->signature[c->index] = 0;
1110 if (!message_extend_body(m, alignment, 0)) {
1111 /* Add alignment between size and first element */
1113 c->signature[c->index] = 0;
1115 m->header->body_size = saved;
1119 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1122 /* m->body might have changed so let's readjust a */
1123 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1130 static int bus_message_open_variant(
1132 struct bus_container *c,
1133 const char *contents) {
1143 if (!signature_is_single(contents))
1146 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1149 if (c->signature && c->signature[c->index]) {
1151 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1155 if (c->enclosing != 0)
1158 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1163 l = strlen(contents);
1164 a = message_extend_body(m, 1, 1 + l + 1);
1166 /* Truncate extended signature again */
1168 c->signature[c->index] = 0;
1174 memcpy((uint8_t*) a + 1, contents, l + 1);
1176 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1182 static int bus_message_open_struct(
1184 struct bus_container *c,
1185 const char *contents) {
1194 if (!signature_is_valid(contents, false))
1197 if (c->signature && c->signature[c->index]) {
1200 l = strlen(contents);
1202 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1203 !startswith(c->signature + c->index + 1, contents) ||
1204 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1207 nindex = c->index + 1 + l + 1;
1209 if (c->enclosing != 0)
1212 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1216 nindex = e - c->signature;
1219 /* Align contents to 8 byte boundary */
1220 if (!message_extend_body(m, 8, 0)) {
1222 c->signature[c->index] = 0;
1227 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1233 static int bus_message_open_dict_entry(
1235 struct bus_container *c,
1236 const char *contents) {
1244 if (!signature_is_pair(contents))
1247 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1250 if (c->signature && c->signature[c->index]) {
1253 l = strlen(contents);
1255 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1256 !startswith(c->signature + c->index + 1, contents) ||
1257 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1260 nindex = c->index + 1 + l + 1;
1264 /* Align contents to 8 byte boundary */
1265 if (!message_extend_body(m, 8, 0))
1268 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1274 int sd_bus_message_open_container(
1277 const char *contents) {
1279 struct bus_container *c, *w;
1280 uint32_t *array_size = NULL;
1291 /* Make sure we have space for one more container */
1292 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1297 c = message_get_container(m);
1299 signature = strdup(contents);
1303 if (type == SD_BUS_TYPE_ARRAY)
1304 r = bus_message_open_array(m, c, contents, &array_size);
1305 else if (type == SD_BUS_TYPE_VARIANT)
1306 r = bus_message_open_variant(m, c, contents);
1307 else if (type == SD_BUS_TYPE_STRUCT)
1308 r = bus_message_open_struct(m, c, contents);
1309 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1310 r = bus_message_open_dict_entry(m, c, contents);
1319 /* OK, let's fill it in */
1320 w += m->n_containers++;
1321 w->enclosing = type;
1322 w->signature = signature;
1324 w->array_size = array_size;
1330 int sd_bus_message_close_container(sd_bus_message *m) {
1331 struct bus_container *c;
1337 if (m->n_containers <= 0)
1340 c = message_get_container(m);
1341 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1342 if (c->signature && c->signature[c->index] != 0)
1358 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1365 stack[*i].types = types;
1366 stack[*i].n_struct = n_struct;
1367 stack[*i].n_array = n_array;
1373 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1384 *types = stack[*i].types;
1385 *n_struct = stack[*i].n_struct;
1386 *n_array = stack[*i].n_array;
1391 int bus_message_append_ap(
1396 unsigned n_array, n_struct;
1397 TypeStack stack[BUS_CONTAINER_DEPTH];
1398 unsigned stack_ptr = 0;
1406 n_array = (unsigned) -1;
1407 n_struct = strlen(types);
1412 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1413 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1419 r = sd_bus_message_close_container(m);
1427 if (n_array != (unsigned) -1)
1436 case SD_BUS_TYPE_BYTE: {
1439 x = (uint8_t) va_arg(ap, int);
1440 r = sd_bus_message_append_basic(m, *t, &x);
1444 case SD_BUS_TYPE_BOOLEAN:
1445 case SD_BUS_TYPE_INT32:
1446 case SD_BUS_TYPE_UINT32:
1447 case SD_BUS_TYPE_UNIX_FD: {
1450 /* We assume a boolean is the same as int32_t */
1451 assert_cc(sizeof(int32_t) == sizeof(int));
1453 x = va_arg(ap, uint32_t);
1454 r = sd_bus_message_append_basic(m, *t, &x);
1458 case SD_BUS_TYPE_INT16:
1459 case SD_BUS_TYPE_UINT16: {
1462 x = (uint16_t) va_arg(ap, int);
1463 r = sd_bus_message_append_basic(m, *t, &x);
1467 case SD_BUS_TYPE_INT64:
1468 case SD_BUS_TYPE_UINT64:
1469 case SD_BUS_TYPE_DOUBLE: {
1472 x = va_arg(ap, uint64_t);
1473 r = sd_bus_message_append_basic(m, *t, &x);
1477 case SD_BUS_TYPE_STRING:
1478 case SD_BUS_TYPE_OBJECT_PATH:
1479 case SD_BUS_TYPE_SIGNATURE: {
1482 x = va_arg(ap, const char*);
1483 r = sd_bus_message_append_basic(m, *t, x);
1487 case SD_BUS_TYPE_ARRAY: {
1490 r = signature_element_length(t + 1, &k);
1496 memcpy(s, t + 1, k);
1499 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1504 if (n_array == (unsigned) -1) {
1509 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1515 n_array = va_arg(ap, unsigned);
1520 case SD_BUS_TYPE_VARIANT: {
1523 s = va_arg(ap, const char*);
1527 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1531 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1536 n_struct = strlen(s);
1537 n_array = (unsigned) -1;
1542 case SD_BUS_TYPE_STRUCT_BEGIN:
1543 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1546 r = signature_element_length(t, &k);
1553 memcpy(s, t + 1, k - 2);
1556 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1561 if (n_array == (unsigned) -1) {
1566 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1572 n_array = (unsigned) -1;
1588 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1599 va_start(ap, types);
1600 r = bus_message_append_ap(m, types, ap);
1606 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1612 start = ALIGN_TO((size_t) *rindex, align);
1618 /* Verify that padding is 0 */
1619 for (k = *rindex; k < start; k++)
1620 if (((const uint8_t*) p)[k] != 0)
1624 *r = (uint8_t*) p + start;
1631 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1632 struct bus_container *c;
1636 c = message_get_container(m);
1640 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1643 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1648 if (message_end_of_array(m, *rindex))
1651 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1654 static bool validate_nul(const char *s, size_t l) {
1656 /* Check for NUL chars in the string */
1657 if (memchr(s, 0, l))
1660 /* Check for NUL termination */
1667 static bool validate_string(const char *s, size_t l) {
1669 if (!validate_nul(s, l))
1672 /* Check if valid UTF8 */
1673 if (!utf8_is_valid(s))
1679 static bool validate_signature(const char *s, size_t l) {
1681 if (!validate_nul(s, l))
1684 /* Check if valid signature */
1685 if (!signature_is_valid(s, true))
1691 static bool validate_object_path(const char *s, size_t l) {
1693 if (!validate_nul(s, l))
1696 if (!object_path_is_valid(s))
1702 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1703 struct bus_container *c;
1711 if (!bus_type_is_basic(type))
1716 c = message_get_container(m);
1718 if (!c->signature || c->signature[c->index] == 0)
1721 if (c->signature[c->index] != type)
1726 case SD_BUS_TYPE_STRING:
1727 case SD_BUS_TYPE_OBJECT_PATH: {
1732 r = message_peek_body(m, &rindex, 4, 4, &q);
1736 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1737 r = message_peek_body(m, &rindex, 1, l+1, &q);
1743 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1744 if (!validate_object_path(q, l))
1747 if (!validate_string(q, l))
1752 *(const char**) p = q;
1756 case SD_BUS_TYPE_SIGNATURE: {
1761 r = message_peek_body(m, &rindex, 1, 1, &q);
1766 r = message_peek_body(m, &rindex, 1, l+1, &q);
1772 if (!validate_signature(q, l))
1776 *(const char**) p = q;
1784 align = bus_type_get_alignment(type);
1785 sz = bus_type_get_size(type);
1786 assert(align > 0 && sz > 0);
1789 r = message_peek_body(m, &rindex, align, sz, &q);
1795 case SD_BUS_TYPE_BYTE:
1796 *(uint8_t*) p = *(uint8_t*) q;
1799 case SD_BUS_TYPE_BOOLEAN:
1800 *(int*) p = !!*(uint32_t*) q;
1803 case SD_BUS_TYPE_INT16:
1804 case SD_BUS_TYPE_UINT16:
1805 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1808 case SD_BUS_TYPE_INT32:
1809 case SD_BUS_TYPE_UINT32:
1810 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1813 case SD_BUS_TYPE_INT64:
1814 case SD_BUS_TYPE_UINT64:
1815 case SD_BUS_TYPE_DOUBLE:
1816 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1819 case SD_BUS_TYPE_UNIX_FD: {
1822 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1826 *(int*) p = m->fds[j];
1831 assert_not_reached("Unknown basic type...");
1840 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1846 static int bus_message_enter_array(
1848 struct bus_container *c,
1849 const char *contents,
1850 uint32_t **array_size) {
1861 if (!signature_is_single(contents))
1864 alignment = bus_type_get_alignment(contents[0]);
1868 if (!c->signature || c->signature[c->index] == 0)
1871 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1874 if (!startswith(c->signature + c->index + 1, contents))
1878 r = message_peek_body(m, &rindex, 4, 4, &q);
1882 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1885 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1891 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1892 c->index += 1 + strlen(contents);
1896 *array_size = (uint32_t*) q;
1901 static int bus_message_enter_variant(
1903 struct bus_container *c,
1904 const char *contents) {
1915 if (!signature_is_single(contents))
1918 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1921 if (!c->signature || c->signature[c->index] == 0)
1924 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1928 r = message_peek_body(m, &rindex, 1, 1, &q);
1933 r = message_peek_body(m, &rindex, 1, l+1, &q);
1939 if (!validate_signature(q, l))
1942 if (!streq(q, contents))
1945 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1953 static int bus_message_enter_struct(
1955 struct bus_container *c,
1956 const char *contents) {
1965 if (!signature_is_valid(contents, false))
1968 if (!c->signature || c->signature[c->index] == 0)
1971 l = strlen(contents);
1973 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1974 !startswith(c->signature + c->index + 1, contents) ||
1975 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1978 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1982 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1983 c->index += 1 + l + 1;
1988 static int bus_message_enter_dict_entry(
1990 struct bus_container *c,
1991 const char *contents) {
2000 if (!signature_is_pair(contents))
2003 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2006 if (!c->signature || c->signature[c->index] == 0)
2009 l = strlen(contents);
2011 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2012 !startswith(c->signature + c->index + 1, contents) ||
2013 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2016 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2020 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2021 c->index += 1 + l + 1;
2026 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2027 struct bus_container *c, *w;
2028 uint32_t *array_size = NULL;
2040 * We enforce a global limit on container depth, that is much
2041 * higher than the 32 structs and 32 arrays the specification
2042 * mandates. This is simpler to implement for us, and we need
2043 * this only to ensure our container array doesn't grow
2044 * without bounds. We are happy to return any data from a
2045 * message as long as the data itself is valid, even if the
2046 * overall message might be not.
2048 * Note that the message signature is validated when
2049 * parsing the headers, and that validation does check the
2052 * Note that the specification defines no limits on the depth
2053 * of stacked variants, but we do.
2055 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2058 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2063 c = message_get_container(m);
2065 if (!c->signature || c->signature[c->index] == 0)
2068 signature = strdup(contents);
2072 if (type == SD_BUS_TYPE_ARRAY)
2073 r = bus_message_enter_array(m, c, contents, &array_size);
2074 else if (type == SD_BUS_TYPE_VARIANT)
2075 r = bus_message_enter_variant(m, c, contents);
2076 else if (type == SD_BUS_TYPE_STRUCT)
2077 r = bus_message_enter_struct(m, c, contents);
2078 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2079 r = bus_message_enter_dict_entry(m, c, contents);
2088 /* OK, let's fill it in */
2089 w += m->n_containers++;
2090 w->enclosing = type;
2091 w->signature = signature;
2093 w->array_size = array_size;
2094 w->begin = m->rindex;
2099 int sd_bus_message_exit_container(sd_bus_message *m) {
2100 struct bus_container *c;
2106 if (m->n_containers <= 0)
2109 c = message_get_container(m);
2110 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2113 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2114 if (c->begin + l != m->rindex)
2118 if (c->signature && c->signature[c->index] != 0)
2128 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2129 struct bus_container *c;
2137 c = message_get_container(m);
2139 if (!c->signature || c->signature[c->index] == 0)
2142 if (message_end_of_array(m, m->rindex))
2145 if (bus_type_is_basic(c->signature[c->index])) {
2149 *type = c->signature[c->index];
2153 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2159 r = signature_element_length(c->signature+c->index+1, &l);
2165 sig = strndup(c->signature + c->index + 1, l);
2169 free(m->peeked_signature);
2170 m->peeked_signature = sig;
2176 *type = SD_BUS_TYPE_ARRAY;
2181 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2182 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2188 r = signature_element_length(c->signature+c->index, &l);
2193 sig = strndup(c->signature + c->index + 1, l - 2);
2197 free(m->peeked_signature);
2198 m->peeked_signature = sig;
2204 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2209 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2215 r = message_peek_body(m, &rindex, 1, 1, &q);
2222 r = message_peek_body(m, &rindex, 1, l+1, &q);
2228 if (!validate_signature(q, l))
2235 *type = SD_BUS_TYPE_VARIANT;
2244 *type = c->enclosing;
2250 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2251 struct bus_container *c;
2259 reset_containers(m);
2261 m->root_container.index = 0;
2263 c = message_get_container(m);
2265 c = message_get_container(m);
2268 m->rindex = c->begin;
2271 return !isempty(c->signature);
2273 static int message_read_ap(
2278 unsigned n_array, n_struct;
2279 TypeStack stack[BUS_CONTAINER_DEPTH];
2280 unsigned stack_ptr = 0;
2288 /* Ideally, we'd just call ourselves recursively on every
2289 * complex type. However, the state of a va_list that is
2290 * passed to a function is undefined after that function
2291 * returns. This means we need to docode the va_list linearly
2292 * in a single stackframe. We hence implement our own
2293 * home-grown stack in an array. */
2295 n_array = (unsigned) -1;
2296 n_struct = strlen(types);
2301 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2302 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2308 r = sd_bus_message_exit_container(m);
2316 if (n_array != (unsigned) -1)
2325 case SD_BUS_TYPE_BYTE:
2326 case SD_BUS_TYPE_BOOLEAN:
2327 case SD_BUS_TYPE_INT16:
2328 case SD_BUS_TYPE_UINT16:
2329 case SD_BUS_TYPE_INT32:
2330 case SD_BUS_TYPE_UINT32:
2331 case SD_BUS_TYPE_INT64:
2332 case SD_BUS_TYPE_UINT64:
2333 case SD_BUS_TYPE_DOUBLE:
2334 case SD_BUS_TYPE_STRING:
2335 case SD_BUS_TYPE_OBJECT_PATH:
2336 case SD_BUS_TYPE_SIGNATURE:
2337 case SD_BUS_TYPE_UNIX_FD: {
2340 p = va_arg(ap, void*);
2341 r = sd_bus_message_read_basic(m, *t, p);
2350 case SD_BUS_TYPE_ARRAY: {
2353 r = signature_element_length(t + 1, &k);
2359 memcpy(s, t + 1, k);
2362 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2369 if (n_array == (unsigned) -1) {
2374 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2380 n_array = va_arg(ap, unsigned);
2385 case SD_BUS_TYPE_VARIANT: {
2388 s = va_arg(ap, const char *);
2392 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2398 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2403 n_struct = strlen(s);
2404 n_array = (unsigned) -1;
2409 case SD_BUS_TYPE_STRUCT_BEGIN:
2410 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2413 r = signature_element_length(t, &k);
2419 memcpy(s, t + 1, k - 2);
2422 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2429 if (n_array == (unsigned) -1) {
2434 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2440 n_array = (unsigned) -1;
2453 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2464 va_start(ap, types);
2465 r = message_read_ap(m, types, ap);
2471 static int message_peek_fields(
2482 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2485 static int message_peek_field_uint32(
2496 r = message_peek_fields(m, ri, 4, 4, &q);
2501 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2506 static int message_peek_field_string(
2508 bool (*validate)(const char *p),
2519 r = message_peek_field_uint32(m, ri, &l);
2523 r = message_peek_fields(m, ri, 1, l+1, &q);
2528 if (!validate_nul(q, l))
2534 if (!validate_string(q, l))
2544 static int message_peek_field_signature(
2556 r = message_peek_fields(m, ri, 1, 1, &q);
2561 r = message_peek_fields(m, ri, 1, l+1, &q);
2565 if (!validate_signature(q, l))
2574 static int message_skip_fields(
2577 uint32_t array_size,
2578 const char **signature) {
2580 size_t original_index;
2587 original_index = *ri;
2593 if (array_size != (uint32_t) -1 &&
2594 array_size <= *ri - original_index)
2601 if (t == SD_BUS_TYPE_STRING) {
2603 r = message_peek_field_string(m, NULL, ri, NULL);
2609 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2611 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2617 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2619 r = message_peek_field_signature(m, ri, NULL);
2625 } else if (bus_type_is_basic(t)) {
2628 align = bus_type_get_alignment(t);
2629 k = bus_type_get_size(t);
2630 assert(align > 0 && k > 0);
2632 r = message_peek_fields(m, ri, align, k, NULL);
2638 } else if (t == SD_BUS_TYPE_ARRAY) {
2640 r = signature_element_length(*signature+1, &l);
2650 strncpy(sig, *signature + 1, l-1);
2653 alignment = bus_type_get_alignment(sig[0]);
2657 r = message_peek_field_uint32(m, ri, &nas);
2660 if (nas > BUS_ARRAY_MAX_SIZE)
2663 r = message_peek_fields(m, ri, alignment, 0, NULL);
2667 r = message_skip_fields(m, ri, nas, (const char**) &s);
2672 (*signature) += 1 + l;
2674 } else if (t == SD_BUS_TYPE_VARIANT) {
2677 r = message_peek_field_signature(m, ri, &s);
2681 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2687 } else if (t == SD_BUS_TYPE_STRUCT ||
2688 t == SD_BUS_TYPE_DICT_ENTRY) {
2690 r = signature_element_length(*signature, &l);
2697 strncpy(sig, *signature + 1, l-1);
2700 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2711 int bus_message_parse_fields(sd_bus_message *m) {
2714 uint32_t unix_fds = 0;
2718 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2719 const char *signature;
2722 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2726 r = message_peek_field_signature(m, &ri, &signature);
2731 case _SD_BUS_MESSAGE_HEADER_INVALID:
2734 case SD_BUS_MESSAGE_HEADER_PATH:
2739 if (!streq(signature, "o"))
2742 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2745 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2750 if (!streq(signature, "s"))
2753 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2756 case SD_BUS_MESSAGE_HEADER_MEMBER:
2761 if (!streq(signature, "s"))
2764 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2767 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2772 if (!streq(signature, "s"))
2775 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2778 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2783 if (!streq(signature, "s"))
2786 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2789 case SD_BUS_MESSAGE_HEADER_SENDER:
2794 if (!streq(signature, "s"))
2797 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2801 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2805 if (m->root_container.signature)
2808 if (!streq(signature, "g"))
2811 r = message_peek_field_signature(m, &ri, &s);
2819 free(m->root_container.signature);
2820 m->root_container.signature = c;
2824 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2825 if (m->reply_serial != 0)
2828 if (!streq(signature, "u"))
2831 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2835 if (m->reply_serial == 0)
2840 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2844 if (!streq(signature, "u"))
2847 r = message_peek_field_uint32(m, &ri, &unix_fds);
2857 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2864 if (m->n_fds != unix_fds)
2867 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2870 switch (m->header->type) {
2872 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2873 if (!m->path || !m->interface || !m->member)
2877 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2879 if (!m->path || !m->member)
2884 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2886 if (m->reply_serial == 0)
2890 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2892 if (m->reply_serial == 0 || !m->error.name)
2897 /* Try to read the error message, but if we can't it's a non-issue */
2898 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2899 sd_bus_message_read(m, "s", &m->error.message);
2904 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2913 if (m->n_containers > 0)
2916 /* If there's a non-trivial signature set, then add it in here */
2917 if (!isempty(m->root_container.signature)) {
2918 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2924 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2929 l = BUS_MESSAGE_FIELDS_SIZE(m);
2933 /* Add padding at the end, since we know the body
2934 * needs to start at an 8 byte alignment. */
2937 p = message_extend_fields(m, 1, a);
2942 m->header->fields_size -= a;
2945 m->header->serial = serial;
2951 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2961 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2964 int bus_message_dump(sd_bus_message *m) {
2965 char **cmdline = NULL;
2971 printf("Message %p\n"
2978 "\tfields_size=%u\n"
2983 "\tdestination=%s\n"
2986 "\treply_serial=%u\n"
2988 "\terror.message=%s\n"
2996 BUS_MESSAGE_SERIAL(m),
2997 BUS_MESSAGE_FIELDS_SIZE(m),
2998 BUS_MESSAGE_BODY_SIZE(m),
3000 strna(m->interface),
3002 strna(m->destination),
3004 strna(m->root_container.signature),
3006 strna(m->error.name),
3007 strna(m->error.message),
3011 printf("\tpid=%lu\n", (unsigned long) m->pid);
3013 printf("\ttid=%lu\n", (unsigned long) m->tid);
3015 printf("\tuid=%lu\n", (unsigned long) m->uid);
3017 printf("\tgid=%lu\n", (unsigned long) m->gid);
3018 if (m->pid_starttime != 0)
3019 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3020 if (m->monotonic != 0)
3021 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3022 if (m->realtime != 0)
3023 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3025 printf("\texe=[%s]\n", m->exe);
3027 printf("\tcomm=[%s]\n", m->comm);
3029 printf("\ttid_comm=[%s]\n", m->tid_comm);
3031 printf("\tlabel=[%s]\n", m->label);
3033 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3036 fputs("\tcmdline=[", stdout);
3037 STRV_FOREACH(c, cmdline) {
3044 fputs("]\n", stdout);
3047 r = sd_bus_message_rewind(m, true);
3049 log_error("Failed to rewind: %s", strerror(-r));
3053 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3056 _cleanup_free_ char *prefix = NULL;
3057 const char *contents = NULL;
3072 r = sd_bus_message_peek_type(m, &type, &contents);
3074 log_error("Failed to peek type: %s", strerror(-r));
3081 r = sd_bus_message_exit_container(m);
3083 log_error("Failed to exit container: %s", strerror(-r));
3089 prefix = strrep("\t", level);
3093 if (type == SD_BUS_TYPE_ARRAY)
3094 printf("%s} END_ARRAY \n", prefix);
3095 else if (type == SD_BUS_TYPE_VARIANT)
3096 printf("%s} END_VARIANT\n", prefix);
3097 else if (type == SD_BUS_TYPE_STRUCT)
3098 printf("%s} END_STRUCT\n", prefix);
3099 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3100 printf("%s} END_DICT_ENTRY\n", prefix);
3105 prefix = strrep("\t", level);
3109 if (bus_type_is_container(type) > 0) {
3110 r = sd_bus_message_enter_container(m, type, contents);
3112 log_error("Failed to enter container: %s", strerror(-r));
3116 if (type == SD_BUS_TYPE_ARRAY)
3117 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3118 else if (type == SD_BUS_TYPE_VARIANT)
3119 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3120 else if (type == SD_BUS_TYPE_STRUCT)
3121 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3122 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3123 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3130 r = sd_bus_message_read_basic(m, type, &basic);
3132 log_error("Failed to get basic: %s", strerror(-r));
3138 case SD_BUS_TYPE_BYTE:
3139 printf("%sBYTE: %u\n", prefix, basic.u8);
3142 case SD_BUS_TYPE_BOOLEAN:
3143 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3146 case SD_BUS_TYPE_INT16:
3147 printf("%sINT16: %i\n", prefix, basic.s16);
3150 case SD_BUS_TYPE_UINT16:
3151 printf("%sUINT16: %u\n", prefix, basic.u16);
3154 case SD_BUS_TYPE_INT32:
3155 printf("%sINT32: %i\n", prefix, basic.s32);
3158 case SD_BUS_TYPE_UINT32:
3159 printf("%sUINT32: %u\n", prefix, basic.u32);
3162 case SD_BUS_TYPE_INT64:
3163 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3166 case SD_BUS_TYPE_UINT64:
3167 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3170 case SD_BUS_TYPE_DOUBLE:
3171 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3174 case SD_BUS_TYPE_STRING:
3175 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3178 case SD_BUS_TYPE_OBJECT_PATH:
3179 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3182 case SD_BUS_TYPE_SIGNATURE:
3183 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3186 case SD_BUS_TYPE_UNIX_FD:
3187 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3191 assert_not_reached("Unknown basic type.");
3195 printf("} END_MESSAGE\n");
3199 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3207 total = BUS_MESSAGE_SIZE(m);
3213 e = mempcpy(p, m->header, sizeof(*m->header));
3216 e = mempcpy(e, m->fields, m->header->fields_size);
3218 if (m->header->fields_size % 8 != 0)
3219 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3223 e = mempcpy(e, m->body, m->header->body_size);
3225 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3233 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3239 r = sd_bus_message_enter_container(m, 'a', "s");
3246 r = sd_bus_message_read_basic(m, 's', &s);
3252 r = strv_extend(l, s);
3257 r = sd_bus_message_exit_container(m);
3264 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3266 const char *t = NULL;
3271 r = sd_bus_message_rewind(m, true);
3275 for (j = 0; j <= i; j++) {
3278 r = sd_bus_message_peek_type(m, &type, NULL);
3282 if (type != SD_BUS_TYPE_STRING &&
3283 type != SD_BUS_TYPE_OBJECT_PATH &&
3284 type != SD_BUS_TYPE_SIGNATURE)
3287 r = sd_bus_message_read_basic(m, type, &t);
3295 int bus_header_size(struct bus_header *h, size_t *sum) {
3301 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3302 fs = h->fields_size;
3304 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3305 fs = bswap_32(h->fields_size);
3306 bs = bswap_32(h->body_size);
3310 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;