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_owner_uid(sd_bus_message *m, uid_t *uid) {
872 return cg_path_get_owner_uid(m->cgroup, uid);
875 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
886 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
890 m->cmdline_array = new(char*, n + 1);
891 if (!m->cmdline_array)
894 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
896 m->cmdline_array[i++] = (char*) p;
901 m->cmdline_array[i] = NULL;
902 *cmdline = m->cmdline_array;
907 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
915 *sessionid = m->audit->sessionid;
919 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
927 *uid = m->audit->loginuid;
931 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
941 sz = m->capability_size / 4;
942 if ((unsigned) capability >= sz*8)
945 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
948 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
952 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
955 if (interface && (!m->interface || !streq(m->interface, interface)))
958 if (member && (!m->member || !streq(m->member, member)))
964 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
968 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
971 if (interface && (!m->interface || !streq(m->interface, interface)))
974 if (member && (!m->member || !streq(m->member, member)))
980 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
984 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
987 if (name && (!m->error.name || !streq(m->error.name, name)))
993 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
998 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1002 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1004 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1009 static struct bus_container *message_get_container(sd_bus_message *m) {
1012 if (m->n_containers == 0)
1013 return &m->root_container;
1015 assert(m->containers);
1016 return m->containers + m->n_containers - 1;
1019 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1022 struct bus_container *c;
1028 added = m->header->body_size;
1030 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
1034 added = m->header->body_size - added;
1036 for (c = m->containers; c < m->containers + m->n_containers; c++)
1037 if (c->array_size) {
1038 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
1039 *c->array_size += added;
1043 if (m->error.message)
1044 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1047 m->free_body = true;
1052 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1053 struct bus_container *c;
1068 if (!bus_type_is_basic(type))
1071 c = message_get_container(m);
1073 if (c->signature && c->signature[c->index]) {
1074 /* Container signature is already set */
1076 if (c->signature[c->index] != type)
1079 /* Maybe we can append to the signature? But only if this is the top-level container*/
1080 if (c->enclosing != 0)
1083 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1090 case SD_BUS_TYPE_STRING:
1091 case SD_BUS_TYPE_OBJECT_PATH:
1094 sz = 4 + strlen(p) + 1;
1097 case SD_BUS_TYPE_SIGNATURE:
1100 sz = 1 + strlen(p) + 1;
1103 case SD_BUS_TYPE_BOOLEAN:
1106 assert_cc(sizeof(int) == sizeof(uint32_t));
1112 case SD_BUS_TYPE_UNIX_FD: {
1115 if (!m->allow_fds) {
1128 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1134 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1148 align = bus_type_get_alignment(type);
1149 sz = bus_type_get_size(type);
1156 a = message_extend_body(m, align, sz);
1162 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1163 *(uint32_t*) a = sz - 5;
1164 memcpy((uint8_t*) a + 4, p, sz - 4);
1167 *stored = (const uint8_t*) a + 4;
1169 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1170 *(uint8_t*) a = sz - 1;
1171 memcpy((uint8_t*) a + 1, p, sz - 1);
1174 *stored = (const uint8_t*) a + 1;
1175 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1176 *(uint32_t*) a = fdi;
1190 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1196 /* Truncate extended signature again */
1198 c->signature[c->index] = 0;
1201 close_nointr_nofail(fd);
1206 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1207 return message_append_basic(m, type, p, NULL);
1210 static int bus_message_open_array(
1212 struct bus_container *c,
1213 const char *contents,
1214 uint32_t **array_size) {
1227 if (!signature_is_single(contents))
1230 alignment = bus_type_get_alignment(contents[0]);
1234 if (c->signature && c->signature[c->index]) {
1236 /* Verify the existing signature */
1238 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1241 if (!startswith(c->signature + c->index + 1, contents))
1244 nindex = c->index + 1 + strlen(contents);
1246 if (c->enclosing != 0)
1249 /* Extend the existing signature */
1251 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1255 nindex = e - c->signature;
1258 saved = m->header->body_size;
1259 a = message_extend_body(m, 4, 4);
1261 /* Truncate extended signature again */
1263 c->signature[c->index] = 0;
1269 if (!message_extend_body(m, alignment, 0)) {
1270 /* Add alignment between size and first element */
1272 c->signature[c->index] = 0;
1274 m->header->body_size = saved;
1278 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1281 /* m->body might have changed so let's readjust a */
1282 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1289 static int bus_message_open_variant(
1291 struct bus_container *c,
1292 const char *contents) {
1302 if (!signature_is_single(contents))
1305 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1308 if (c->signature && c->signature[c->index]) {
1310 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1314 if (c->enclosing != 0)
1317 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1322 l = strlen(contents);
1323 a = message_extend_body(m, 1, 1 + l + 1);
1325 /* Truncate extended signature again */
1327 c->signature[c->index] = 0;
1333 memcpy((uint8_t*) a + 1, contents, l + 1);
1335 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1341 static int bus_message_open_struct(
1343 struct bus_container *c,
1344 const char *contents) {
1353 if (!signature_is_valid(contents, false))
1356 if (c->signature && c->signature[c->index]) {
1359 l = strlen(contents);
1361 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1362 !startswith(c->signature + c->index + 1, contents) ||
1363 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1366 nindex = c->index + 1 + l + 1;
1368 if (c->enclosing != 0)
1371 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1375 nindex = e - c->signature;
1378 /* Align contents to 8 byte boundary */
1379 if (!message_extend_body(m, 8, 0)) {
1381 c->signature[c->index] = 0;
1386 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1392 static int bus_message_open_dict_entry(
1394 struct bus_container *c,
1395 const char *contents) {
1403 if (!signature_is_pair(contents))
1406 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1409 if (c->signature && c->signature[c->index]) {
1412 l = strlen(contents);
1414 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1415 !startswith(c->signature + c->index + 1, contents) ||
1416 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1419 nindex = c->index + 1 + l + 1;
1423 /* Align contents to 8 byte boundary */
1424 if (!message_extend_body(m, 8, 0))
1427 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1433 int sd_bus_message_open_container(
1436 const char *contents) {
1438 struct bus_container *c, *w;
1439 uint32_t *array_size = NULL;
1450 /* Make sure we have space for one more container */
1451 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1456 c = message_get_container(m);
1458 signature = strdup(contents);
1462 if (type == SD_BUS_TYPE_ARRAY)
1463 r = bus_message_open_array(m, c, contents, &array_size);
1464 else if (type == SD_BUS_TYPE_VARIANT)
1465 r = bus_message_open_variant(m, c, contents);
1466 else if (type == SD_BUS_TYPE_STRUCT)
1467 r = bus_message_open_struct(m, c, contents);
1468 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1469 r = bus_message_open_dict_entry(m, c, contents);
1478 /* OK, let's fill it in */
1479 w += m->n_containers++;
1480 w->enclosing = type;
1481 w->signature = signature;
1483 w->array_size = array_size;
1489 int sd_bus_message_close_container(sd_bus_message *m) {
1490 struct bus_container *c;
1496 if (m->n_containers <= 0)
1499 c = message_get_container(m);
1500 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1501 if (c->signature && c->signature[c->index] != 0)
1517 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1524 stack[*i].types = types;
1525 stack[*i].n_struct = n_struct;
1526 stack[*i].n_array = n_array;
1532 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1543 *types = stack[*i].types;
1544 *n_struct = stack[*i].n_struct;
1545 *n_array = stack[*i].n_array;
1550 int bus_message_append_ap(
1555 unsigned n_array, n_struct;
1556 TypeStack stack[BUS_CONTAINER_DEPTH];
1557 unsigned stack_ptr = 0;
1565 n_array = (unsigned) -1;
1566 n_struct = strlen(types);
1571 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1572 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1578 r = sd_bus_message_close_container(m);
1586 if (n_array != (unsigned) -1)
1595 case SD_BUS_TYPE_BYTE: {
1598 x = (uint8_t) va_arg(ap, int);
1599 r = sd_bus_message_append_basic(m, *t, &x);
1603 case SD_BUS_TYPE_BOOLEAN:
1604 case SD_BUS_TYPE_INT32:
1605 case SD_BUS_TYPE_UINT32:
1606 case SD_BUS_TYPE_UNIX_FD: {
1609 /* We assume a boolean is the same as int32_t */
1610 assert_cc(sizeof(int32_t) == sizeof(int));
1612 x = va_arg(ap, uint32_t);
1613 r = sd_bus_message_append_basic(m, *t, &x);
1617 case SD_BUS_TYPE_INT16:
1618 case SD_BUS_TYPE_UINT16: {
1621 x = (uint16_t) va_arg(ap, int);
1622 r = sd_bus_message_append_basic(m, *t, &x);
1626 case SD_BUS_TYPE_INT64:
1627 case SD_BUS_TYPE_UINT64:
1628 case SD_BUS_TYPE_DOUBLE: {
1631 x = va_arg(ap, uint64_t);
1632 r = sd_bus_message_append_basic(m, *t, &x);
1636 case SD_BUS_TYPE_STRING:
1637 case SD_BUS_TYPE_OBJECT_PATH:
1638 case SD_BUS_TYPE_SIGNATURE: {
1641 x = va_arg(ap, const char*);
1642 r = sd_bus_message_append_basic(m, *t, x);
1646 case SD_BUS_TYPE_ARRAY: {
1649 r = signature_element_length(t + 1, &k);
1655 memcpy(s, t + 1, k);
1658 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1663 if (n_array == (unsigned) -1) {
1668 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1674 n_array = va_arg(ap, unsigned);
1679 case SD_BUS_TYPE_VARIANT: {
1682 s = va_arg(ap, const char*);
1686 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1690 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1695 n_struct = strlen(s);
1696 n_array = (unsigned) -1;
1701 case SD_BUS_TYPE_STRUCT_BEGIN:
1702 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1705 r = signature_element_length(t, &k);
1712 memcpy(s, t + 1, k - 2);
1715 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1720 if (n_array == (unsigned) -1) {
1725 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1731 n_array = (unsigned) -1;
1747 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1758 va_start(ap, types);
1759 r = bus_message_append_ap(m, types, ap);
1765 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1771 start = ALIGN_TO((size_t) *rindex, align);
1777 /* Verify that padding is 0 */
1778 for (k = *rindex; k < start; k++)
1779 if (((const uint8_t*) p)[k] != 0)
1783 *r = (uint8_t*) p + start;
1790 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1791 struct bus_container *c;
1795 c = message_get_container(m);
1799 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1802 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1807 if (message_end_of_array(m, *rindex))
1810 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1813 static bool validate_nul(const char *s, size_t l) {
1815 /* Check for NUL chars in the string */
1816 if (memchr(s, 0, l))
1819 /* Check for NUL termination */
1826 static bool validate_string(const char *s, size_t l) {
1828 if (!validate_nul(s, l))
1831 /* Check if valid UTF8 */
1832 if (!utf8_is_valid(s))
1838 static bool validate_signature(const char *s, size_t l) {
1840 if (!validate_nul(s, l))
1843 /* Check if valid signature */
1844 if (!signature_is_valid(s, true))
1850 static bool validate_object_path(const char *s, size_t l) {
1852 if (!validate_nul(s, l))
1855 if (!object_path_is_valid(s))
1861 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1862 struct bus_container *c;
1870 if (!bus_type_is_basic(type))
1875 c = message_get_container(m);
1877 if (!c->signature || c->signature[c->index] == 0)
1880 if (c->signature[c->index] != type)
1885 case SD_BUS_TYPE_STRING:
1886 case SD_BUS_TYPE_OBJECT_PATH: {
1891 r = message_peek_body(m, &rindex, 4, 4, &q);
1895 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1896 r = message_peek_body(m, &rindex, 1, l+1, &q);
1902 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1903 if (!validate_object_path(q, l))
1906 if (!validate_string(q, l))
1911 *(const char**) p = q;
1915 case SD_BUS_TYPE_SIGNATURE: {
1920 r = message_peek_body(m, &rindex, 1, 1, &q);
1925 r = message_peek_body(m, &rindex, 1, l+1, &q);
1931 if (!validate_signature(q, l))
1935 *(const char**) p = q;
1943 align = bus_type_get_alignment(type);
1944 sz = bus_type_get_size(type);
1945 assert(align > 0 && sz > 0);
1948 r = message_peek_body(m, &rindex, align, sz, &q);
1954 case SD_BUS_TYPE_BYTE:
1955 *(uint8_t*) p = *(uint8_t*) q;
1958 case SD_BUS_TYPE_BOOLEAN:
1959 *(int*) p = !!*(uint32_t*) q;
1962 case SD_BUS_TYPE_INT16:
1963 case SD_BUS_TYPE_UINT16:
1964 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1967 case SD_BUS_TYPE_INT32:
1968 case SD_BUS_TYPE_UINT32:
1969 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1972 case SD_BUS_TYPE_INT64:
1973 case SD_BUS_TYPE_UINT64:
1974 case SD_BUS_TYPE_DOUBLE:
1975 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1978 case SD_BUS_TYPE_UNIX_FD: {
1981 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1985 *(int*) p = m->fds[j];
1990 assert_not_reached("Unknown basic type...");
1999 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2005 static int bus_message_enter_array(
2007 struct bus_container *c,
2008 const char *contents,
2009 uint32_t **array_size) {
2020 if (!signature_is_single(contents))
2023 alignment = bus_type_get_alignment(contents[0]);
2027 if (!c->signature || c->signature[c->index] == 0)
2030 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2033 if (!startswith(c->signature + c->index + 1, contents))
2037 r = message_peek_body(m, &rindex, 4, 4, &q);
2041 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2044 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2050 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2051 c->index += 1 + strlen(contents);
2055 *array_size = (uint32_t*) q;
2060 static int bus_message_enter_variant(
2062 struct bus_container *c,
2063 const char *contents) {
2074 if (!signature_is_single(contents))
2077 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2080 if (!c->signature || c->signature[c->index] == 0)
2083 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2087 r = message_peek_body(m, &rindex, 1, 1, &q);
2092 r = message_peek_body(m, &rindex, 1, l+1, &q);
2098 if (!validate_signature(q, l))
2101 if (!streq(q, contents))
2104 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2112 static int bus_message_enter_struct(
2114 struct bus_container *c,
2115 const char *contents) {
2124 if (!signature_is_valid(contents, false))
2127 if (!c->signature || c->signature[c->index] == 0)
2130 l = strlen(contents);
2132 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2133 !startswith(c->signature + c->index + 1, contents) ||
2134 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2137 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2141 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2142 c->index += 1 + l + 1;
2147 static int bus_message_enter_dict_entry(
2149 struct bus_container *c,
2150 const char *contents) {
2159 if (!signature_is_pair(contents))
2162 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2165 if (!c->signature || c->signature[c->index] == 0)
2168 l = strlen(contents);
2170 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2171 !startswith(c->signature + c->index + 1, contents) ||
2172 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2175 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2179 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2180 c->index += 1 + l + 1;
2185 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2186 struct bus_container *c, *w;
2187 uint32_t *array_size = NULL;
2199 * We enforce a global limit on container depth, that is much
2200 * higher than the 32 structs and 32 arrays the specification
2201 * mandates. This is simpler to implement for us, and we need
2202 * this only to ensure our container array doesn't grow
2203 * without bounds. We are happy to return any data from a
2204 * message as long as the data itself is valid, even if the
2205 * overall message might be not.
2207 * Note that the message signature is validated when
2208 * parsing the headers, and that validation does check the
2211 * Note that the specification defines no limits on the depth
2212 * of stacked variants, but we do.
2214 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2217 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2222 c = message_get_container(m);
2224 if (!c->signature || c->signature[c->index] == 0)
2227 signature = strdup(contents);
2231 if (type == SD_BUS_TYPE_ARRAY)
2232 r = bus_message_enter_array(m, c, contents, &array_size);
2233 else if (type == SD_BUS_TYPE_VARIANT)
2234 r = bus_message_enter_variant(m, c, contents);
2235 else if (type == SD_BUS_TYPE_STRUCT)
2236 r = bus_message_enter_struct(m, c, contents);
2237 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2238 r = bus_message_enter_dict_entry(m, c, contents);
2247 /* OK, let's fill it in */
2248 w += m->n_containers++;
2249 w->enclosing = type;
2250 w->signature = signature;
2252 w->array_size = array_size;
2253 w->begin = m->rindex;
2258 int sd_bus_message_exit_container(sd_bus_message *m) {
2259 struct bus_container *c;
2265 if (m->n_containers <= 0)
2268 c = message_get_container(m);
2269 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2272 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2273 if (c->begin + l != m->rindex)
2277 if (c->signature && c->signature[c->index] != 0)
2287 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2288 struct bus_container *c;
2296 c = message_get_container(m);
2298 if (!c->signature || c->signature[c->index] == 0)
2301 if (message_end_of_array(m, m->rindex))
2304 if (bus_type_is_basic(c->signature[c->index])) {
2308 *type = c->signature[c->index];
2312 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2318 r = signature_element_length(c->signature+c->index+1, &l);
2324 sig = strndup(c->signature + c->index + 1, l);
2328 free(m->peeked_signature);
2329 m->peeked_signature = sig;
2335 *type = SD_BUS_TYPE_ARRAY;
2340 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2341 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2347 r = signature_element_length(c->signature+c->index, &l);
2352 sig = strndup(c->signature + c->index + 1, l - 2);
2356 free(m->peeked_signature);
2357 m->peeked_signature = sig;
2363 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2368 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2374 r = message_peek_body(m, &rindex, 1, 1, &q);
2381 r = message_peek_body(m, &rindex, 1, l+1, &q);
2387 if (!validate_signature(q, l))
2394 *type = SD_BUS_TYPE_VARIANT;
2403 *type = c->enclosing;
2409 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2410 struct bus_container *c;
2418 reset_containers(m);
2420 m->root_container.index = 0;
2422 c = message_get_container(m);
2424 c = message_get_container(m);
2427 m->rindex = c->begin;
2430 return !isempty(c->signature);
2432 static int message_read_ap(
2437 unsigned n_array, n_struct;
2438 TypeStack stack[BUS_CONTAINER_DEPTH];
2439 unsigned stack_ptr = 0;
2447 /* Ideally, we'd just call ourselves recursively on every
2448 * complex type. However, the state of a va_list that is
2449 * passed to a function is undefined after that function
2450 * returns. This means we need to docode the va_list linearly
2451 * in a single stackframe. We hence implement our own
2452 * home-grown stack in an array. */
2454 n_array = (unsigned) -1;
2455 n_struct = strlen(types);
2460 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2461 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2467 r = sd_bus_message_exit_container(m);
2475 if (n_array != (unsigned) -1)
2484 case SD_BUS_TYPE_BYTE:
2485 case SD_BUS_TYPE_BOOLEAN:
2486 case SD_BUS_TYPE_INT16:
2487 case SD_BUS_TYPE_UINT16:
2488 case SD_BUS_TYPE_INT32:
2489 case SD_BUS_TYPE_UINT32:
2490 case SD_BUS_TYPE_INT64:
2491 case SD_BUS_TYPE_UINT64:
2492 case SD_BUS_TYPE_DOUBLE:
2493 case SD_BUS_TYPE_STRING:
2494 case SD_BUS_TYPE_OBJECT_PATH:
2495 case SD_BUS_TYPE_SIGNATURE:
2496 case SD_BUS_TYPE_UNIX_FD: {
2499 p = va_arg(ap, void*);
2500 r = sd_bus_message_read_basic(m, *t, p);
2509 case SD_BUS_TYPE_ARRAY: {
2512 r = signature_element_length(t + 1, &k);
2518 memcpy(s, t + 1, k);
2521 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2528 if (n_array == (unsigned) -1) {
2533 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2539 n_array = va_arg(ap, unsigned);
2544 case SD_BUS_TYPE_VARIANT: {
2547 s = va_arg(ap, const char *);
2551 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2557 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2562 n_struct = strlen(s);
2563 n_array = (unsigned) -1;
2568 case SD_BUS_TYPE_STRUCT_BEGIN:
2569 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2572 r = signature_element_length(t, &k);
2578 memcpy(s, t + 1, k - 2);
2581 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2588 if (n_array == (unsigned) -1) {
2593 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2599 n_array = (unsigned) -1;
2612 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2623 va_start(ap, types);
2624 r = message_read_ap(m, types, ap);
2630 static int message_peek_fields(
2641 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2644 static int message_peek_field_uint32(
2655 r = message_peek_fields(m, ri, 4, 4, &q);
2660 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2665 static int message_peek_field_string(
2667 bool (*validate)(const char *p),
2678 r = message_peek_field_uint32(m, ri, &l);
2682 r = message_peek_fields(m, ri, 1, l+1, &q);
2687 if (!validate_nul(q, l))
2693 if (!validate_string(q, l))
2703 static int message_peek_field_signature(
2715 r = message_peek_fields(m, ri, 1, 1, &q);
2720 r = message_peek_fields(m, ri, 1, l+1, &q);
2724 if (!validate_signature(q, l))
2733 static int message_skip_fields(
2736 uint32_t array_size,
2737 const char **signature) {
2739 size_t original_index;
2746 original_index = *ri;
2752 if (array_size != (uint32_t) -1 &&
2753 array_size <= *ri - original_index)
2760 if (t == SD_BUS_TYPE_STRING) {
2762 r = message_peek_field_string(m, NULL, ri, NULL);
2768 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2770 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2776 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2778 r = message_peek_field_signature(m, ri, NULL);
2784 } else if (bus_type_is_basic(t)) {
2787 align = bus_type_get_alignment(t);
2788 k = bus_type_get_size(t);
2789 assert(align > 0 && k > 0);
2791 r = message_peek_fields(m, ri, align, k, NULL);
2797 } else if (t == SD_BUS_TYPE_ARRAY) {
2799 r = signature_element_length(*signature+1, &l);
2809 strncpy(sig, *signature + 1, l-1);
2812 alignment = bus_type_get_alignment(sig[0]);
2816 r = message_peek_field_uint32(m, ri, &nas);
2819 if (nas > BUS_ARRAY_MAX_SIZE)
2822 r = message_peek_fields(m, ri, alignment, 0, NULL);
2826 r = message_skip_fields(m, ri, nas, (const char**) &s);
2831 (*signature) += 1 + l;
2833 } else if (t == SD_BUS_TYPE_VARIANT) {
2836 r = message_peek_field_signature(m, ri, &s);
2840 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2846 } else if (t == SD_BUS_TYPE_STRUCT ||
2847 t == SD_BUS_TYPE_DICT_ENTRY) {
2849 r = signature_element_length(*signature, &l);
2856 strncpy(sig, *signature + 1, l-1);
2859 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2870 int bus_message_parse_fields(sd_bus_message *m) {
2873 uint32_t unix_fds = 0;
2877 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2878 const char *signature;
2881 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2885 r = message_peek_field_signature(m, &ri, &signature);
2890 case _SD_BUS_MESSAGE_HEADER_INVALID:
2893 case SD_BUS_MESSAGE_HEADER_PATH:
2898 if (!streq(signature, "o"))
2901 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2904 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2909 if (!streq(signature, "s"))
2912 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2915 case SD_BUS_MESSAGE_HEADER_MEMBER:
2920 if (!streq(signature, "s"))
2923 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2926 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2931 if (!streq(signature, "s"))
2934 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2937 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2942 if (!streq(signature, "s"))
2945 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2948 case SD_BUS_MESSAGE_HEADER_SENDER:
2953 if (!streq(signature, "s"))
2956 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2960 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2964 if (m->root_container.signature)
2967 if (!streq(signature, "g"))
2970 r = message_peek_field_signature(m, &ri, &s);
2978 free(m->root_container.signature);
2979 m->root_container.signature = c;
2983 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2984 if (m->reply_serial != 0)
2987 if (!streq(signature, "u"))
2990 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2994 if (m->reply_serial == 0)
2999 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3003 if (!streq(signature, "u"))
3006 r = message_peek_field_uint32(m, &ri, &unix_fds);
3016 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3023 if (m->n_fds != unix_fds)
3026 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3029 switch (m->header->type) {
3031 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3032 if (!m->path || !m->interface || !m->member)
3036 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3038 if (!m->path || !m->member)
3043 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3045 if (m->reply_serial == 0)
3049 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3051 if (m->reply_serial == 0 || !m->error.name)
3056 /* Try to read the error message, but if we can't it's a non-issue */
3057 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3058 sd_bus_message_read(m, "s", &m->error.message);
3063 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3072 if (m->n_containers > 0)
3075 /* If there's a non-trivial signature set, then add it in here */
3076 if (!isempty(m->root_container.signature)) {
3077 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3083 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3088 l = BUS_MESSAGE_FIELDS_SIZE(m);
3092 /* Add padding at the end, since we know the body
3093 * needs to start at an 8 byte alignment. */
3096 p = message_extend_fields(m, 1, a);
3101 m->header->fields_size -= a;
3104 m->header->serial = serial;
3110 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3120 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3123 int bus_message_dump(sd_bus_message *m) {
3124 const char *u = NULL, *uu = NULL, *s = NULL;
3125 char **cmdline = NULL;
3128 uid_t owner, audit_loginuid;
3129 uint32_t audit_sessionid;
3133 printf("Message %p\n"
3140 "\tfields_size=%u\n"
3145 "\tdestination=%s\n"
3148 "\treply_serial=%u\n"
3150 "\terror.message=%s\n"
3158 BUS_MESSAGE_SERIAL(m),
3159 BUS_MESSAGE_FIELDS_SIZE(m),
3160 BUS_MESSAGE_BODY_SIZE(m),
3162 strna(m->interface),
3164 strna(m->destination),
3166 strna(m->root_container.signature),
3168 strna(m->error.name),
3169 strna(m->error.message),
3173 printf("\tpid=%lu\n", (unsigned long) m->pid);
3175 printf("\ttid=%lu\n", (unsigned long) m->tid);
3177 printf("\tuid=%lu\n", (unsigned long) m->uid);
3179 printf("\tgid=%lu\n", (unsigned long) m->gid);
3180 if (m->pid_starttime != 0)
3181 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3182 if (m->monotonic != 0)
3183 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3184 if (m->realtime != 0)
3185 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3187 printf("\texe=[%s]\n", m->exe);
3189 printf("\tcomm=[%s]\n", m->comm);
3191 printf("\ttid_comm=[%s]\n", m->tid_comm);
3193 printf("\tlabel=[%s]\n", m->label);
3195 printf("\tcgroup=[%s]\n", m->cgroup);
3197 sd_bus_message_get_unit(m, &u);
3199 printf("\tunit=[%s]\n", u);
3200 sd_bus_message_get_user_unit(m, &uu);
3202 printf("\tuser_unit=[%s]\n", uu);
3203 sd_bus_message_get_session(m, &s);
3205 printf("\tsession=[%s]\n", s);
3206 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3207 printf("\towner_uid=%lu\n", (unsigned long) owner);
3208 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3209 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3210 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3211 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3213 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3215 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3218 fputs("\tcmdline=[", stdout);
3219 STRV_FOREACH(c, cmdline) {
3226 fputs("]\n", stdout);
3229 r = sd_bus_message_rewind(m, true);
3231 log_error("Failed to rewind: %s", strerror(-r));
3235 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3238 _cleanup_free_ char *prefix = NULL;
3239 const char *contents = NULL;
3254 r = sd_bus_message_peek_type(m, &type, &contents);
3256 log_error("Failed to peek type: %s", strerror(-r));
3263 r = sd_bus_message_exit_container(m);
3265 log_error("Failed to exit container: %s", strerror(-r));
3271 prefix = strrep("\t", level);
3275 if (type == SD_BUS_TYPE_ARRAY)
3276 printf("%s} END_ARRAY \n", prefix);
3277 else if (type == SD_BUS_TYPE_VARIANT)
3278 printf("%s} END_VARIANT\n", prefix);
3279 else if (type == SD_BUS_TYPE_STRUCT)
3280 printf("%s} END_STRUCT\n", prefix);
3281 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3282 printf("%s} END_DICT_ENTRY\n", prefix);
3287 prefix = strrep("\t", level);
3291 if (bus_type_is_container(type) > 0) {
3292 r = sd_bus_message_enter_container(m, type, contents);
3294 log_error("Failed to enter container: %s", strerror(-r));
3298 if (type == SD_BUS_TYPE_ARRAY)
3299 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3300 else if (type == SD_BUS_TYPE_VARIANT)
3301 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3302 else if (type == SD_BUS_TYPE_STRUCT)
3303 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3304 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3305 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3312 r = sd_bus_message_read_basic(m, type, &basic);
3314 log_error("Failed to get basic: %s", strerror(-r));
3320 case SD_BUS_TYPE_BYTE:
3321 printf("%sBYTE: %u\n", prefix, basic.u8);
3324 case SD_BUS_TYPE_BOOLEAN:
3325 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3328 case SD_BUS_TYPE_INT16:
3329 printf("%sINT16: %i\n", prefix, basic.s16);
3332 case SD_BUS_TYPE_UINT16:
3333 printf("%sUINT16: %u\n", prefix, basic.u16);
3336 case SD_BUS_TYPE_INT32:
3337 printf("%sINT32: %i\n", prefix, basic.s32);
3340 case SD_BUS_TYPE_UINT32:
3341 printf("%sUINT32: %u\n", prefix, basic.u32);
3344 case SD_BUS_TYPE_INT64:
3345 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3348 case SD_BUS_TYPE_UINT64:
3349 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3352 case SD_BUS_TYPE_DOUBLE:
3353 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3356 case SD_BUS_TYPE_STRING:
3357 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3360 case SD_BUS_TYPE_OBJECT_PATH:
3361 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3364 case SD_BUS_TYPE_SIGNATURE:
3365 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3368 case SD_BUS_TYPE_UNIX_FD:
3369 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3373 assert_not_reached("Unknown basic type.");
3377 printf("} END_MESSAGE\n");
3381 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3389 total = BUS_MESSAGE_SIZE(m);
3395 e = mempcpy(p, m->header, sizeof(*m->header));
3398 e = mempcpy(e, m->fields, m->header->fields_size);
3400 if (m->header->fields_size % 8 != 0)
3401 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3405 e = mempcpy(e, m->body, m->header->body_size);
3407 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3415 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3421 r = sd_bus_message_enter_container(m, 'a', "s");
3428 r = sd_bus_message_read_basic(m, 's', &s);
3434 r = strv_extend(l, s);
3439 r = sd_bus_message_exit_container(m);
3446 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3448 const char *t = NULL;
3453 r = sd_bus_message_rewind(m, true);
3457 for (j = 0; j <= i; j++) {
3460 r = sd_bus_message_peek_type(m, &type, NULL);
3464 if (type != SD_BUS_TYPE_STRING &&
3465 type != SD_BUS_TYPE_OBJECT_PATH &&
3466 type != SD_BUS_TYPE_SIGNATURE)
3469 r = sd_bus_message_read_basic(m, type, &t);
3477 int bus_header_size(struct bus_header *h, size_t *sum) {
3483 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3484 fs = h->fields_size;
3486 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3487 fs = bswap_32(h->fields_size);
3488 bs = bswap_32(h->body_size);
3492 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;