`systemd-gpt-auto-generator` to ensure the root partition is mounted writable
in accordance to the GPT partition flags.
-`systemd-firstboot` and `localectl`:
+`systemd-firstboot`, `localectl`, and `systemd-localed`:
* `$SYSTEMD_LIST_NON_UTF8_LOCALES=1` — if set, non-UTF-8 locales are listed among
the installed ones. By default non-UTF-8 locales are suppressed from the
selection, since we are living in the 21st century.
+* `$SYSTEMD_KEYMAP_DIRECTORIES=` — takes a colon (`:`) separated list of keymap
+ directories. The directories must be absolute and normalized. If unset, the
+ default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
+ /usr/lib/kbd/keymaps/) will be used.
+
`systemd-resolved`:
* `$SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME` — if set to "0", `systemd-resolved`
int find_converted_keymap(const X11Context *xc, char **ret) {
_cleanup_free_ char *n = NULL, *p = NULL, *pz = NULL;
+ _cleanup_strv_free_ char **keymap_dirs = NULL;
+ int r;
assert(xc);
assert(!isempty(xc->layout));
if (!p || !pz)
return -ENOMEM;
- NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
+ r = keymap_directories(&keymap_dirs);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(dir, keymap_dirs) {
_cleanup_close_ int dir_fd = -EBADF;
bool uncompressed;
- dir_fd = open(dir, O_CLOEXEC | O_DIRECTORY | O_PATH);
+ dir_fd = open(*dir, O_CLOEXEC | O_DIRECTORY | O_PATH);
if (dir_fd < 0) {
if (errno != ENOENT)
- log_debug_errno(errno, "Failed to open %s, ignoring: %m", dir);
+ log_debug_errno(errno, "Failed to open %s, ignoring: %m", *dir);
continue;
}
uncompressed = faccessat(dir_fd, p, F_OK, 0) >= 0;
if (uncompressed || faccessat(dir_fd, pz, F_OK, 0) >= 0) {
- log_debug("Found converted keymap %s at %s/%s", n, dir, uncompressed ? p : pz);
+ log_debug("Found converted keymap %s at %s/%s", n, *dir, uncompressed ? p : pz);
*ret = TAKE_PTR(n);
return 1;
}
/* 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"
#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;
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,
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);
}
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,
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;