1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "analyze.h"
#include "analyze-capability.h"
#include "cap-list.h"
#include "capability-util.h"
#include "format-table.h"
#include "parse-util.h"
static int table_add_capability(Table *table, int c) {
int r;
r = table_add_many(table,
TABLE_STRING, capability_to_name(c) ?: "cap_???",
TABLE_UINT, c);
if (r < 0)
return table_log_add_error(r);
return 0;
}
int verb_capabilities(int argc, char *argv[], void *userdata) {
_cleanup_(table_unrefp) Table *table = NULL;
unsigned last_cap;
int r;
table = table_new("name", "number");
if (!table)
return log_oom();
(void) table_set_align_percent(table, table_get_cell(table, 0, 1), 100);
/* Determine the maximum of the last cap known by the kernel and by us */
last_cap = MAX((unsigned) CAP_LAST_CAP, cap_last_cap());
if (arg_capability == CAPABILITY_MASK) {
uint64_t cap_mask;
if (argc != 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Exactly 1 positional argument expected.");
r = safe_atoux64(argv[1], &cap_mask);
if (r < 0)
return log_error_errno(r, "Capability mask \"%s\" is not valid.", argv[1]);
for (unsigned c = 0; cap_mask != 0; ) {
if (cap_mask & 0b1) {
if (c > last_cap)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Capability %u is not known.", c);
r = table_add_capability(table, c);
if (r < 0)
return r;
}
++c;
cap_mask >>= 1;
}
(void) table_set_sort(table, (size_t) 1);
} else if (argc == 1) {
for (unsigned c = 0; c <= last_cap; c++) {
r = table_add_capability(table, c);
if (r < 0)
return r;
}
} else {
for (int i = 1; i < argc; i++) {
int c;
c = capability_from_name(argv[i]);
if (c < 0 || (unsigned) c > last_cap)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Capability \"%s\" is not known.", argv[i]);
r = table_add_capability(table, c);
if (r < 0)
return r;
}
(void) table_set_sort(table, (size_t) 1);
}
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
if (r < 0)
return log_error_errno(r, "Failed to output table: %m");
return EXIT_SUCCESS;
}
|