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