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