Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : : 3 : : #include <ftw.h> 4 : : 5 : : #include "kbd-util.h" 6 : : #include "log.h" 7 : : #include "nulstr-util.h" 8 : : #include "path-util.h" 9 : : #include "set.h" 10 : : #include "string-util.h" 11 : : #include "strv.h" 12 : : #include "utf8.h" 13 : : 14 : : static thread_local Set *keymaps = NULL; 15 : : 16 : 2440 : static int nftw_cb( 17 : : const char *fpath, 18 : : const struct stat *sb, 19 : : int tflag, 20 : : struct FTW *ftwbuf) { 21 : : 22 : 2440 : _cleanup_free_ char *p = NULL; 23 : : char *e; 24 : : int r; 25 : : 26 [ + + ]: 2440 : if (tflag != FTW_F) 27 : 96 : return 0; 28 : : 29 [ + - ]: 2344 : if (!endswith(fpath, ".map") && 30 [ + + ]: 2344 : !endswith(fpath, ".map.gz")) 31 : 100 : return 0; 32 : : 33 : 2244 : p = strdup(basename(fpath)); 34 [ - + ]: 2244 : if (!p) 35 : 0 : return FTW_STOP; 36 : : 37 : 2244 : e = endswith(p, ".map"); 38 [ - + ]: 2244 : if (e) 39 : 0 : *e = 0; 40 : : 41 : 2244 : e = endswith(p, ".map.gz"); 42 [ + - ]: 2244 : if (e) 43 : 2244 : *e = 0; 44 : : 45 [ - + ]: 2244 : if (!keymap_is_valid(p)) 46 : 0 : return 0; 47 : : 48 : 2244 : r = set_consume(keymaps, TAKE_PTR(p)); 49 [ - + # # ]: 2244 : if (r < 0 && r != -EEXIST) 50 : 0 : return r; 51 : : 52 : 2244 : return 0; 53 : : } 54 : : 55 : 4 : int get_keymaps(char ***ret) { 56 : 4 : _cleanup_strv_free_ char **l = NULL; 57 : : const char *dir; 58 : : int r; 59 : : 60 : 4 : keymaps = set_new(&string_hash_ops); 61 [ - + ]: 4 : if (!keymaps) 62 : 0 : return -ENOMEM; 63 : : 64 [ + - + + ]: 16 : NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) { 65 : 12 : r = nftw(dir, nftw_cb, 20, FTW_PHYS|FTW_ACTIONRETVAL); 66 : : 67 [ - + ]: 12 : if (r == FTW_STOP) 68 [ # # ]: 0 : log_debug("Directory not found %s", dir); 69 [ + + ]: 12 : else if (r < 0) 70 [ - + ]: 8 : log_debug_errno(r, "Can't add keymap: %m"); 71 : : } 72 : : 73 : 4 : l = set_get_strv(keymaps); 74 [ - + ]: 4 : if (!l) { 75 : 0 : set_free_free(keymaps); 76 : 0 : return -ENOMEM; 77 : : } 78 : : 79 : 4 : set_free(keymaps); 80 : : 81 [ - + ]: 4 : if (strv_isempty(l)) 82 : 0 : return -ENOENT; 83 : : 84 : 4 : strv_sort(l); 85 : : 86 : 4 : *ret = TAKE_PTR(l); 87 : : 88 : 4 : return 0; 89 : : } 90 : : 91 : 4424 : bool keymap_is_valid(const char *name) { 92 : : 93 [ + + ]: 4424 : if (isempty(name)) 94 : 4 : return false; 95 : : 96 [ - + ]: 4420 : if (strlen(name) >= 128) 97 : 0 : return false; 98 : : 99 [ - + ]: 4420 : if (!utf8_is_valid(name)) 100 : 0 : return false; 101 : : 102 [ + + ]: 4420 : if (!filename_is_valid(name)) 103 : 4 : return false; 104 : : 105 [ + + ]: 4416 : if (!string_is_safe(name)) 106 : 4 : return false; 107 : : 108 : 4412 : return true; 109 : : }