summaryrefslogtreecommitdiffstats
path: root/src/locale
diff options
context:
space:
mode:
Diffstat (limited to 'src/locale')
-rw-r--r--src/locale/localed-util.c35
-rw-r--r--src/locale/localed.c48
-rw-r--r--src/locale/xkbcommon-util.c23
-rw-r--r--src/locale/xkbcommon-util.h21
4 files changed, 60 insertions, 67 deletions
diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c
index e4e57a0..5699659 100644
--- a/src/locale/localed-util.c
+++ b/src/locale/localed-util.c
@@ -304,7 +304,7 @@ void context_clear(Context *c) {
c->x11_cache = sd_bus_message_unref(c->x11_cache);
c->vc_cache = sd_bus_message_unref(c->vc_cache);
- c->polkit_registry = bus_verify_polkit_async_registry_free(c->polkit_registry);
+ c->polkit_registry = hashmap_free(c->polkit_registry);
};
X11Context *context_get_x11_context(Context *c) {
@@ -735,7 +735,9 @@ int vconsole_convert_to_x11(const VCContext *vc, X11Context *ret) {
}
int find_converted_keymap(const X11Context *xc, char **ret) {
- _cleanup_free_ char *n = NULL;
+ _cleanup_free_ char *n = NULL, *p = NULL, *pz = NULL;
+ _cleanup_strv_free_ char **keymap_dirs = NULL;
+ int r;
assert(xc);
assert(!isempty(xc->layout));
@@ -748,18 +750,29 @@ int find_converted_keymap(const X11Context *xc, char **ret) {
if (!n)
return -ENOMEM;
- NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
- _cleanup_free_ char *p = NULL, *pz = NULL;
+ p = strjoin("xkb/", n, ".map");
+ pz = strjoin("xkb/", n, ".map.gz");
+ if (!p || !pz)
+ return -ENOMEM;
+
+ r = keymap_directories(&keymap_dirs);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(dir, keymap_dirs) {
+ _cleanup_close_ int dir_fd = -EBADF;
bool uncompressed;
- p = strjoin(dir, "xkb/", n, ".map");
- pz = strjoin(dir, "xkb/", n, ".map.gz");
- if (!p || !pz)
- return -ENOMEM;
+ 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);
+ continue;
+ }
- uncompressed = access(p, F_OK) == 0;
- if (uncompressed || access(pz, F_OK) == 0) {
- log_debug("Found converted keymap %s at %s", n, uncompressed ? p : pz);
+ 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);
*ret = TAKE_PTR(n);
return 1;
}
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 5d96237..c0d1045 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -15,6 +15,7 @@
#include "bus-polkit.h"
#include "bus-unit-util.h"
#include "constants.h"
+#include "daemon-util.h"
#include "kbd-util.h"
#include "localed-util.h"
#include "macro.h"
@@ -157,11 +158,7 @@ static int process_locale_list_item(
if (new_locale[p])
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name);
- new_locale[p] = strdup(e);
- if (!new_locale[p])
- return -ENOMEM;
-
- return 0;
+ return strdup_to(&new_locale[p], e);
}
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment);
@@ -281,13 +278,12 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
return sd_bus_reply_method_return(m, NULL);
}
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_ADMIN,
"org.freedesktop.locale1.set-locale",
- NULL,
- interactive,
- UID_INVALID,
+ /* details= */ NULL,
+ /* good_user= */ UID_INVALID,
+ interactive ? POLKIT_ALLOW_INTERACTIVE : 0,
&c->polkit_registry,
error);
if (r < 0)
@@ -386,13 +382,12 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro
if (vc_context_equal(&c->vc, &in) && !x_needs_update)
return sd_bus_reply_method_return(m, NULL);
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_ADMIN,
"org.freedesktop.locale1.set-keyboard",
- NULL,
- interactive,
- UID_INVALID,
+ /* details= */ NULL,
+ /* good_user= */ UID_INVALID,
+ interactive ? POLKIT_ALLOW_INTERACTIVE : 0,
&c->polkit_registry,
error);
if (r < 0)
@@ -506,13 +501,12 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
if (x11_context_equal(&c->x11_from_vc, &in) && x11_context_equal(&c->x11_from_xorg, &in) && !convert)
return sd_bus_reply_method_return(m, NULL);
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
m,
- CAP_SYS_ADMIN,
"org.freedesktop.locale1.set-keyboard",
- NULL,
- interactive,
- UID_INVALID,
+ /* details= */ NULL,
+ /* good_user= */ UID_INVALID,
+ interactive ? POLKIT_ALLOW_INTERACTIVE : 0,
&c->polkit_registry,
error);
if (r < 0)
@@ -650,26 +644,24 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
- assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
-
r = sd_event_default(&event);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");
(void) sd_event_set_watchdog(event, true);
- r = sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to install SIGINT handler: %m");
-
- r = sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
+ r = sd_event_set_signal_exit(event, true);
if (r < 0)
- return log_error_errno(r, "Failed to install SIGTERM handler: %m");
+ return log_error_errno(r, "Failed to install SIGINT/SIGTERM handlers: %m");
r = connect_bus(&context, event, &bus);
if (r < 0)
return r;
+ r = sd_notify(false, NOTIFY_READY);
+ if (r < 0)
+ log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
+
r = bus_event_loop_with_idle(event, bus, "org.freedesktop.locale1", DEFAULT_EXIT_USEC, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
diff --git a/src/locale/xkbcommon-util.c b/src/locale/xkbcommon-util.c
index 295ac8a..d4e24cd 100644
--- a/src/locale/xkbcommon-util.c
+++ b/src/locale/xkbcommon-util.c
@@ -9,22 +9,17 @@
#if HAVE_XKBCOMMON
static void *xkbcommon_dl = NULL;
-struct xkb_context* (*sym_xkb_context_new)(enum xkb_context_flags flags);
-void (*sym_xkb_context_unref)(struct xkb_context *context);
-void (*sym_xkb_context_set_log_fn)(
- struct xkb_context *context,
- void (*log_fn)(
- struct xkb_context *context,
- enum xkb_log_level level,
- const char *format,
- va_list args));
-struct xkb_keymap* (*sym_xkb_keymap_new_from_names)(
- struct xkb_context *context,
- const struct xkb_rule_names *names,
- enum xkb_keymap_compile_flags flags);
-void (*sym_xkb_keymap_unref)(struct xkb_keymap *keymap);
+DLSYM_FUNCTION(xkb_context_new);
+DLSYM_FUNCTION(xkb_context_unref);
+DLSYM_FUNCTION(xkb_context_set_log_fn);
+DLSYM_FUNCTION(xkb_keymap_new_from_names);
+DLSYM_FUNCTION(xkb_keymap_unref);
static int dlopen_xkbcommon(void) {
+ ELF_NOTE_DLOPEN("xkbcommon",
+ "Support for keyboard locale descriptions",
+ ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, "libxkbcommon.so.0");
+
return dlopen_many_sym_or_warn(
&xkbcommon_dl, "libxkbcommon.so.0", LOG_DEBUG,
DLSYM_ARG(xkb_context_new),
diff --git a/src/locale/xkbcommon-util.h b/src/locale/xkbcommon-util.h
index e99c2d7..92f45c2 100644
--- a/src/locale/xkbcommon-util.h
+++ b/src/locale/xkbcommon-util.h
@@ -1,23 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlfcn-util.h"
+
#if HAVE_XKBCOMMON
#include <xkbcommon/xkbcommon.h>
-extern struct xkb_context* (*sym_xkb_context_new)(enum xkb_context_flags flags);
-extern void (*sym_xkb_context_unref)(struct xkb_context *context);
-extern void (*sym_xkb_context_set_log_fn)(
- struct xkb_context *context,
- void (*log_fn)(
- struct xkb_context *context,
- enum xkb_log_level level,
- const char *format,
- va_list args));
-extern struct xkb_keymap* (*sym_xkb_keymap_new_from_names)(
- struct xkb_context *context,
- const struct xkb_rule_names *names,
- enum xkb_keymap_compile_flags flags);
-extern void (*sym_xkb_keymap_unref)(struct xkb_keymap *keymap);
+DLSYM_PROTOTYPE(xkb_context_new);
+DLSYM_PROTOTYPE(xkb_context_unref);
+DLSYM_PROTOTYPE(xkb_context_set_log_fn);
+DLSYM_PROTOTYPE(xkb_keymap_new_from_names);
+DLSYM_PROTOTYPE(xkb_keymap_unref);
int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options);