chiark / gitweb /
01f163b60cada89ddfee5e323c6003bb647407b5
[elogind.git] / src / basic / cap-list.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3   This file is part of systemd.
4
5   Copyright 2014 Lennart Poettering
6 ***/
7
8 #include <errno.h>
9 #include <string.h>
10
11 #include "alloc-util.h"
12 #include "capability-util.h"
13 #include "cap-list.h"
14 #include "extract-word.h"
15 #include "macro.h"
16 #include "missing.h"
17 #include "parse-util.h"
18 #include "util.h"
19
20 static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len);
21
22 #include "cap-from-name.h"
23 #include "cap-to-name.h"
24
25 const char *capability_to_name(int id) {
26
27         if (id < 0)
28                 return NULL;
29
30         if (id >= (int) ELEMENTSOF(capability_names))
31                 return NULL;
32
33         return capability_names[id];
34 }
35
36 int capability_from_name(const char *name) {
37         const struct capability_name *sc;
38         int r, i;
39
40         assert(name);
41
42         /* Try to parse numeric capability */
43         r = safe_atoi(name, &i);
44         if (r >= 0) {
45                 if (i >= 0 && i < (int) ELEMENTSOF(capability_names))
46                         return i;
47                 else
48                         return -EINVAL;
49         }
50
51         /* Try to parse string capability */
52         sc = lookup_capability(name, strlen(name));
53         if (!sc)
54                 return -EINVAL;
55
56         return sc->id;
57 }
58
59 int capability_list_length(void) {
60         return (int) ELEMENTSOF(capability_names);
61 }
62
63 int capability_set_to_string_alloc(uint64_t set, char **s) {
64         _cleanup_free_ char *str = NULL;
65         unsigned long i;
66         size_t allocated = 0, n = 0;
67
68         assert(s);
69
70         for (i = 0; i < cap_last_cap(); i++)
71                 if (set & (UINT64_C(1) << i)) {
72                         const char *p;
73                         size_t add;
74
75                         p = capability_to_name(i);
76                         if (!p)
77                                 return -EINVAL;
78
79                         add = strlen(p);
80
81                         if (!GREEDY_REALLOC(str, allocated, n + add + 2))
82                                 return -ENOMEM;
83
84                         strcpy(mempcpy(str + n, p, add), " ");
85                         n += add + 1;
86                 }
87
88         if (!GREEDY_REALLOC(str, allocated, n + 1))
89                 return -ENOMEM;
90
91         str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */
92
93         *s = TAKE_PTR(str);
94
95         return 0;
96 }
97
98 int capability_set_from_string(const char *s, uint64_t *set) {
99         uint64_t val = 0;
100         const char *p;
101
102         assert(set);
103
104         for (p = s;;) {
105                 _cleanup_free_ char *word = NULL;
106                 int r;
107
108                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
109                 if (r == -ENOMEM)
110                         return r;
111                 if (r <= 0)
112                         break;
113
114                 r = capability_from_name(word);
115                 if (r < 0)
116                         continue;
117
118                 val |= ((uint64_t) UINT64_C(1)) << (uint64_t) r;
119         }
120
121         *set = val;
122
123         return 0;
124 }