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 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1211 struct bus_container *c;
1223 c = message_get_container(m);
1225 if (c->signature && c->signature[c->index]) {
1226 /* Container signature is already set */
1228 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1231 /* Maybe we can append to the signature? But only if this is the top-level container*/
1232 if (c->enclosing != 0)
1235 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1241 a = message_extend_body(m, 4, 4 + size + 1);
1247 *(uint32_t*) a = size;
1252 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1259 c->signature[c->index] = 0;
1264 static int bus_message_open_array(
1266 struct bus_container *c,
1267 const char *contents,
1268 uint32_t **array_size) {
1281 if (!signature_is_single(contents))
1284 alignment = bus_type_get_alignment(contents[0]);
1288 if (c->signature && c->signature[c->index]) {
1290 /* Verify the existing signature */
1292 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1295 if (!startswith(c->signature + c->index + 1, contents))
1298 nindex = c->index + 1 + strlen(contents);
1300 if (c->enclosing != 0)
1303 /* Extend the existing signature */
1305 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1309 nindex = e - c->signature;
1312 saved = m->header->body_size;
1313 a = message_extend_body(m, 4, 4);
1315 /* Truncate extended signature again */
1317 c->signature[c->index] = 0;
1323 if (!message_extend_body(m, alignment, 0)) {
1324 /* Add alignment between size and first element */
1326 c->signature[c->index] = 0;
1328 m->header->body_size = saved;
1332 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1335 /* m->body might have changed so let's readjust a */
1336 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1343 static int bus_message_open_variant(
1345 struct bus_container *c,
1346 const char *contents) {
1356 if (!signature_is_single(contents))
1359 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1362 if (c->signature && c->signature[c->index]) {
1364 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1368 if (c->enclosing != 0)
1371 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1376 l = strlen(contents);
1377 a = message_extend_body(m, 1, 1 + l + 1);
1379 /* Truncate extended signature again */
1381 c->signature[c->index] = 0;
1387 memcpy((uint8_t*) a + 1, contents, l + 1);
1389 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1395 static int bus_message_open_struct(
1397 struct bus_container *c,
1398 const char *contents) {
1407 if (!signature_is_valid(contents, false))
1410 if (c->signature && c->signature[c->index]) {
1413 l = strlen(contents);
1415 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1416 !startswith(c->signature + c->index + 1, contents) ||
1417 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1420 nindex = c->index + 1 + l + 1;
1422 if (c->enclosing != 0)
1425 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1429 nindex = e - c->signature;
1432 /* Align contents to 8 byte boundary */
1433 if (!message_extend_body(m, 8, 0)) {
1435 c->signature[c->index] = 0;
1440 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1446 static int bus_message_open_dict_entry(
1448 struct bus_container *c,
1449 const char *contents) {
1457 if (!signature_is_pair(contents))
1460 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1463 if (c->signature && c->signature[c->index]) {
1466 l = strlen(contents);
1468 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1469 !startswith(c->signature + c->index + 1, contents) ||
1470 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1473 nindex = c->index + 1 + l + 1;
1477 /* Align contents to 8 byte boundary */
1478 if (!message_extend_body(m, 8, 0))
1481 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1487 int sd_bus_message_open_container(
1490 const char *contents) {
1492 struct bus_container *c, *w;
1493 uint32_t *array_size = NULL;
1505 /* Make sure we have space for one more container */
1506 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1511 c = message_get_container(m);
1513 signature = strdup(contents);
1517 /* Save old index in the parent container, in case we have to
1518 * abort this container */
1519 c->saved_index = c->index;
1520 before = m->header->body_size;
1522 if (type == SD_BUS_TYPE_ARRAY)
1523 r = bus_message_open_array(m, c, contents, &array_size);
1524 else if (type == SD_BUS_TYPE_VARIANT)
1525 r = bus_message_open_variant(m, c, contents);
1526 else if (type == SD_BUS_TYPE_STRUCT)
1527 r = bus_message_open_struct(m, c, contents);
1528 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1529 r = bus_message_open_dict_entry(m, c, contents);
1538 /* OK, let's fill it in */
1539 w += m->n_containers++;
1540 w->enclosing = type;
1541 w->signature = signature;
1543 w->array_size = array_size;
1545 w->begin = m->rindex;
1550 int sd_bus_message_close_container(sd_bus_message *m) {
1551 struct bus_container *c;
1557 if (m->n_containers <= 0)
1560 c = message_get_container(m);
1561 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1562 if (c->signature && c->signature[c->index] != 0)
1571 static void message_abort_container(sd_bus_message *m) {
1572 struct bus_container *c;
1577 assert(m->n_containers > 0);
1579 c = message_get_container(m);
1582 assert(m->header->body_size >= c->before);
1583 delta = m->header->body_size - c->before;
1584 m->header->body_size = c->before;
1586 /* Free container */
1590 /* Correct index of new top-level container */
1591 c = message_get_container(m);
1592 c->index = c->saved_index;
1594 /* Correct array sizes all the way up */
1595 for (c = m->containers; c < m->containers + m->n_containers; c++)
1596 if (c->array_size) {
1597 assert(*c->array_size >= delta);
1598 *c->array_size -= delta;
1608 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1615 stack[*i].types = types;
1616 stack[*i].n_struct = n_struct;
1617 stack[*i].n_array = n_array;
1623 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1634 *types = stack[*i].types;
1635 *n_struct = stack[*i].n_struct;
1636 *n_array = stack[*i].n_array;
1641 int bus_message_append_ap(
1646 unsigned n_array, n_struct;
1647 TypeStack stack[BUS_CONTAINER_DEPTH];
1648 unsigned stack_ptr = 0;
1656 n_array = (unsigned) -1;
1657 n_struct = strlen(types);
1662 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1663 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1669 r = sd_bus_message_close_container(m);
1677 if (n_array != (unsigned) -1)
1686 case SD_BUS_TYPE_BYTE: {
1689 x = (uint8_t) va_arg(ap, int);
1690 r = sd_bus_message_append_basic(m, *t, &x);
1694 case SD_BUS_TYPE_BOOLEAN:
1695 case SD_BUS_TYPE_INT32:
1696 case SD_BUS_TYPE_UINT32:
1697 case SD_BUS_TYPE_UNIX_FD: {
1700 /* We assume a boolean is the same as int32_t */
1701 assert_cc(sizeof(int32_t) == sizeof(int));
1703 x = va_arg(ap, uint32_t);
1704 r = sd_bus_message_append_basic(m, *t, &x);
1708 case SD_BUS_TYPE_INT16:
1709 case SD_BUS_TYPE_UINT16: {
1712 x = (uint16_t) va_arg(ap, int);
1713 r = sd_bus_message_append_basic(m, *t, &x);
1717 case SD_BUS_TYPE_INT64:
1718 case SD_BUS_TYPE_UINT64:
1719 case SD_BUS_TYPE_DOUBLE: {
1722 x = va_arg(ap, uint64_t);
1723 r = sd_bus_message_append_basic(m, *t, &x);
1727 case SD_BUS_TYPE_STRING:
1728 case SD_BUS_TYPE_OBJECT_PATH:
1729 case SD_BUS_TYPE_SIGNATURE: {
1732 x = va_arg(ap, const char*);
1733 r = sd_bus_message_append_basic(m, *t, x);
1737 case SD_BUS_TYPE_ARRAY: {
1740 r = signature_element_length(t + 1, &k);
1746 memcpy(s, t + 1, k);
1749 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1754 if (n_array == (unsigned) -1) {
1759 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1765 n_array = va_arg(ap, unsigned);
1770 case SD_BUS_TYPE_VARIANT: {
1773 s = va_arg(ap, const char*);
1777 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1781 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1786 n_struct = strlen(s);
1787 n_array = (unsigned) -1;
1792 case SD_BUS_TYPE_STRUCT_BEGIN:
1793 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1796 r = signature_element_length(t, &k);
1803 memcpy(s, t + 1, k - 2);
1806 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1811 if (n_array == (unsigned) -1) {
1816 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1822 n_array = (unsigned) -1;
1838 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1849 va_start(ap, types);
1850 r = bus_message_append_ap(m, types, ap);
1856 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
1865 if (!bus_type_is_trivial(type))
1867 if (!ptr && size > 0)
1870 align = bus_type_get_alignment(type);
1871 sz = bus_type_get_size(type);
1873 assert_se(align > 0);
1879 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1883 a = message_extend_body(m, align, size);
1889 r = sd_bus_message_close_container(m);
1897 message_abort_container(m);
1901 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
1905 if (!ptr && size > 0)
1908 r = sd_bus_message_append_array_space(m, type, size, &p);
1913 memcpy(p, ptr, size);
1918 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1924 start = ALIGN_TO((size_t) *rindex, align);
1930 /* Verify that padding is 0 */
1931 for (k = *rindex; k < start; k++)
1932 if (((const uint8_t*) p)[k] != 0)
1936 *r = (uint8_t*) p + start;
1943 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1944 struct bus_container *c;
1948 c = message_get_container(m);
1952 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1955 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1960 if (message_end_of_array(m, *rindex))
1963 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1966 static bool validate_nul(const char *s, size_t l) {
1968 /* Check for NUL chars in the string */
1969 if (memchr(s, 0, l))
1972 /* Check for NUL termination */
1979 static bool validate_string(const char *s, size_t l) {
1981 if (!validate_nul(s, l))
1984 /* Check if valid UTF8 */
1985 if (!utf8_is_valid(s))
1991 static bool validate_signature(const char *s, size_t l) {
1993 if (!validate_nul(s, l))
1996 /* Check if valid signature */
1997 if (!signature_is_valid(s, true))
2003 static bool validate_object_path(const char *s, size_t l) {
2005 if (!validate_nul(s, l))
2008 if (!object_path_is_valid(s))
2014 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2015 struct bus_container *c;
2023 if (!bus_type_is_basic(type))
2028 c = message_get_container(m);
2030 if (!c->signature || c->signature[c->index] == 0)
2033 if (c->signature[c->index] != type)
2038 case SD_BUS_TYPE_STRING:
2039 case SD_BUS_TYPE_OBJECT_PATH: {
2044 r = message_peek_body(m, &rindex, 4, 4, &q);
2048 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2049 r = message_peek_body(m, &rindex, 1, l+1, &q);
2055 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2056 if (!validate_object_path(q, l))
2059 if (!validate_string(q, l))
2064 *(const char**) p = q;
2068 case SD_BUS_TYPE_SIGNATURE: {
2073 r = message_peek_body(m, &rindex, 1, 1, &q);
2078 r = message_peek_body(m, &rindex, 1, l+1, &q);
2084 if (!validate_signature(q, l))
2088 *(const char**) p = q;
2096 align = bus_type_get_alignment(type);
2097 sz = bus_type_get_size(type);
2098 assert(align > 0 && sz > 0);
2101 r = message_peek_body(m, &rindex, align, sz, &q);
2107 case SD_BUS_TYPE_BYTE:
2108 *(uint8_t*) p = *(uint8_t*) q;
2111 case SD_BUS_TYPE_BOOLEAN:
2112 *(int*) p = !!*(uint32_t*) q;
2115 case SD_BUS_TYPE_INT16:
2116 case SD_BUS_TYPE_UINT16:
2117 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2120 case SD_BUS_TYPE_INT32:
2121 case SD_BUS_TYPE_UINT32:
2122 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2125 case SD_BUS_TYPE_INT64:
2126 case SD_BUS_TYPE_UINT64:
2127 case SD_BUS_TYPE_DOUBLE:
2128 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2131 case SD_BUS_TYPE_UNIX_FD: {
2134 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2138 *(int*) p = m->fds[j];
2143 assert_not_reached("Unknown basic type...");
2152 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2158 static int bus_message_enter_array(
2160 struct bus_container *c,
2161 const char *contents,
2162 uint32_t **array_size) {
2173 if (!signature_is_single(contents))
2176 alignment = bus_type_get_alignment(contents[0]);
2180 if (!c->signature || c->signature[c->index] == 0)
2183 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2186 if (!startswith(c->signature + c->index + 1, contents))
2190 r = message_peek_body(m, &rindex, 4, 4, &q);
2194 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2197 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2203 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2204 c->index += 1 + strlen(contents);
2208 *array_size = (uint32_t*) q;
2213 static int bus_message_enter_variant(
2215 struct bus_container *c,
2216 const char *contents) {
2227 if (!signature_is_single(contents))
2230 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2233 if (!c->signature || c->signature[c->index] == 0)
2236 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2240 r = message_peek_body(m, &rindex, 1, 1, &q);
2245 r = message_peek_body(m, &rindex, 1, l+1, &q);
2251 if (!validate_signature(q, l))
2254 if (!streq(q, contents))
2257 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2265 static int bus_message_enter_struct(
2267 struct bus_container *c,
2268 const char *contents) {
2277 if (!signature_is_valid(contents, false))
2280 if (!c->signature || c->signature[c->index] == 0)
2283 l = strlen(contents);
2285 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2286 !startswith(c->signature + c->index + 1, contents) ||
2287 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2290 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2294 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2295 c->index += 1 + l + 1;
2300 static int bus_message_enter_dict_entry(
2302 struct bus_container *c,
2303 const char *contents) {
2312 if (!signature_is_pair(contents))
2315 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2318 if (!c->signature || c->signature[c->index] == 0)
2321 l = strlen(contents);
2323 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2324 !startswith(c->signature + c->index + 1, contents) ||
2325 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2328 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2332 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2333 c->index += 1 + l + 1;
2338 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2339 struct bus_container *c, *w;
2340 uint32_t *array_size = NULL;
2353 * We enforce a global limit on container depth, that is much
2354 * higher than the 32 structs and 32 arrays the specification
2355 * mandates. This is simpler to implement for us, and we need
2356 * this only to ensure our container array doesn't grow
2357 * without bounds. We are happy to return any data from a
2358 * message as long as the data itself is valid, even if the
2359 * overall message might be not.
2361 * Note that the message signature is validated when
2362 * parsing the headers, and that validation does check the
2365 * Note that the specification defines no limits on the depth
2366 * of stacked variants, but we do.
2368 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2371 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2376 c = message_get_container(m);
2378 if (!c->signature || c->signature[c->index] == 0)
2381 signature = strdup(contents);
2385 c->saved_index = c->index;
2388 if (type == SD_BUS_TYPE_ARRAY)
2389 r = bus_message_enter_array(m, c, contents, &array_size);
2390 else if (type == SD_BUS_TYPE_VARIANT)
2391 r = bus_message_enter_variant(m, c, contents);
2392 else if (type == SD_BUS_TYPE_STRUCT)
2393 r = bus_message_enter_struct(m, c, contents);
2394 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2395 r = bus_message_enter_dict_entry(m, c, contents);
2404 /* OK, let's fill it in */
2405 w += m->n_containers++;
2406 w->enclosing = type;
2407 w->signature = signature;
2409 w->array_size = array_size;
2411 w->begin = m->rindex;
2416 int sd_bus_message_exit_container(sd_bus_message *m) {
2417 struct bus_container *c;
2423 if (m->n_containers <= 0)
2426 c = message_get_container(m);
2427 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2430 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2431 if (c->begin + l != m->rindex)
2435 if (c->signature && c->signature[c->index] != 0)
2445 static void message_quit_container(sd_bus_message *m) {
2446 struct bus_container *c;
2450 assert(m->n_containers > 0);
2452 c = message_get_container(m);
2455 assert(m->rindex >= c->before);
2456 m->rindex = c->before;
2458 /* Free container */
2462 /* Correct index of new top-level container */
2463 c = message_get_container(m);
2464 c->index = c->saved_index;
2467 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2468 struct bus_container *c;
2476 c = message_get_container(m);
2478 if (!c->signature || c->signature[c->index] == 0)
2481 if (message_end_of_array(m, m->rindex))
2484 if (bus_type_is_basic(c->signature[c->index])) {
2488 *type = c->signature[c->index];
2492 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2498 r = signature_element_length(c->signature+c->index+1, &l);
2504 sig = strndup(c->signature + c->index + 1, l);
2508 free(m->peeked_signature);
2509 m->peeked_signature = sig;
2515 *type = SD_BUS_TYPE_ARRAY;
2520 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2521 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2527 r = signature_element_length(c->signature+c->index, &l);
2532 sig = strndup(c->signature + c->index + 1, l - 2);
2536 free(m->peeked_signature);
2537 m->peeked_signature = sig;
2543 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2548 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2554 r = message_peek_body(m, &rindex, 1, 1, &q);
2561 r = message_peek_body(m, &rindex, 1, l+1, &q);
2567 if (!validate_signature(q, l))
2574 *type = SD_BUS_TYPE_VARIANT;
2583 *type = c->enclosing;
2589 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2590 struct bus_container *c;
2598 reset_containers(m);
2600 m->root_container.index = 0;
2602 c = message_get_container(m);
2604 c = message_get_container(m);
2607 m->rindex = c->begin;
2610 return !isempty(c->signature);
2612 static int message_read_ap(
2617 unsigned n_array, n_struct;
2618 TypeStack stack[BUS_CONTAINER_DEPTH];
2619 unsigned stack_ptr = 0;
2627 /* Ideally, we'd just call ourselves recursively on every
2628 * complex type. However, the state of a va_list that is
2629 * passed to a function is undefined after that function
2630 * returns. This means we need to docode the va_list linearly
2631 * in a single stackframe. We hence implement our own
2632 * home-grown stack in an array. */
2634 n_array = (unsigned) -1;
2635 n_struct = strlen(types);
2640 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2641 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2647 r = sd_bus_message_exit_container(m);
2655 if (n_array != (unsigned) -1)
2664 case SD_BUS_TYPE_BYTE:
2665 case SD_BUS_TYPE_BOOLEAN:
2666 case SD_BUS_TYPE_INT16:
2667 case SD_BUS_TYPE_UINT16:
2668 case SD_BUS_TYPE_INT32:
2669 case SD_BUS_TYPE_UINT32:
2670 case SD_BUS_TYPE_INT64:
2671 case SD_BUS_TYPE_UINT64:
2672 case SD_BUS_TYPE_DOUBLE:
2673 case SD_BUS_TYPE_STRING:
2674 case SD_BUS_TYPE_OBJECT_PATH:
2675 case SD_BUS_TYPE_SIGNATURE:
2676 case SD_BUS_TYPE_UNIX_FD: {
2679 p = va_arg(ap, void*);
2680 r = sd_bus_message_read_basic(m, *t, p);
2689 case SD_BUS_TYPE_ARRAY: {
2692 r = signature_element_length(t + 1, &k);
2698 memcpy(s, t + 1, k);
2701 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2708 if (n_array == (unsigned) -1) {
2713 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2719 n_array = va_arg(ap, unsigned);
2724 case SD_BUS_TYPE_VARIANT: {
2727 s = va_arg(ap, const char *);
2731 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2737 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2742 n_struct = strlen(s);
2743 n_array = (unsigned) -1;
2748 case SD_BUS_TYPE_STRUCT_BEGIN:
2749 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2752 r = signature_element_length(t, &k);
2758 memcpy(s, t + 1, k - 2);
2761 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2768 if (n_array == (unsigned) -1) {
2773 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2779 n_array = (unsigned) -1;
2792 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2803 va_start(ap, types);
2804 r = message_read_ap(m, types, ap);
2810 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
2811 struct bus_container *c;
2821 if (!bus_type_is_trivial(type))
2827 if (BUS_MESSAGE_NEED_BSWAP(m))
2830 align = bus_type_get_alignment(type);
2834 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2838 c = message_get_container(m);
2839 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2841 r = message_peek_body(m, &m->rindex, align, sz, &p);
2849 r = sd_bus_message_exit_container(m);
2853 *ptr = (const void*) p;
2859 message_quit_container(m);
2863 static int message_peek_fields(
2874 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2877 static int message_peek_field_uint32(
2888 r = message_peek_fields(m, ri, 4, 4, &q);
2893 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2898 static int message_peek_field_string(
2900 bool (*validate)(const char *p),
2911 r = message_peek_field_uint32(m, ri, &l);
2915 r = message_peek_fields(m, ri, 1, l+1, &q);
2920 if (!validate_nul(q, l))
2926 if (!validate_string(q, l))
2936 static int message_peek_field_signature(
2948 r = message_peek_fields(m, ri, 1, 1, &q);
2953 r = message_peek_fields(m, ri, 1, l+1, &q);
2957 if (!validate_signature(q, l))
2966 static int message_skip_fields(
2969 uint32_t array_size,
2970 const char **signature) {
2972 size_t original_index;
2979 original_index = *ri;
2985 if (array_size != (uint32_t) -1 &&
2986 array_size <= *ri - original_index)
2993 if (t == SD_BUS_TYPE_STRING) {
2995 r = message_peek_field_string(m, NULL, ri, NULL);
3001 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3003 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3009 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3011 r = message_peek_field_signature(m, ri, NULL);
3017 } else if (bus_type_is_basic(t)) {
3020 align = bus_type_get_alignment(t);
3021 k = bus_type_get_size(t);
3022 assert(align > 0 && k > 0);
3024 r = message_peek_fields(m, ri, align, k, NULL);
3030 } else if (t == SD_BUS_TYPE_ARRAY) {
3032 r = signature_element_length(*signature+1, &l);
3042 strncpy(sig, *signature + 1, l-1);
3045 alignment = bus_type_get_alignment(sig[0]);
3049 r = message_peek_field_uint32(m, ri, &nas);
3052 if (nas > BUS_ARRAY_MAX_SIZE)
3055 r = message_peek_fields(m, ri, alignment, 0, NULL);
3059 r = message_skip_fields(m, ri, nas, (const char**) &s);
3064 (*signature) += 1 + l;
3066 } else if (t == SD_BUS_TYPE_VARIANT) {
3069 r = message_peek_field_signature(m, ri, &s);
3073 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3079 } else if (t == SD_BUS_TYPE_STRUCT ||
3080 t == SD_BUS_TYPE_DICT_ENTRY) {
3082 r = signature_element_length(*signature, &l);
3089 strncpy(sig, *signature + 1, l-1);
3092 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3103 int bus_message_parse_fields(sd_bus_message *m) {
3106 uint32_t unix_fds = 0;
3110 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3111 const char *signature;
3114 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3118 r = message_peek_field_signature(m, &ri, &signature);
3123 case _SD_BUS_MESSAGE_HEADER_INVALID:
3126 case SD_BUS_MESSAGE_HEADER_PATH:
3131 if (!streq(signature, "o"))
3134 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3137 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3142 if (!streq(signature, "s"))
3145 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3148 case SD_BUS_MESSAGE_HEADER_MEMBER:
3153 if (!streq(signature, "s"))
3156 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3159 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3164 if (!streq(signature, "s"))
3167 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3170 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3175 if (!streq(signature, "s"))
3178 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3181 case SD_BUS_MESSAGE_HEADER_SENDER:
3186 if (!streq(signature, "s"))
3189 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3193 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3197 if (m->root_container.signature)
3200 if (!streq(signature, "g"))
3203 r = message_peek_field_signature(m, &ri, &s);
3211 free(m->root_container.signature);
3212 m->root_container.signature = c;
3216 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3217 if (m->reply_serial != 0)
3220 if (!streq(signature, "u"))
3223 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3227 if (m->reply_serial == 0)
3232 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3236 if (!streq(signature, "u"))
3239 r = message_peek_field_uint32(m, &ri, &unix_fds);
3249 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3256 if (m->n_fds != unix_fds)
3259 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3262 switch (m->header->type) {
3264 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3265 if (!m->path || !m->interface || !m->member)
3269 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3271 if (!m->path || !m->member)
3276 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3278 if (m->reply_serial == 0)
3282 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3284 if (m->reply_serial == 0 || !m->error.name)
3289 /* Try to read the error message, but if we can't it's a non-issue */
3290 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3291 sd_bus_message_read(m, "s", &m->error.message);
3296 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3305 if (m->n_containers > 0)
3308 /* If there's a non-trivial signature set, then add it in here */
3309 if (!isempty(m->root_container.signature)) {
3310 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3316 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3321 l = BUS_MESSAGE_FIELDS_SIZE(m);
3325 /* Add padding at the end, since we know the body
3326 * needs to start at an 8 byte alignment. */
3329 p = message_extend_fields(m, 1, a);
3334 m->header->fields_size -= a;
3337 m->header->serial = serial;
3343 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3353 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3356 int bus_message_dump(sd_bus_message *m) {
3357 const char *u = NULL, *uu = NULL, *s = NULL;
3358 char **cmdline = NULL;
3361 uid_t owner, audit_loginuid;
3362 uint32_t audit_sessionid;
3366 printf("Message %p\n"
3373 "\tfields_size=%u\n"
3378 "\tdestination=%s\n"
3381 "\treply_serial=%u\n"
3383 "\terror.message=%s\n"
3391 BUS_MESSAGE_SERIAL(m),
3392 BUS_MESSAGE_FIELDS_SIZE(m),
3393 BUS_MESSAGE_BODY_SIZE(m),
3395 strna(m->interface),
3397 strna(m->destination),
3399 strna(m->root_container.signature),
3401 strna(m->error.name),
3402 strna(m->error.message),
3406 printf("\tpid=%lu\n", (unsigned long) m->pid);
3408 printf("\ttid=%lu\n", (unsigned long) m->tid);
3410 printf("\tuid=%lu\n", (unsigned long) m->uid);
3412 printf("\tgid=%lu\n", (unsigned long) m->gid);
3413 if (m->pid_starttime != 0)
3414 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3415 if (m->monotonic != 0)
3416 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3417 if (m->realtime != 0)
3418 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3420 printf("\texe=[%s]\n", m->exe);
3422 printf("\tcomm=[%s]\n", m->comm);
3424 printf("\ttid_comm=[%s]\n", m->tid_comm);
3426 printf("\tlabel=[%s]\n", m->label);
3428 printf("\tcgroup=[%s]\n", m->cgroup);
3430 sd_bus_message_get_unit(m, &u);
3432 printf("\tunit=[%s]\n", u);
3433 sd_bus_message_get_user_unit(m, &uu);
3435 printf("\tuser_unit=[%s]\n", uu);
3436 sd_bus_message_get_session(m, &s);
3438 printf("\tsession=[%s]\n", s);
3439 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3440 printf("\towner_uid=%lu\n", (unsigned long) owner);
3441 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3442 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3443 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3444 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3446 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3448 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3451 fputs("\tcmdline=[", stdout);
3452 STRV_FOREACH(c, cmdline) {
3459 fputs("]\n", stdout);
3462 r = sd_bus_message_rewind(m, true);
3464 log_error("Failed to rewind: %s", strerror(-r));
3468 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3471 _cleanup_free_ char *prefix = NULL;
3472 const char *contents = NULL;
3487 r = sd_bus_message_peek_type(m, &type, &contents);
3489 log_error("Failed to peek type: %s", strerror(-r));
3496 r = sd_bus_message_exit_container(m);
3498 log_error("Failed to exit container: %s", strerror(-r));
3504 prefix = strrep("\t", level);
3508 if (type == SD_BUS_TYPE_ARRAY)
3509 printf("%s} END_ARRAY \n", prefix);
3510 else if (type == SD_BUS_TYPE_VARIANT)
3511 printf("%s} END_VARIANT\n", prefix);
3512 else if (type == SD_BUS_TYPE_STRUCT)
3513 printf("%s} END_STRUCT\n", prefix);
3514 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3515 printf("%s} END_DICT_ENTRY\n", prefix);
3520 prefix = strrep("\t", level);
3524 if (bus_type_is_container(type) > 0) {
3525 r = sd_bus_message_enter_container(m, type, contents);
3527 log_error("Failed to enter container: %s", strerror(-r));
3531 if (type == SD_BUS_TYPE_ARRAY)
3532 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3533 else if (type == SD_BUS_TYPE_VARIANT)
3534 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3535 else if (type == SD_BUS_TYPE_STRUCT)
3536 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3537 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3538 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3545 r = sd_bus_message_read_basic(m, type, &basic);
3547 log_error("Failed to get basic: %s", strerror(-r));
3553 case SD_BUS_TYPE_BYTE:
3554 printf("%sBYTE: %u\n", prefix, basic.u8);
3557 case SD_BUS_TYPE_BOOLEAN:
3558 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3561 case SD_BUS_TYPE_INT16:
3562 printf("%sINT16: %i\n", prefix, basic.s16);
3565 case SD_BUS_TYPE_UINT16:
3566 printf("%sUINT16: %u\n", prefix, basic.u16);
3569 case SD_BUS_TYPE_INT32:
3570 printf("%sINT32: %i\n", prefix, basic.s32);
3573 case SD_BUS_TYPE_UINT32:
3574 printf("%sUINT32: %u\n", prefix, basic.u32);
3577 case SD_BUS_TYPE_INT64:
3578 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3581 case SD_BUS_TYPE_UINT64:
3582 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3585 case SD_BUS_TYPE_DOUBLE:
3586 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3589 case SD_BUS_TYPE_STRING:
3590 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3593 case SD_BUS_TYPE_OBJECT_PATH:
3594 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3597 case SD_BUS_TYPE_SIGNATURE:
3598 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3601 case SD_BUS_TYPE_UNIX_FD:
3602 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3606 assert_not_reached("Unknown basic type.");
3610 printf("} END_MESSAGE\n");
3614 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3622 total = BUS_MESSAGE_SIZE(m);
3628 e = mempcpy(p, m->header, sizeof(*m->header));
3631 e = mempcpy(e, m->fields, m->header->fields_size);
3633 if (m->header->fields_size % 8 != 0)
3634 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3638 e = mempcpy(e, m->body, m->header->body_size);
3640 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3648 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3654 r = sd_bus_message_enter_container(m, 'a', "s");
3661 r = sd_bus_message_read_basic(m, 's', &s);
3667 r = strv_extend(l, s);
3672 r = sd_bus_message_exit_container(m);
3679 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3681 const char *t = NULL;
3686 r = sd_bus_message_rewind(m, true);
3690 for (j = 0; j <= i; j++) {
3693 r = sd_bus_message_peek_type(m, &type, NULL);
3697 if (type != SD_BUS_TYPE_STRING &&
3698 type != SD_BUS_TYPE_OBJECT_PATH &&
3699 type != SD_BUS_TYPE_SIGNATURE)
3702 r = sd_bus_message_read_basic(m, type, &t);
3710 int bus_header_size(struct bus_header *h, size_t *sum) {
3716 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3717 fs = h->fields_size;
3719 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3720 fs = bswap_32(h->fields_size);
3721 bs = bswap_32(h->body_size);
3725 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;