localed.c revision e78af5ffe53a0d24854d721d1166a60f8ed0dfb6
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann This file is part of systemd.
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann Copyright 2011 Lennart Poettering
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann Copyright 2013 Kay Sievers
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann systemd is free software; you can redistribute it and/or modify it
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann under the terms of the GNU Lesser General Public License as published by
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann the Free Software Foundation; either version 2.1 of the License, or
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann (at your option) any later version.
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann systemd is distributed in the hope that it will be useful, but
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann WITHOUT ANY WARRANTY; without even the implied warranty of
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann Lesser General Public License for more details.
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann You should have received a copy of the GNU Lesser General Public License
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann along with systemd; If not, see <http://www.gnu.org/licenses/>.
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann /* We don't list LC_ALL here on purpose. People should be
c0395aeb903cde25bd9e81fba3334f63335fe0efDavid Herrmann * using LANG instead. */
typedef struct Context {
char *x11_layout;
char *x11_model;
char *x11_variant;
char *x11_options;
char *vc_keymap;
char *vc_keymap_toggle;
} Context;
static const char* nonempty(const char *s) {
static void free_and_replace(char **s, char *v) {
free(*s);
for (p = 0; p < _LOCALE_MAX; p++)
context_free_x11(c);
NULL);
if (r == -ENOENT) {
for (p = 0; p < _LOCALE_MAX; p++) {
locale_simplify(c);
NULL);
if (r < 0 && r != -ENOENT)
bool in_section = false;
context_free_x11(c);
r = strv_split_quoted(&a, l);
r = strv_split_quoted(&a, l);
return -ENOMEM;
in_section = true;
in_section = false;
r = locale_read_data(c);
q = vconsole_read_data(c);
p = x11_read_data(c);
if (r < 0 && r != -ENOENT)
for (p = 0; p < _LOCALE_MAX; p++) {
return -ENOMEM;
u = strv_env_set(l, t);
return -ENOMEM;
strv_free(l);
if (strv_isempty(l)) {
*settings = l;
l = NULL;
if (!l_unset)
return -ENOMEM;
if (!l_set)
return -ENOMEM;
return -ENOMEM;
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
if (r < 0 && r != -ENOENT)
return -ENOMEM;
u = strv_env_set(l, s);
return -ENOMEM;
strv_free(l);
return -ENOMEM;
u = strv_env_set(l, s);
return -ENOMEM;
strv_free(l);
if (strv_isempty(l)) {
fflush(f);
r = -errno;
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&error,
NULL,
static const char* strnulldash(const char *s) {
assert(f);
assert(n);
assert(a);
errno = 0;
if (ferror(f))
r = strv_split_quoted(&b, l);
strv_free(b);
bool modified = false;
modified =
context_free_x11(c);
return -errno;
r = read_next_mapping(f, &n, &a);
return -ENOMEM;
modified = true;
if (modified) {
r = x11_write_data(c);
"/org/freedesktop/locale1",
static int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap) {
const char *dir;
_cleanup_free_ char *n;
if (x11_variant)
return -ENOMEM;
bool uncompressed;
if (!p || !pz)
return -ENOMEM;
*new_keymap = n;
n = NULL;
unsigned best_matching = 0;
return -errno;
unsigned matching = 0;
r = read_next_mapping(f, &n, &a);
if (matching > 0) {
matching++;
matching++;
matching++;
a[0], matching);
if (c->x11_variant)
bool modified = false;
modified =
context_free_x11(c);
modified = true;
if (modified) {
r = vconsole_write_data(c);
"/org/freedesktop/locale1",
static int property_get_locale(
const char *path,
const char *interface,
const char *property,
void *userdata,
return -ENOMEM;
for (p = 0, q = 0; p < _LOCALE_MAX; p++) {
return -ENOMEM;
int interactive;
bool modified = false;
r = bus_message_read_strv_extend(m, &l);
STRV_FOREACH(i, l) {
bool valid = false;
for (p = 0; p < _LOCALE_MAX; p++) {
size_t k;
valid = true;
passed[p] = true;
modified = true;
if (!valid)
if (!modified)
for (p = 0; p < _LOCALE_MAX; p++)
modified = true;
if (modified) {
r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
STRV_FOREACH(i, l)
for (p = 0; p < _LOCALE_MAX; p++) {
size_t k;
for (p = 0; p < _LOCALE_MAX; p++) {
if (passed[p])
locale_simplify(c);
if (settings) {
"/org/freedesktop/locale1",
static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
return -ENOMEM;
r = vconsole_write_data(c);
"/org/freedesktop/locale1",
if (convert) {
static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
return -ENOMEM;
r = x11_write_data(c);
"/org/freedesktop/locale1",
if (convert) {
SD_BUS_PROPERTY("X11Layout", "s", NULL, offsetof(Context, x11_layout), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("X11Model", "s", NULL, offsetof(Context, x11_model), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("X11Variant", "s", NULL, offsetof(Context, x11_variant), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("X11Options", "s", NULL, offsetof(Context, x11_options), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("VConsoleKeymap", "s", NULL, offsetof(Context, vc_keymap), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("VConsoleKeymapToggle", "s", NULL, offsetof(Context, vc_keymap_toggle), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("SetVConsoleKeyboard", "ssbb", NULL, method_set_vc_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetX11Keyboard", "ssssbb", NULL, method_set_x11_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
assert(c);
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
log_open();
r = -EINVAL;
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;