kbd-util: allow to override the default keymap directories
This introduces $SYSTEMD_KEYMAP_DIRECTORIES environment variable to override the hardcoded keymap directories. I think it is not necessary to provide the first class configuration option for controlling the keymap directories, but it is not good to hardcode the paths. So, let's introduce an environment variable to override that. Prompted by #31759. Closes #31759.
This commit is contained in:
+37
-8
@@ -1,9 +1,9 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "env-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "kbd-util.h"
|
||||
#include "log.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "path-util.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "set.h"
|
||||
@@ -11,6 +11,25 @@
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#define KBD_KEYMAP_DIRS \
|
||||
"/usr/share/keymaps/", \
|
||||
"/usr/share/kbd/keymaps/", \
|
||||
"/usr/lib/kbd/keymaps/"
|
||||
|
||||
int keymap_directories(char ***ret) {
|
||||
assert(ret);
|
||||
|
||||
if (getenv_path_list("SYSTEMD_KEYMAP_DIRECTORIES", ret) >= 0)
|
||||
return 0;
|
||||
|
||||
char **paths = strv_new(KBD_KEYMAP_DIRS);
|
||||
if (!paths)
|
||||
return log_oom_debug();
|
||||
|
||||
*ret = TAKE_PTR(paths);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct recurse_dir_userdata {
|
||||
const char *keymap_name;
|
||||
Set *keymaps;
|
||||
@@ -65,16 +84,21 @@ static int keymap_recurse_dir_callback(
|
||||
|
||||
int get_keymaps(char ***ret) {
|
||||
_cleanup_set_free_free_ Set *keymaps = NULL;
|
||||
_cleanup_strv_free_ char **keymap_dirs = NULL;
|
||||
int r;
|
||||
|
||||
r = keymap_directories(&keymap_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
keymaps = set_new(&string_hash_ops);
|
||||
if (!keymaps)
|
||||
return -ENOMEM;
|
||||
|
||||
NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
|
||||
STRV_FOREACH(dir, keymap_dirs) {
|
||||
r = recurse_dir_at(
|
||||
AT_FDCWD,
|
||||
dir,
|
||||
*dir,
|
||||
/* statx_mask= */ 0,
|
||||
/* n_depth_max= */ UINT_MAX,
|
||||
RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE,
|
||||
@@ -85,9 +109,9 @@ int get_keymaps(char ***ret) {
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (ERRNO_IS_NEG_RESOURCE(r))
|
||||
return log_warning_errno(r, "Failed to read keymap list from %s: %m", dir);
|
||||
return log_warning_errno(r, "Failed to read keymap list from %s: %m", *dir);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read keymap list from %s, ignoring: %m", dir);
|
||||
log_debug_errno(r, "Failed to read keymap list from %s, ignoring: %m", *dir);
|
||||
}
|
||||
|
||||
_cleanup_strv_free_ char **l = set_get_strv(keymaps);
|
||||
@@ -127,15 +151,20 @@ bool keymap_is_valid(const char *name) {
|
||||
}
|
||||
|
||||
int keymap_exists(const char *name) {
|
||||
_cleanup_strv_free_ char **keymap_dirs = NULL;
|
||||
int r;
|
||||
|
||||
if (!keymap_is_valid(name))
|
||||
return -EINVAL;
|
||||
|
||||
NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
|
||||
r = keymap_directories(&keymap_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(dir, keymap_dirs) {
|
||||
r = recurse_dir_at(
|
||||
AT_FDCWD,
|
||||
dir,
|
||||
*dir,
|
||||
/* statx_mask= */ 0,
|
||||
/* n_depth_max= */ UINT_MAX,
|
||||
RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE,
|
||||
@@ -148,7 +177,7 @@ int keymap_exists(const char *name) {
|
||||
if (ERRNO_IS_NEG_RESOURCE(r))
|
||||
return r;
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_debug_errno(r, "Failed to read keymap list from %s, ignoring: %m", dir);
|
||||
log_debug_errno(r, "Failed to read keymap list from %s, ignoring: %m", *dir);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define KBD_KEYMAP_DIRS \
|
||||
"/usr/share/keymaps/\0" \
|
||||
"/usr/share/kbd/keymaps/\0" \
|
||||
"/usr/lib/kbd/keymaps/\0"
|
||||
|
||||
int get_keymaps(char ***l);
|
||||
int keymap_directories(char ***ret);
|
||||
int get_keymaps(char ***ret);
|
||||
bool keymap_is_valid(const char *name);
|
||||
int keymap_exists(const char *name);
|
||||
|
||||
Reference in New Issue
Block a user