]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-bus/bus-message.h
bus: add macro for iterating through body parts of a message
[thirdparty/systemd.git] / src / libsystemd-bus / bus-message.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 #pragma once
4
5 /***
6 This file is part of systemd.
7
8 Copyright 2013 Lennart Poettering
9
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <stdbool.h>
25 #include <byteswap.h>
26 #include <sys/socket.h>
27
28 #include "macro.h"
29 #include "sd-bus.h"
30 #include "kdbus.h"
31 #include "time-util.h"
32
33 struct bus_container {
34 char enclosing;
35
36 char *signature;
37 unsigned index, saved_index;
38
39 uint32_t *array_size;
40 size_t before, begin;
41 };
42
43 struct bus_header {
44 uint8_t endian;
45 uint8_t type;
46 uint8_t flags;
47 uint8_t version;
48 uint32_t body_size;
49 uint32_t serial;
50 uint32_t fields_size;
51 } _packed_;
52
53 struct bus_body_part {
54 void *data;
55 size_t size;
56 size_t mapped;
57 int memfd;
58 bool free_this:1;
59 bool sealed:1;
60 struct bus_body_part *next;
61 };
62
63 struct sd_bus_message {
64 unsigned n_ref;
65
66 sd_bus *bus;
67
68 uint32_t reply_serial;
69
70 const char *path;
71 const char *interface;
72 const char *member;
73 const char *destination;
74 const char *sender;
75
76 sd_bus_error error;
77
78 uid_t uid;
79 gid_t gid;
80 pid_t pid;
81 pid_t tid;
82 usec_t pid_starttime;
83 usec_t monotonic;
84 usec_t realtime;
85
86 bool sealed:1;
87 bool dont_send:1;
88 bool allow_fds:1;
89 bool uid_valid:1;
90 bool gid_valid:1;
91 bool free_header:1;
92 bool free_fields:1;
93 bool free_kdbus:1;
94 bool free_fds:1;
95 bool release_kdbus:1;
96 bool poisoned:1;
97
98 struct bus_header *header;
99 void *fields;
100 struct bus_body_part body;
101 struct bus_body_part *body_end;
102 unsigned n_body_parts;
103
104 char *label;
105
106 size_t rindex;
107 struct bus_body_part *cached_rindex_part;
108 size_t cached_rindex_part_begin;
109
110 uint32_t n_fds;
111 int *fds;
112
113 struct bus_container root_container, *containers;
114 unsigned n_containers;
115
116 struct iovec *iovec;
117 struct iovec iovec_fixed[3];
118 unsigned n_iovec;
119
120 struct kdbus_msg *kdbus;
121
122 char *peeked_signature;
123
124 usec_t timeout;
125
126 char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
127 char destination_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
128
129 const char *exe;
130 const char *comm;
131 const char *tid_comm;
132 const char *cgroup;
133
134 const char *cmdline;
135 size_t cmdline_length;
136 char **cmdline_array;
137
138 char *session;
139 char *unit;
140 char *user_unit;
141
142 struct kdbus_audit *audit;
143
144 uint8_t *capability;
145 size_t capability_size;
146 };
147
148 #define BUS_MESSAGE_NEED_BSWAP(m) ((m)->header->endian != SD_BUS_NATIVE_ENDIAN)
149
150 static inline uint16_t BUS_MESSAGE_BSWAP16(sd_bus_message *m, uint16_t u) {
151 return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_16(u) : u;
152 }
153
154 static inline uint32_t BUS_MESSAGE_BSWAP32(sd_bus_message *m, uint32_t u) {
155 return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_32(u) : u;
156 }
157
158 static inline uint64_t BUS_MESSAGE_BSWAP64(sd_bus_message *m, uint64_t u) {
159 return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_64(u) : u;
160 }
161
162 static inline uint32_t BUS_MESSAGE_SERIAL(sd_bus_message *m) {
163 return BUS_MESSAGE_BSWAP32(m, m->header->serial);
164 }
165
166 static inline uint32_t BUS_MESSAGE_BODY_SIZE(sd_bus_message *m) {
167 return BUS_MESSAGE_BSWAP32(m, m->header->body_size);
168 }
169
170 static inline uint32_t BUS_MESSAGE_FIELDS_SIZE(sd_bus_message *m) {
171 return BUS_MESSAGE_BSWAP32(m, m->header->fields_size);
172 }
173
174 static inline uint32_t BUS_MESSAGE_SIZE(sd_bus_message *m) {
175 return
176 sizeof(struct bus_header) +
177 ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)) +
178 BUS_MESSAGE_BODY_SIZE(m);
179 }
180
181 static inline void bus_message_unrefp(sd_bus_message **m) {
182 sd_bus_message_unref(*m);
183 }
184
185 #define _cleanup_bus_message_unref_ __attribute__((cleanup(bus_message_unrefp)))
186
187 int bus_message_seal(sd_bus_message *m, uint64_t serial);
188 int bus_message_dump(sd_bus_message *m);
189 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz);
190 int bus_message_read_strv_extend(sd_bus_message *m, char ***l);
191
192 int bus_message_from_header(
193 void *header,
194 size_t length,
195 int *fds,
196 unsigned n_fds,
197 const struct ucred *ucred,
198 const char *label,
199 size_t extra,
200 sd_bus_message **ret);
201
202 int bus_message_from_malloc(
203 void *buffer,
204 size_t length,
205 int *fds,
206 unsigned n_fds,
207 const struct ucred *ucred,
208 const char *label,
209 sd_bus_message **ret);
210
211 const char* bus_message_get_arg(sd_bus_message *m, unsigned i);
212
213 int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
214
215 int bus_message_parse_fields(sd_bus_message *m);
216
217 int bus_header_size(struct bus_header *h, size_t *sum);
218
219 struct bus_body_part *message_append_part(sd_bus_message *m);
220
221 #define MESSAGE_FOREACH_PART(part, i, m) \
222 for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts; (i)++, (part) = (part)->next)