]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-dump.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-dump.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
3db0e46b
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
b5efdb8a 21#include "alloc-util.h"
0d39fa9c 22#include "bus-dump.h"
07630cea
LP
23#include "bus-internal.h"
24#include "bus-message.h"
25#include "bus-type.h"
2822da4f 26#include "cap-list.h"
430f0182 27#include "capability-util.h"
0d39fa9c 28#include "fileio.h"
f97b34a6 29#include "format-util.h"
8752c575 30#include "locale-util.h"
07630cea
LP
31#include "macro.h"
32#include "string-util.h"
33#include "strv.h"
288a74cc 34#include "terminal-util.h"
07630cea 35#include "util.h"
3db0e46b 36
d55192ad 37static char *indent(unsigned level, unsigned flags) {
f8cfb5f5 38 char *p;
d55192ad 39 unsigned n, i = 0;
f8cfb5f5 40
d55192ad
LP
41 n = 0;
42
43 if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
44 level -= 1;
45
46 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
47 n += 2;
48
49 p = new(char, n + level*8 + 1);
f8cfb5f5
LP
50 if (!p)
51 return NULL;
52
d55192ad
LP
53 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
54 p[i++] = ' ';
55 p[i++] = ' ';
56 }
57
58 memset(p + i, ' ', level*8);
59 p[i + level*8] = 0;
f8cfb5f5
LP
60
61 return p;
62}
63
d55192ad 64int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
3db0e46b
LP
65 unsigned level = 1;
66 int r;
3db0e46b
LP
67
68 assert(m);
69
70 if (!f)
71 f = stdout;
72
d55192ad 73 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
3db0e46b 74 fprintf(f,
1fa2f38f 75 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
f8cfb5f5
LP
76 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
77 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
323b7dc9 78 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(),
1fc464f6 79 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
f8cfb5f5 80 m->header->endian,
3db0e46b 81 m->header->flags,
ca7b42c8 82 m->header->version,
1fa2f38f 83 m->priority);
a009c158
LS
84
85 /* Display synthetic message serial number in a more readable
86 * format than (uint32_t) -1 */
693eb9a2
LP
87 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
88 fprintf(f, " Cookie=-1");
a009c158 89 else
42c4ebcb 90 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
3db0e46b 91
693eb9a2 92 if (m->reply_cookie != 0)
42c4ebcb 93 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
3db0e46b
LP
94
95 fputs("\n", f);
96
97 if (m->sender)
1fc464f6 98 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_normal());
3db0e46b 99 if (m->destination)
1fc464f6 100 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_normal());
3db0e46b 101 if (m->path)
1fc464f6 102 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_normal());
3db0e46b 103 if (m->interface)
1fc464f6 104 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_normal());
3db0e46b 105 if (m->member)
1fc464f6 106 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_normal());
3db0e46b
LP
107
108 if (m->sender || m->destination || m->path || m->interface || m->member)
109 fputs("\n", f);
110
111 if (sd_bus_error_is_set(&m->error))
112 fprintf(f,
113 " ErrorName=%s%s%s"
114 " ErrorMessage=%s\"%s\"%s\n",
1fc464f6
LP
115 ansi_highlight_red(), strna(m->error.name), ansi_normal(),
116 ansi_highlight_red(), strna(m->error.message), ansi_normal());
3db0e46b 117
3db0e46b 118 if (m->monotonic != 0)
de0671ee 119 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
3db0e46b 120 if (m->realtime != 0)
de0671ee 121 fprintf(f, " Realtime="USEC_FMT, m->realtime);
6a0e376c 122 if (m->seqnum != 0)
de0671ee 123 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
3db0e46b 124
6a0e376c 125 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
3db0e46b
LP
126 fputs("\n", f);
127
d0b2babf 128 bus_creds_dump(&m->creds, f, true);
3db0e46b
LP
129 }
130
d55192ad 131 r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
23bbb0de
MS
132 if (r < 0)
133 return log_error_errno(r, "Failed to rewind: %m");
3db0e46b 134
ee04388a
LP
135 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
136 _cleanup_free_ char *prefix = NULL;
137
138 prefix = indent(0, flags);
139 if (!prefix)
140 return log_oom();
141
142 fprintf(f, "%sMESSAGE \"%s\" {\n", prefix, strempty(m->root_container.signature));
143 }
3db0e46b 144
f168c273 145 for (;;) {
3db0e46b
LP
146 _cleanup_free_ char *prefix = NULL;
147 const char *contents = NULL;
148 char type;
149 union {
150 uint8_t u8;
151 uint16_t u16;
152 int16_t s16;
153 uint32_t u32;
154 int32_t s32;
155 uint64_t u64;
156 int64_t s64;
157 double d64;
158 const char *string;
159 int i;
160 } basic;
161
162 r = sd_bus_message_peek_type(m, &type, &contents);
23bbb0de
MS
163 if (r < 0)
164 return log_error_errno(r, "Failed to peek type: %m");
3db0e46b
LP
165
166 if (r == 0) {
167 if (level <= 1)
168 break;
169
170 r = sd_bus_message_exit_container(m);
23bbb0de
MS
171 if (r < 0)
172 return log_error_errno(r, "Failed to exit container: %m");
3db0e46b
LP
173
174 level--;
175
d55192ad 176 prefix = indent(level, flags);
3db0e46b
LP
177 if (!prefix)
178 return log_oom();
179
180 fprintf(f, "%s};\n", prefix);
181 continue;
182 }
183
d55192ad 184 prefix = indent(level, flags);
3db0e46b
LP
185 if (!prefix)
186 return log_oom();
187
188 if (bus_type_is_container(type) > 0) {
189 r = sd_bus_message_enter_container(m, type, contents);
23bbb0de
MS
190 if (r < 0)
191 return log_error_errno(r, "Failed to enter container: %m");
3db0e46b
LP
192
193 if (type == SD_BUS_TYPE_ARRAY)
194 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
195 else if (type == SD_BUS_TYPE_VARIANT)
196 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
197 else if (type == SD_BUS_TYPE_STRUCT)
198 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
199 else if (type == SD_BUS_TYPE_DICT_ENTRY)
200 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
201
313cefa1 202 level++;
3db0e46b
LP
203
204 continue;
205 }
206
207 r = sd_bus_message_read_basic(m, type, &basic);
23bbb0de
MS
208 if (r < 0)
209 return log_error_errno(r, "Failed to get basic: %m");
3db0e46b
LP
210
211 assert(r > 0);
212
213 switch (type) {
214
215 case SD_BUS_TYPE_BYTE:
1fc464f6 216 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_normal());
3db0e46b
LP
217 break;
218
219 case SD_BUS_TYPE_BOOLEAN:
1fc464f6 220 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_normal());
3db0e46b
LP
221 break;
222
223 case SD_BUS_TYPE_INT16:
1fc464f6 224 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_normal());
3db0e46b
LP
225 break;
226
227 case SD_BUS_TYPE_UINT16:
1fc464f6 228 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_normal());
3db0e46b
LP
229 break;
230
231 case SD_BUS_TYPE_INT32:
1fc464f6 232 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_normal());
3db0e46b
LP
233 break;
234
235 case SD_BUS_TYPE_UINT32:
1fc464f6 236 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_normal());
3db0e46b
LP
237 break;
238
239 case SD_BUS_TYPE_INT64:
1fc464f6 240 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_normal());
3db0e46b
LP
241 break;
242
243 case SD_BUS_TYPE_UINT64:
1fc464f6 244 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_normal());
3db0e46b
LP
245 break;
246
247 case SD_BUS_TYPE_DOUBLE:
1fc464f6 248 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_normal());
3db0e46b
LP
249 break;
250
251 case SD_BUS_TYPE_STRING:
1fc464f6 252 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
253 break;
254
255 case SD_BUS_TYPE_OBJECT_PATH:
1fc464f6 256 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
257 break;
258
259 case SD_BUS_TYPE_SIGNATURE:
1fc464f6 260 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
3db0e46b
LP
261 break;
262
263 case SD_BUS_TYPE_UNIX_FD:
1fc464f6 264 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_normal());
3db0e46b
LP
265 break;
266
267 default:
268 assert_not_reached("Unknown basic type.");
269 }
270 }
271
ee04388a
LP
272 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
273 _cleanup_free_ char *prefix = NULL;
274
275 prefix = indent(0, flags);
276 if (!prefix)
277 return log_oom();
278
279 fprintf(f, "%s};\n\n", prefix);
280 }
d55192ad 281
3db0e46b
LP
282 return 0;
283}
5b12334d
LP
284
285static void dump_capabilities(
286 sd_bus_creds *c,
287 FILE *f,
288 const char *name,
d0b2babf 289 bool terse,
5b12334d
LP
290 int (*has)(sd_bus_creds *c, int capability)) {
291
292 unsigned long i, last_cap;
293 unsigned n = 0;
294 int r;
295
296 assert(c);
297 assert(f);
298 assert(name);
299 assert(has);
300
301 i = 0;
302 r = has(c, i);
303 if (r < 0)
304 return;
305
d0b2babf 306 fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
5b12334d
LP
307 last_cap = cap_last_cap();
308
309 for (;;) {
310 if (r > 0) {
5ce70e5b 311
5b12334d
LP
312 if (n > 0)
313 fputc(' ', f);
314 if (n % 4 == 3)
d0b2babf 315 fprintf(f, terse ? "\n " : "\n ");
5b12334d 316
2822da4f 317 fprintf(f, "%s", strna(capability_to_name(i)));
5b12334d
LP
318 n++;
319 }
320
321 i++;
322
323 if (i > last_cap)
324 break;
325
326 r = has(c, i);
327 }
328
329 fputs("\n", f);
d0b2babf
LP
330
331 if (!terse)
1fc464f6 332 fputs(ansi_normal(), f);
5b12334d
LP
333}
334
d0b2babf 335int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
5b12334d
LP
336 uid_t owner, audit_loginuid;
337 uint32_t audit_sessionid;
49b832c5 338 char **cmdline = NULL, **well_known = NULL;
cfeaa44a 339 const char *prefix, *color, *suffix, *s;
329ac4bc 340 int r, q, v, w, z;
5b12334d
LP
341
342 assert(c);
343
344 if (!f)
345 f = stdout;
346
d0b2babf
LP
347 if (terse) {
348 prefix = " ";
349 suffix = "";
350 color = "";
351 } else {
352 const char *off;
353
354 prefix = "";
355 color = ansi_highlight();
356
1fc464f6 357 off = ansi_normal();
63c372cb 358 suffix = strjoina(off, "\n");
d0b2babf
LP
359 }
360
5b12334d 361 if (c->mask & SD_BUS_CREDS_PID)
d0b2babf 362 fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
5b12334d 363 if (c->mask & SD_BUS_CREDS_TID)
d0b2babf 364 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
cfeaa44a
LP
365 if (c->mask & SD_BUS_CREDS_PPID) {
366 if (c->ppid == 0)
367 fprintf(f, "%sPPID=%sn/a%s", prefix, color, suffix);
368 else
369 fprintf(f, "%sPPID=%s"PID_FMT"%s", prefix, color, c->ppid, suffix);
370 }
4761e880
LP
371 if (c->mask & SD_BUS_CREDS_TTY)
372 fprintf(f, "%sTTY=%s%s%s", prefix, color, strna(c->tty), suffix);
705a415f 373
4761e880 374 if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID|SD_BUS_CREDS_TTY))))
705a415f
LP
375 fputs("\n", f);
376
5b12334d 377 if (c->mask & SD_BUS_CREDS_UID)
d0b2babf 378 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
705a415f
LP
379 if (c->mask & SD_BUS_CREDS_EUID)
380 fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
381 if (c->mask & SD_BUS_CREDS_SUID)
382 fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
383 if (c->mask & SD_BUS_CREDS_FSUID)
384 fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
5b12334d
LP
385 r = sd_bus_creds_get_owner_uid(c, &owner);
386 if (r >= 0)
d0b2babf 387 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
5b12334d 388 if (c->mask & SD_BUS_CREDS_GID)
d0b2babf 389 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
705a415f
LP
390 if (c->mask & SD_BUS_CREDS_EGID)
391 fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
392 if (c->mask & SD_BUS_CREDS_SGID)
393 fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
394 if (c->mask & SD_BUS_CREDS_FSGID)
395 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
396
02581590
LP
397 if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
398 unsigned i;
399
400 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
401 for (i = 0; i < c->n_supplementary_gids; i++)
402 fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
403 fprintf(f, "%s", suffix);
404 }
405
705a415f 406 if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
02581590
LP
407 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
408 SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
5b12334d
LP
409 fputs("\n", f);
410
5b12334d 411 if (c->mask & SD_BUS_CREDS_COMM)
d0b2babf 412 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
5b12334d 413 if (c->mask & SD_BUS_CREDS_TID_COMM)
d0b2babf 414 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
5cf4f2d1 415 if (c->mask & SD_BUS_CREDS_EXE)
cfeaa44a 416 fprintf(f, "%sExe=%s%s%s", prefix, color, strna(c->exe), suffix);
14008e4e 417
d0b2babf 418 if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
14008e4e
LP
419 fputs("\n", f);
420
cfeaa44a
LP
421 r = sd_bus_creds_get_cmdline(c, &cmdline);
422 if (r >= 0) {
5b12334d
LP
423 char **i;
424
d0b2babf 425 fprintf(f, "%sCommandLine=%s", prefix, color);
5b12334d
LP
426 STRV_FOREACH(i, cmdline) {
427 if (i != cmdline)
428 fputc(' ', f);
429
430 fputs(*i, f);
431 }
432
d0b2babf 433 fprintf(f, "%s", suffix);
cfeaa44a
LP
434 } else if (r != -ENODATA)
435 fprintf(f, "%sCommandLine=%sn/a%s", prefix, color, suffix);
5b12334d 436
5cf4f2d1
LP
437 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
438 fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
439 if (c->mask & SD_BUS_CREDS_DESCRIPTION)
440 fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
441
442 if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
443 fputs("\n", f);
444
5b12334d 445 if (c->mask & SD_BUS_CREDS_CGROUP)
d0b2babf 446 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
cfeaa44a
LP
447 s = NULL;
448 r = sd_bus_creds_get_unit(c, &s);
449 if (r != -ENODATA)
450 fprintf(f, "%sUnit=%s%s%s", prefix, color, strna(s), suffix);
451 s = NULL;
cfeaa44a
LP
452 v = sd_bus_creds_get_slice(c, &s);
453 if (v != -ENODATA)
454 fprintf(f, "%sSlice=%s%s%s", prefix, color, strna(s), suffix);
455 s = NULL;
329ac4bc
LP
456 q = sd_bus_creds_get_user_unit(c, &s);
457 if (q != -ENODATA)
458 fprintf(f, "%sUserUnit=%s%s%s", prefix, color, strna(s), suffix);
459 s = NULL;
460 w = sd_bus_creds_get_user_slice(c, &s);
cfeaa44a 461 if (w != -ENODATA)
329ac4bc
LP
462 fprintf(f, "%sUserSlice=%s%s%s", prefix, color, strna(s), suffix);
463 s = NULL;
464 z = sd_bus_creds_get_session(c, &s);
465 if (z != -ENODATA)
cfeaa44a
LP
466 fprintf(f, "%sSession=%s%s%s", prefix, color, strna(s), suffix);
467
329ac4bc 468 if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || r != -ENODATA || q != -ENODATA || v != -ENODATA || w != -ENODATA || z != -ENODATA))
5b12334d
LP
469 fputs("\n", f);
470
cfeaa44a
LP
471 r = sd_bus_creds_get_audit_login_uid(c, &audit_loginuid);
472 if (r >= 0)
d0b2babf 473 fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
cfeaa44a
LP
474 else if (r != -ENODATA)
475 fprintf(f, "%sAuditLoginUID=%sn/a%s", prefix, color, suffix);
476 q = sd_bus_creds_get_audit_session_id(c, &audit_sessionid);
477 if (q >= 0)
d0b2babf 478 fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
cfeaa44a
LP
479 else if (q != -ENODATA)
480 fprintf(f, "%sAuditSessionID=%sn/a%s", prefix, color, suffix);
5b12334d 481
cfeaa44a 482 if (terse && (r != -ENODATA || q != -ENODATA))
5b12334d
LP
483 fputs("\n", f);
484
49b832c5 485 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
d0b2babf 486 fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
49b832c5
LP
487
488 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
489 char **i;
490
d0b2babf 491 fprintf(f, "%sWellKnownNames=%s", prefix, color);
49b832c5
LP
492 STRV_FOREACH(i, well_known) {
493 if (i != well_known)
494 fputc(' ', f);
495
496 fputs(*i, f);
497 }
498
d0b2babf 499 fprintf(f, "%s", suffix);
49b832c5
LP
500 }
501
d0b2babf 502 if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
3310dfd5
LP
503 fputc('\n', f);
504
d0b2babf
LP
505 dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
506 dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
507 dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
508 dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
5b12334d
LP
509
510 return 0;
511}
1f70b087
LP
512
513/*
514 * For details about the file format, see:
515 *
516 * http://wiki.wireshark.org/Development/LibpcapFileFormat
517 */
518
519typedef struct _packed_ pcap_hdr_s {
520 uint32_t magic_number; /* magic number */
521 uint16_t version_major; /* major version number */
522 uint16_t version_minor; /* minor version number */
523 int32_t thiszone; /* GMT to local correction */
524 uint32_t sigfigs; /* accuracy of timestamps */
525 uint32_t snaplen; /* max length of captured packets, in octets */
526 uint32_t network; /* data link type */
527} pcap_hdr_t ;
528
529typedef struct _packed_ pcaprec_hdr_s {
530 uint32_t ts_sec; /* timestamp seconds */
531 uint32_t ts_usec; /* timestamp microseconds */
532 uint32_t incl_len; /* number of octets of packet saved in file */
533 uint32_t orig_len; /* actual length of packet */
534} pcaprec_hdr_t;
535
536int bus_pcap_header(size_t snaplen, FILE *f) {
537
538 pcap_hdr_t hdr = {
539 .magic_number = 0xa1b2c3d4U,
540 .version_major = 2,
541 .version_minor = 4,
542 .thiszone = 0, /* UTC */
543 .sigfigs = 0,
544 .network = 231, /* D-Bus */
545 };
546
547 if (!f)
548 f = stdout;
549
550 assert(snaplen > 0);
551 assert((size_t) (uint32_t) snaplen == snaplen);
552
553 hdr.snaplen = (uint32_t) snaplen;
554
555 fwrite(&hdr, 1, sizeof(hdr), f);
1f70b087 556
dacd6cee 557 return fflush_and_check(f);
1f70b087
LP
558}
559
560int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
561 struct bus_body_part *part;
562 pcaprec_hdr_t hdr = {};
563 struct timeval tv;
564 unsigned i;
565 size_t w;
566
567 if (!f)
568 f = stdout;
569
570 assert(m);
571 assert(snaplen > 0);
572 assert((size_t) (uint32_t) snaplen == snaplen);
573
574 if (m->realtime != 0)
575 timeval_store(&tv, m->realtime);
576 else
577 assert_se(gettimeofday(&tv, NULL) >= 0);
578
579 hdr.ts_sec = tv.tv_sec;
580 hdr.ts_usec = tv.tv_usec;
581 hdr.orig_len = BUS_MESSAGE_SIZE(m);
582 hdr.incl_len = MIN(hdr.orig_len, snaplen);
583
584 /* write the pcap header */
585 fwrite(&hdr, 1, sizeof(hdr), f);
586
587 /* write the dbus header */
588 w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
589 fwrite(m->header, 1, w, f);
590 snaplen -= w;
591
592 /* write the dbus body */
593 MESSAGE_FOREACH_PART(part, i, m) {
594 if (snaplen <= 0)
595 break;
596
597 w = MIN(part->size, snaplen);
598 fwrite(part->data, 1, w, f);
599 snaplen -= w;
600 }
601
dacd6cee 602 return fflush_and_check(f);
1f70b087 603}